Bug 233405 - sparc64: DWARF unwinder required for GCC 4.2.1 retirement
Summary: sparc64: DWARF unwinder required for GCC 4.2.1 retirement
Status: Closed Overcome By Events
Alias: None
Product: Base System
Classification: Unclassified
Component: misc (show other bugs)
Version: CURRENT
Hardware: sparc64 Any
: --- Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks: 233094 228919
  Show dependency treegraph
 
Reported: 2018-11-22 14:41 UTC by Ed Maste
Modified: 2020-03-08 21:22 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Maste freebsd_committer freebsd_triage 2018-11-22 14:41:26 UTC
GCC 4.2.1's retirement is expected before FreeBSD 13.0. This will also remove GCC's libgcc including the DWARF unwinder.

LLVM's libunwind provides the replacement for most architectures but does not currently support sparc64.
Comment 1 Conrad Meyer freebsd_committer freebsd_triage 2018-11-22 17:51:20 UTC
(We could also retire sparc64 before 13.0.)
Comment 2 Ed Maste freebsd_committer freebsd_triage 2019-08-14 16:19:19 UTC
Attempting to enable LLVM libunwind on sparc64 resulted in:

In file included from /scratch/tmp/emaste/freebsd/contrib/libunwind/src/libunwind.cpp:29:
/scratch/tmp/emaste/freebsd/contrib/libunwind/src/UnwindCursor.hpp:1155:3: error: static_assert failed due to requirement 'check_fit<libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_sparc>, unw_cursor_t>::does_fit' "UnwindCursor<> does not fit in unw_cursor_t"
  static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
  ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/scratch/tmp/emaste/freebsd/contrib/libunwind/src/libunwind.cpp:78:24: note: in instantiation of member function 'libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_sparc>::UnwindCursor' requested here
  new ((void *)cursor) UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
                       ^
Comment 3 Conrad Meyer freebsd_committer freebsd_triage 2019-08-14 16:34:33 UTC
Would an acceptable unwind implementation on Sparc be "raise(SIGKILL);"?
Comment 4 Ed Maste freebsd_committer freebsd_triage 2019-08-14 16:38:34 UTC
(In reply to Conrad Meyer from comment #3)
Sure, if those who have an interest in FreeBSD/sparc64 want to make that change and are happy enough with the result.
Comment 5 commit-hook freebsd_committer freebsd_triage 2019-11-07 19:37:58 UTC
A commit references this bug:

Author: emaste
Date: Thu Nov  7 19:37:26 UTC 2019
New revision: 354468
URL: https://svnweb.freebsd.org/changeset/base/354468

Log:
  arch.7: claim 12.x as the last architecture with sparc64 support

  GCC 4.2.1 is being removed before FreeBSD 13, as are some other
  components required by FreeBSD/sparc64.  Contemporary GCC does not build
  and there is currently no indication that anyone is going to address
  these issues.

  PR:		228919, 233405, 236839, 239851

Changes:
  head/share/man/man7/arch.7
Comment 6 commit-hook freebsd_committer freebsd_triage 2019-11-08 15:20:24 UTC
A commit references this bug:

Author: emaste
Date: Fri Nov  8 15:20:20 UTC 2019
New revision: 354545
URL: https://svnweb.freebsd.org/changeset/base/354545

Log:
  mark LLVM_LIBUNWIND as broken on sparc64, with PR reference

  PR:		233405

Changes:
  head/share/mk/src.opts.mk
Comment 7 Conrad Meyer freebsd_committer freebsd_triage 2019-11-09 01:36:52 UTC
FWIW, I think this is all that is needed to fix libunwind on sparc64:

--- include/__libunwind_config.h        (revision 354566)
+++ include/__libunwind_config.h        (working copy)
@@ -124,7 +124,7 @@
   #define _LIBUNWIND_TARGET_SPARC 1
   #define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC
   #define _LIBUNWIND_CONTEXT_SIZE 16
-  #define _LIBUNWIND_CURSOR_SIZE 23
+  #define _LIBUNWIND_CURSOR_SIZE 28
 # else
 #  error "Unsupported architecture."
 # endif
--- src/config.h        (revision 354566)
+++ src/config.h        (working copy)
@@ -104,7 +106,8 @@
     (!defined(__APPLE__) && defined(__arm__)) ||                               \
     (defined(__arm64__) || defined(__aarch64__)) ||                            \
     defined(__mips__) ||                                                       \
-    defined(__riscv)
+    defined(__riscv) ||                                                        \
+    defined(__sparc__)
 #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
 #define _LIBUNWIND_BUILD_ZERO_COST_APIS
 #endif
Comment 8 Conrad Meyer freebsd_committer freebsd_triage 2019-11-09 01:38:32 UTC
(Well, to fix the build anyway.  There are some "TODO" comments for some of the implementation still.)
Comment 9 Conrad Meyer freebsd_committer freebsd_triage 2019-11-10 02:42:47 UTC
More "necessary but not sufficient" IAS support (needed to compile libc).


--- contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp  (revision 354566)
+++ contrib/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp  (working copy)
@@ -815,7 +815,7 @@
                                                  Parser.getTok().getLoc()));
     Parser.Lex(); // Eat the [

-    if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
+    if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa" || Mnemonic == "casxa") {
       SMLoc S = Parser.getTok().getLoc();
       if (getLexer().getKind() != AsmToken::Percent)
         return MatchOperand_NoMatch;
@@ -1014,7 +1014,22 @@
       return true;
     }

-    // %fprs is an alias of %asr6.
+    // %asrN aliases.
+    if (name.equals("ccr")) {
+      RegNo = ASRRegs[2];
+      RegKind = SparcOperand::rk_Special;
+      return true;
+    }
+    if (name.equals("asi")) {
+      RegNo = ASRRegs[3];
+      RegKind = SparcOperand::rk_Special;
+      return true;
+    }
+    if (name.equals("pc")) {
+      RegNo = ASRRegs[5];
+      RegKind = SparcOperand::rk_Special;
+      return true;
+    }
     if (name.equals("fprs")) {
       RegNo = ASRRegs[6];
       RegKind = SparcOperand::rk_Special;
--- contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td    (revision 354566)
+++ contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td    (working copy)
@@ -495,6 +495,15 @@

 } // Predicates = [Is64Bit], Constraints = ...

+// CASX with explicit ASI; ASM-only, LLVM doesn't grok ASIs, etc, etc.
+let Predicates = [Is64Bit], Constraints = "$swap = $rd" in {
+  def CASXArr: F3_1_asi<3, 0b111110,
+                (outs I64Regs:$rd), (ins I64Regs:$rs1, i8imm:$asi,
+                                    I64Regs:$rs2, I64Regs:$swap),
+                 "casxa [$rs1] $asi, $rs2, $rd",
+                 []>;
+}
+
 let Predicates = [Is64Bit] in {

 def : Pat<(atomic_fence imm, imm), (MEMBARi 0xf)>;
--- contrib/llvm/lib/Target/Sparc/SparcInstrAliases.td  (revision 354566)
+++ contrib/llvm/lib/Target/Sparc/SparcInstrAliases.td  (working copy)
@@ -477,6 +477,8 @@

 // unimp -> unimp 0
 def : InstAlias<"unimp", (UNIMP 0), 0>;
+// illtrap -> unimp (same instruction, FreeBSD .S uses illtrap)
+def : MnemonicAlias<"illtrap", "unimp">;

 def : MnemonicAlias<"iflush", "flush">;

@@ -492,6 +494,9 @@
 def : MnemonicAlias<"stuha", "stha">;
 def : MnemonicAlias<"stsha", "stha">;

+// V8 ST renamed to STW in V9 (equivalent) (also: stuw, stsw, but we don't use those)
+def : MnemonicAlias<"stw", "st">;
+
 def : MnemonicAlias<"lduw", "ld">, Requires<[HasV9]>;
 def : MnemonicAlias<"lduwa", "lda">, Requires<[HasV9]>;


Still runs into linking issues (using LLD) *very* early on (and ld.bfd segfaults).  LLD.SPARC doesn't grok symbolic R_SPARC_64 relocations in shared libraries (used by self-referential __dso_handle pointer in CRT), doesn't grok GOT, and doesn't grok TLS relocations.  This probably needs someone with an intimate knowledge of at least two out of three of: SPARCV9, LLD, and ELF loader/linker model.  (Not to mention: time, and caring about 15-20 year old dead hardware.)
Comment 10 Ed Maste freebsd_committer freebsd_triage 2019-11-11 14:06:37 UTC
(In reply to Conrad Meyer from comment #7)
> +    defined(__sparc__)

__sparc__ or __sparc64__?
Comment 11 Conrad Meyer freebsd_committer freebsd_triage 2019-11-11 15:30:23 UTC
(In reply to Ed Maste from comment #10)
For us, they’re both defined, and we only support sparc64.  The un-numbered variant was already used in that file, so I just followed existing convention.

The upstream numbers (cursor words) are probably intended for 32bit Sparc.  So this isn’t literally the patch to upstream, if you cared to, but retaining 32bit Sparc isn’t too difficult.

It’s odd- the clang/llvm sparc support is heavily v8 (pre-64bit) focused, but the (rough, minimal) LLD support is V9 *only*. Different contributors, patchwork support...
Comment 12 Mark Linimon freebsd_committer freebsd_triage 2019-11-11 17:18:44 UTC
(In reply to Conrad Meyer from comment #11)

FreeBSD never supported 32 bit sparc.
Comment 13 Conrad Meyer freebsd_committer freebsd_triage 2019-11-11 18:47:54 UTC
(In reply to Mark Linimon from comment #12)
Right.  libunwind comes from LLVM upstream.  All I meant by my comments about retaining 32-bit Sparc were directed at not breaking support for it in LLVM upstream -- not about FreeBSD.
Comment 14 commit-hook freebsd_committer freebsd_triage 2020-01-08 20:37:34 UTC
A commit references this bug:

Author: emaste
Date: Wed Jan  8 20:37:04 UTC 2020
New revision: 356513
URL: https://svnweb.freebsd.org/changeset/base/356513

Log:
  libunwind: untested attempt to fix sparc64 build

  sparc64 is the only architecture currently using the DWARF unwinder from
  GCC 4.2.1.  Old GCC and related libraries are being removed soon; absent
  other changes sparc64 would be left with no unwinder when that happens.

  Instead, commit these changes which should at least allow the LLVM
  unwinder to build.  Someone with access to the obolete sparc64 hardware
  supported by FreeBSD will need to test the result.

  PR:		233405
  Submitted by:	cem

Changes:
  head/contrib/llvm-project/libunwind/include/__libunwind_config.h
  head/contrib/llvm-project/libunwind/src/config.h
Comment 15 commit-hook freebsd_committer freebsd_triage 2020-01-08 20:45:36 UTC
A commit references this bug:

Author: emaste
Date: Wed Jan  8 20:45:18 UTC 2020
New revision: 356514
URL: https://svnweb.freebsd.org/changeset/base/356514

Log:
  src.opts.mk: enable LLVM_UNWIND by default for all archs

  Only sparc64 did not enable LLVM_LIBUNWIND. After r356513 LLVM_LIBUNWIND
  should at least build on sparc64. The old DWARF unwinder will be removed
  along with GCC 4.2.1 in the near future, so switch sparc64 to use LLVM's
  unwinder in advance of the removal.  Someone with access to the obsolete
  sparc64 hardware supported by FreeBSD will have to test, and investigate
  any failures. I will gladly help, but I don't have any suitable hardware
  myself.

  PR:		233405

Changes:
  head/share/mk/src.opts.mk
Comment 16 Ed Maste freebsd_committer freebsd_triage 2020-01-09 16:04:56 UTC
r356513 reverted at submitter's request. Someone with sparc64 hw needs to apply the patch and test.
Comment 17 commit-hook freebsd_committer freebsd_triage 2020-01-30 02:46:34 UTC
A commit references this bug:

Author: meta
Date: Thu Jan 30 02:45:33 UTC 2020
New revision: 524622
URL: https://svnweb.freebsd.org/changeset/ports/524622

Log:
  www/sabredav: unbreak, make fetchable

  use WWWDIR in pkg-plist

  PR:		233405
  Submitted by:	Krzysztof <ports@bsdserwis.com>
  Approved by:	matthias+freebsd+bugzilla@harz.de (maintainer)

Changes:
  head/www/sabredav/Makefile
  head/www/sabredav/distinfo
  head/www/sabredav/pkg-plist
Comment 18 Ed Maste freebsd_committer freebsd_triage 2020-02-02 22:32:49 UTC
imp@ started removing sparc64 support as of r357407
Comment 19 Ed Maste freebsd_committer freebsd_triage 2020-02-28 16:26:37 UTC
sparc64 removed from HEAD prior to GCC 4.2.1 retirement
Comment 20 commit-hook freebsd_committer freebsd_triage 2020-03-08 21:22:08 UTC
A commit references this bug:

Author: emaste
Date: Sun Mar  8 21:21:47 UTC 2020
New revision: 358787
URL: https://svnweb.freebsd.org/changeset/base/358787

Log:
  MFC r354468: arch.7: claim 12.x as the last architecture with sparc64 support

  PR:		228919, 233405, 236839, 239851

Changes:
_U  stable/12/
  stable/12/share/man/man7/arch.7