https://sourceware.org/bugzilla/show_bug.cgi?id=18223
Bug ID: 18223 Summary: _init/_fini dropped with --gc-sections Product: binutils Version: 2.26 (HEAD) Status: NEW Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: rmorell at nvidia dot com Created attachment 8235 --> https://sourceware.org/bugzilla/attachment.cgi?id=8235&action=edit Test case that reproduces the problem This sounds like the same symptom as bug 14726, but it happens with ld rather than gold. I can reproduce with both the latest binutils release (2.25) and the latest git commit (82d8e420ab39cf22). (This also reproduces as far back as 2.22, at least.) The attached test case is a couple of source files and a makefile; when built with 'make' it should produce: a) a library `libtest.so` b) a test program `main`, dynamically linked against libtest.so. libtest.so consists of one global variable 'test' with static linkage, one constructor using the old implicit '_init' method to initialize the variable 'test' to the value 42, and one exported function 'foo' with visibility "default" that returns the current value of 'test'. The source is built with GCC's default visibility "hidden" to localize all non-exported symbols when linking, as well as -ffunction-sections to put each function into its own section. The 'main' test program simply calls foo() from the library and prints the result. The expected result is that when the 'main' program is run, the value 42 is printed. When the library is linked with --gc-sections (as in the attached test case), the _init function is dropped and the value 0 is printed instead. If the makefile is changed to remove --gc-sections and the library is rebuilt, then the expected result of 42 is printed. Unsurprisingly (given bug 14726), this does not reproduce with ld.gold, only ld.bfd. It looks like ld treats _init and _fini specially: info->{init,fini}_function are initialized to _init and _fini, respectively, and then in bfd_elf_size_dynamic_sections(), DT_INIT and DT_FINI dynamic section entries are added to point to them. However, bfd_elf_gc_sections() occurs before bfd_elf_size_dynamic_sections(), so the functions are dropped since they are unreferenced before the dynamic entries can be added. I think the right solution is to add code to bfd_elf_gc_sections() before the "grovelling" step that is similar to that used to set up DT_INIT and DT_FINI, but instead of adding dynamic entries, it just adds the SEC_KEEP flag to the section that they're found in. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils