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