When building ports-gcc on riscv64 I get this kind of error:

--8<--
ld: error: relocation refers to a symbol in a discarded section: .LEHB30
>>> defined in .libs/libcp1.o
>>> referenced by connection.hh:72 
>>> (/usr/ports/pobj/gcc-8.4.0/gcc-8.4.0/libcc1/connection.hh:72)
>>>               .libs/libcp1.o:(.gcc_except_table+0x1A9)
>>> referenced by connection.hh:72 
>>> (/usr/ports/pobj/gcc-8.4.0/gcc-8.4.0/libcc1/connection.hh:72)
>>>               .libs/libcp1.o:(.gcc_except_table+0x1AD)
-->8--

The checks in ld.lld try to implement the ELF specs in a strict way,
but this causes problems on riscv[0] and other architectures (the
comments in the diff with additional context below).  The
.gcc_except_table case has been fixed in newer clang releases[1] but
I suspect gcc hasn't improved upstream - looking only at their bugzilla.

One can work around this with -ffunction-sections so that
.gcc_except_table is split and the parts pointing at discarded sections
can be pruned. But this feels like a hack and would require egcc/eg++
consumers to use it. AFAIK there is no documented knob to downgrade this
kind of error to a warning.

Hence the diff below, which happens to be the same proposal as in [0].
I have split this case from the checks above, thinking that it would let
me both document the workaround and lessen the risk of merge conflict.
But I can merge the .gcc_except_table case with the checks above it if
preferred.

Thoughts?  ok?


[0] https://reviews.llvm.org/D83244
[1] https://reviews.llvm.org/D83655


Index: ELF/Relocations.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/lld/ELF/Relocations.cpp,v
retrieving revision 1.4
diff -u -p -U15 -r1.4 Relocations.cpp
--- ELF/Relocations.cpp 17 Dec 2021 14:46:47 -0000      1.4
+++ ELF/Relocations.cpp 6 Sep 2022 01:08:23 -0000
@@ -974,30 +974,36 @@ static bool maybeReportUndefined(Symbol 
     return false;
 
   // clang (as of 2019-06-12) / gcc (as of 8.2.1) PPC64 may emit a .rela.toc
   // which references a switch table in a discarded .rodata/.text section. The
   // .toc and the .rela.toc are incorrectly not placed in the comdat. The ELF
   // spec says references from outside the group to a STB_LOCAL symbol are not
   // allowed. Work around the bug.
   //
   // PPC32 .got2 is similar but cannot be fixed. Multiple .got2 is infeasible
   // because .LC0-.LTOC is not representable if the two labels are in different
   // .got2
   if (cast<Undefined>(sym).discardedSecIdx != 0 &&
       (sec.name == ".got2" || sec.name == ".toc"))
     return false;
 
+  // GCC (at least 8 and 11) can produce a ".gcc_except_table" with relocations
+  // to discarded sections on riscv64
+  if (cast<Undefined>(sym).discardedSecIdx != 0 &&
+      sec.name == ".gcc_except_table")
+    return false;
+
   bool isWarning =
       (config->unresolvedSymbols == UnresolvedPolicy::Warn && canBeExternal) ||
       config->noinhibitExec;
   undefs.push_back({&sym, {{&sec, offset}}, isWarning});
   return !isWarning;
 }
 
 // MIPS N32 ABI treats series of successive relocations with the same offset
 // as a single relocation. The similar approach used by N64 ABI, but this ABI
 // packs all relocations into the single relocation record. Here we emulate
 // this for the N32 ABI. Iterate over relocation with the same offset and put
 // theirs types into the single bit-set.
 template <class RelTy> static RelType getMipsN32RelType(RelTy *&rel, RelTy 
*end) {
   RelType type = 0;
   uint64_t offset = rel->r_offset;

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to