bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/18223] New: _init/_fini dropped with --gc-sections


From: rmorell at nvidia dot com
Subject: [Bug ld/18223] New: _init/_fini dropped with --gc-sections
Date: Thu, 09 Apr 2015 01:50:41 +0000

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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]