Created attachment 7330 [details] Patch If ld is used to partially link several object files that have different text sections (e.g., .text and .init), the resulting object file (when used in further linking) makes ld emit an error while reading .eh_frame sections. Test case: $ cat qq1.s .text bar: .cfi_startproc; ret; .cfi_endproc $ cat qq2.s .section .init,"ax",@progbits .globl baz baz: .cfi_startproc; ret; .cfi_endproc $ /home/aneyman/work/install/bin/as -o qq1.o qq1.s $ /home/aneyman/work/install/bin/as -o qq2.o qq2.s $ /home/aneyman/work/install/bin/ld -r -o qq.o qq1.o qq2.o $ /home/aneyman/work/install/bin/ld -o qq -e baz qq.o /home/aneyman/work/install/bin/ld: error in qq.o(.eh_frame); no .eh_frame_hdr table will be created. The problem is that the code in bfd/elf-eh-frame.c assumes the relocations in the .rela.eh_frame are ordered (see GET_RELOC/SKIP_RELOCS/ENSURE_NO_RELOCS macros), but the assumption does not hold in the above scenario: $ readelf -Wr qq.o Relocation section '.rela.eh_frame' at offset 0x370 contains 2 entries: Offset Info Type Symbol's Value Symbol's Name + Addend 0000000000000050 0000000100000002 R_X86_64_PC32 0000000000000000 .init + 0 0000000000000020 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 0 The attached patch makes the code in bfd/elf-eh-frame.c fall back to slower but more resilient relocation search/check functions if it fails to interpret the .eh_frame section with the ordering assumption. Patch does not add any regressions to 'make check'. I don't know if it would be right to sort the relocations on the output. If needed, such sorting can be added separately.
.init section is a special section: .init This section holds executable instructions that contribute to the process initialization code. When a program starts to run, the system arranges to execute the code in this section before calling the main program entry point (called main for C programs). Did you really want to use .init section here?
Both .init and .fini sections are special. This patch warns about using "ld -r" on them: diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 9a2fe89..098f423 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1114,7 +1114,20 @@ gld${EMULATION_NAME}_after_open (void) } if (link_info.relocatable) - return; + { + bfd *abfd; + + for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next) + { + if (bfd_get_section_by_name (abfd, ".init")) + einfo ("%P: warning: -r on %B with .init section may lead" + " to incorrect output.\n", abfd); + if (bfd_get_section_by_name (abfd, ".fini")) + einfo ("%P: warning: -r on %B with .fini section may lead" + " to incorrect output.\n", abfd); + } + return; + } if (link_info.eh_frame_hdr && !link_info.traditional_format)
Well, we've been using partial linking to isolate module interfaces. One of the modules is CPU support - which includes the start-up code for the kernel. Naturally, this start up code was put into the .init section. Our code in .init does not have .eh_frame contributions, but the mere presence of the .init section in the object file already makes `ld -r` output unsorted relocations. You can see that by substituting qq2.s in the test case with: .section .init,"ax",@progbits /* empty .init section */ .text .globl baz baz: .cfi_startproc; ret; .cfi_endproc Now, it is probably possible for us to rename the .init section to, say, .text.startup - but are there any guarantees that `ld -r` is not going to mess up the output relocations in that case? Also, the quote from LSB talks about semantical differences between .text and .init. Is there any technical reason not to allow `ld -r` on files with .init? Perhaps, it would be better to accept such files with unordered relocations on input and/or order the relocations on output?
.init is a special section and linker treats it differently. If you use a section name like .text.startup, it should work. If not, please open a new linker bug report and I will fix it.
.text.init seems to work. You are still going to commit the patch that adds warnings for .init/.fini, correct? Also, I think, a mention in the description of -r option in ld.info would be appropriate.
(In reply to Alexey Neyman from comment #5) > You are still going to commit the patch that adds warnings for .init/.fini, > correct? No. > Also, I think, a mention in the description of -r option in ld.info would be > appropriate. .init section can only be used according to the gABI. It is irrelevant to ld -r. When in doubt, DON't USE special sections documented in the gABI for your own purpose.
(In reply to H.J. Lu from comment #6) > > Also, I think, a mention in the description of -r option in ld.info would be > > appropriate. > > .init section can only be used according to the gABI. It is irrelevant > to ld -r. When in doubt, DON't USE special sections documented in the > gABI for your own purpose. The .text section is also listed as a "special section" in gABI/LSB, yet you suggested to use it: ---- Special Sections ... .init This section holds executable instructions that contribute to the process initialization code. When a program starts to run, the system arranges to execute the code in this section before calling the main program entry point (called main for C programs). ... .text This section holds the ``text,'' or executable instructions, of a program. ---- I don't see how putting startup code in .init in a freestanding environment contradicts the usage described by gABI, nor why a presense of the .init section in any of the input objects should affect the relocation order in .text section. Could you explain why you think the test case is not compliant to gABI? Especially, the second version with the empty .init section?
(In reply to Alexey Neyman from comment #7) > (In reply to H.J. Lu from comment #6) > > > Also, I think, a mention in the description of -r option in ld.info would be > > > appropriate. > > > > .init section can only be used according to the gABI. It is irrelevant > > to ld -r. When in doubt, DON't USE special sections documented in the > > gABI for your own purpose. > > The .text section is also listed as a "special section" in gABI/LSB, yet you > suggested to use it: > > ---- > Special Sections > ... > .init > This section holds executable instructions that contribute to the process > initialization code. When a program starts to run, the system arranges to > execute the code in this section before calling the main program entry point > (called main for C programs). Linker concatenates all input .init sections and turn it into a single function. You can't use it for yourself.
I also encountered the error (warning?) "no .eh_frame_hdr table will be created." when linking a relocatable object (without .init). This bug report (and patch) discusses handling the problem of unsorted relocators at the time of final linking, when the message is raised. However, this problem was solved at partial linking in bug #17666, and that fix solved my problem.