Bug 233405 - sparc64: DWARF unwinder required for GCC 4.2.1 retirement
Summary: sparc64: DWARF unwinder required for GCC 4.2.1 retirement
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: misc (show other bugs)
Version: CURRENT
Hardware: sparc64 Any
: --- Affects Only Me
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks: 228919 233094
  Show dependency treegraph
 
Reported: 2018-11-22 14:41 UTC by Ed Maste
Modified: 2019-11-11 18:47 UTC (History)
3 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 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 2018-11-22 17:51:20 UTC
(We could also retire sparc64 before 13.0.)
Comment 2 Ed Maste freebsd_committer 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 2019-08-14 16:34:33 UTC
Would an acceptable unwind implementation on Sparc be "raise(SIGKILL);"?
Comment 4 Ed Maste freebsd_committer 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 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 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 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 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 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 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 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 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.