Page MenuHomePhabricator

[lld] Don't error out on relocations in .gcc_except_table to discarded sections.
Needs RevisionPublic

Authored by abidh on Jul 6 2020, 11:10 AM.

Details

Summary

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.

Diff Detail

Event Timeline

abidh created this revision.Jul 6 2020, 11:10 AM

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?

abidh added a comment.Jul 7 2020, 2:03 AM

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.cpp

locale.cpp.o:(.gcc_except_table+0x6FD) in archive /opt/llvm/lib/clang-runtimes/riscv64-unknown-elf/rv64imac/lp64/medany/lib/libc++.a

referenced 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++.a

referenced 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
MaskRay added a comment.EditedJul 7 2020, 5:46 PM

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.cpp

locale.cpp.o:(.gcc_except_table+0x6FD) in archive /opt/llvm/lib/clang-runtimes/riscv64-unknown-elf/rv64imac/lp64/medany/lib/libc++.a

referenced 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++.a

referenced 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.

abidh updated this revision to Diff 277104.Jul 10 2020, 11:08 AM

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

MaskRay requested changes to this revision.EditedJul 12 2020, 11:56 AM

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.

This revision now requires changes to proceed.Jul 12 2020, 11:56 AM

Can be abandoned after D83655