Such relocations don't generate errors for -r/--emit-relocs in InputSection::copyRelocations. This patch allows similar behaviour in general and makes lld more consistent.
Details
Diff Detail
Event Timeline
The .eh_frame test case is invalid. LLD handles .eh_frame input sections differently. It parses .eh_frame and deduplicates them. See eh-frame-merge.s, an input .eh_frame referencing a non-prevailing COMDAT group is dropped (EhFrameSection::isFdeLive)
Do you have a realistic case where LLD erroneously errors? If so, can you get a minimal reproduce, use LLD_REPRODUCE=/tmp/rep.tar or -Wl,--reproduce=/tmp/rep.tar to get a reproduce file and upload it somewhere?
The problem that I faced is with gcc_except_table. I added .eh_frame for completion sake. The problem was coming while linking in libc++ for a beremetal target. I will try if I can get a minimal testcase from that but it may be difficult. The error looks like this:
ld.lld: error: relocation refers to a symbol in a discarded section:
defined in /opt/llvm/lib/clang-runtimes/riscv64-unknown-elf/rv64imac/lp64/medany/lib/libc++.a(locale.cpp.o)
section group signature: _ZNSt3116pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
prevailing definition is in /tmp/test-48f00f.o
referenced by locale.cpplocale.cpp.o:(.gcc_except_table+0x6FD) in archive /opt/llvm/lib/clang-runtimes/riscv64-unknown-elf/rv64imac/lp64/medany/lib/libc++.areferenced by locale.cpp
locale.cpp.o:(.gcc_except_table+0x706) in archive /opt/llvm/lib/clang-runtimes/riscv64-unknown-elf/rv64imac/lp64/medany/lib/libc++.areferenced by locale.cpp
locale.cpp.o:(.gcc_except_table+0x70A) in archive /opt/llvm/lib/clang-runtimes/riscv64-unknown-elf/rv64imac/lp64/medany/lib/libc++.a
OK, please drop .eh_frame from the patch. I don't think a valid input can cause lld to choke. For .gcc_except_table, I still hope we can have a better understanding of the problem.
If it is indeed a fundamental unfixable issue like .eh_frame/ppc64 .toc/ppc32 .got2, we may have to work around it, but I want to make sure we are not working around a riscv toolchain problem.
If you can get a reproduce, I'd be happy help analyze it.
I have removed the .eh_frame. I have looked a bit more into it. It seems that riscv target does create relocations in .gcc_except_table. The following commit gives some background on its encoding.
https://reviews.llvm.org/rGab009a602e96b238000d9e20e5c54b078d08aad3
If I use -mno-relax during compilation then I dont see the relocations in .gcc_except_table and the problem goes away. I was able to create a simpler testcase which is attached with https://bugs.llvm.org/show_bug.cgi?id=46675
I think this is invalid. See more on https://bugs.llvm.org/show_bug.cgi?id=46675#c1
I'll try fixing clang -target riscv64 and inspecting whether GCC emitted .eh_frame can be improved.