[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.
- [Bug ld/18223] New: _init/_fini dropped with --gc-sections,
rmorell at nvidia dot com <=
- [Bug ld/18223] _init/_fini dropped with --gc-sections, amodra at gmail dot com, 2015/04/09
- [Bug ld/18223] _init/_fini dropped with --gc-sections, rmorell at nvidia dot com, 2015/04/09
- [Bug ld/18223] _init/_fini dropped with --gc-sections, jsweval at arxan dot com, 2015/04/09
- [Bug ld/18223] _init/_fini dropped with --gc-sections, cvs-commit at gcc dot gnu.org, 2015/04/09
- [Bug ld/18223] _init/_fini dropped with --gc-sections, amodra at gmail dot com, 2015/04/09
- [Bug ld/18223] _init/_fini dropped with --gc-sections, cvs-commit at gcc dot gnu.org, 2015/04/10
- [Bug ld/18223] _init/_fini dropped with --gc-sections, hjl.tools at gmail dot com, 2015/04/10