PR ld/21233: Avoid sweeping forced-undefined symbols in section GC
Complement commit902e9fc76a
("PR ld/20828: Move symbol version processing ahead of GC symbol sweep"), commitb531344c34
("PR ld/20828: Reorder the symbol sweep stage of section GC") and commit81ff47b3a5
("PR ld/20828: Fix linker script symbols wrongly forced local with section GC"), and prevent symbols forcibly entered in the output file with the use of the `--undefined=' or `--require-defined=' linker command line options or the EXTERN linker script command from being swept in section garbage collection and consequently recorded in the dynamic symbol table as local entries. This happens in certain circumstances, where a symbol reference also exists in one of the static input files, however only in a section which is garbage-collected and does not make it to the output file, and the symbol is defined in a dynamic object present in the link. For example with the `i386-linux' target and the `pr21233.s' and `pr21233-l.s' sources, and the `pr21233.ld' linker script included with this change we get: $ as -o pr21233-l.o pr21233-l.s $ ld -shared -T pr21233.ld -o libpr21233.so pr21233-l.o $ as -o pr21233.o pr21233.s $ ld --gc-sections -e foo --require-defined=bar -T pr21233.ld -o pr21233 pr21233.o libpr21233.so $ readelf --dyn-syms pr21233 Symbol table '.dynsym' contains 2 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 OBJECT LOCAL DEFAULT UND bar $ which makes the run-time `bar' dependency of the `pr21233' executable different from its corresponding link-time dependency, i.e. the presence of `libpr21233.so' and its `bar' symbol is required at the link time, however at the run time a copy of `libpr21233.so' without `bar' will do. Similarly with `--undefined=' and EXTERN which do not actually require the reference to the symbol requested to be satisfied with a definition at the link time, however once the definition has been pulled at the link time, so it should at the dynamic load time. Additionally with the `mips-linux' target we get: $ ld --gc-sections -e foo --require-defined=bar -T pr21233.ld -o pr21233 pr21233.o libpr21233.so ld: BFD (GNU Binutils) 2.28.51.20170324 assertion fail .../bfd/elfxx-mips.c:3861 $ as the target is not prepared to handle such a local dynamic symbol. With this change in effect we get: $ readelf --dyn-syms pr21233 Symbol table '.dynsym' contains 2 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 OBJECT GLOBAL DEFAULT UND bar $ instead, for both targets. ld/ PR ld/21233 * ldlang.c (insert_undefined): Set `mark' for ELF symbols. * testsuite/ld-elf/pr21233.sd: New test. * testsuite/ld-elf/pr21233-l.sd: New test. * testsuite/ld-elf/pr21233.ld: New test linker script. * testsuite/ld-elf/pr21233-e.ld: New test linker script. * testsuite/ld-elf/pr21233.s: New test source. * testsuite/ld-elf/pr21233-l.s: New test source. * testsuite/ld-elf/shared.exp: Run the new tests.
This commit is contained in:
parent
4c7bf4f91b
commit
80070c0d34
9 changed files with 101 additions and 0 deletions
12
ld/ChangeLog
12
ld/ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2017-04-04 Maciej W. Rozycki <macro@imgtec.com>
|
||||
|
||||
PR ld/21233
|
||||
* ldlang.c (insert_undefined): Set `mark' for ELF symbols.
|
||||
* testsuite/ld-elf/pr21233.sd: New test.
|
||||
* testsuite/ld-elf/pr21233-l.sd: New test.
|
||||
* testsuite/ld-elf/pr21233.ld: New test linker script.
|
||||
* testsuite/ld-elf/pr21233-e.ld: New test linker script.
|
||||
* testsuite/ld-elf/pr21233.s: New test source.
|
||||
* testsuite/ld-elf/pr21233-l.s: New test source.
|
||||
* testsuite/ld-elf/shared.exp: Run the new tests.
|
||||
|
||||
2017-04-04 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* NEWS: Mention support for ELF SHF_GNU_MBIND and
|
||||
|
|
|
@ -3429,6 +3429,8 @@ insert_undefined (const char *name)
|
|||
{
|
||||
h->type = bfd_link_hash_undefined;
|
||||
h->u.undef.abfd = NULL;
|
||||
if (is_elf_hash_table (link_info.hash))
|
||||
((struct elf_link_hash_entry *) h)->mark = 1;
|
||||
bfd_link_add_undef (link_info.hash, h);
|
||||
}
|
||||
}
|
||||
|
|
2
ld/testsuite/ld-elf/pr21233-e.ld
Normal file
2
ld/testsuite/ld-elf/pr21233-e.ld
Normal file
|
@ -0,0 +1,2 @@
|
|||
EXTERN (bar)
|
||||
INCLUDE pr21233.ld
|
6
ld/testsuite/ld-elf/pr21233-l.s
Normal file
6
ld/testsuite/ld-elf/pr21233-l.s
Normal file
|
@ -0,0 +1,6 @@
|
|||
.data
|
||||
.globl bar
|
||||
.type bar, %object
|
||||
bar:
|
||||
.byte 1
|
||||
.size bar, . - bar
|
6
ld/testsuite/ld-elf/pr21233-l.sd
Normal file
6
ld/testsuite/ld-elf/pr21233-l.sd
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Make sure global `bar' is present in the dynamic symbol table, e.g.:
|
||||
# Num: Value Size Type Bind Vis Ndx Name
|
||||
# 1: 00000000 1 OBJECT GLOBAL DEFAULT 5 bar
|
||||
#...
|
||||
*[0-9]+: +[0-9a-f]+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +bar
|
||||
#pass
|
17
ld/testsuite/ld-elf/pr21233.ld
Normal file
17
ld/testsuite/ld-elf/pr21233.ld
Normal file
|
@ -0,0 +1,17 @@
|
|||
SECTIONS
|
||||
{
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.dyn : { *(.rel.dyn) }
|
||||
.text : { *(.text) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.data : { *(.data) }
|
||||
.symtab : { *(.symtab) }
|
||||
.strtab : { *(.strtab) }
|
||||
.shstrtab : { *(.shstrtab) }
|
||||
.plt : { *(.plt) }
|
||||
.got.plt : { *(.got.plt) }
|
||||
.got : { *(.got) }
|
||||
/DISCARD/ : { *(*) }
|
||||
}
|
8
ld/testsuite/ld-elf/pr21233.s
Normal file
8
ld/testsuite/ld-elf/pr21233.s
Normal file
|
@ -0,0 +1,8 @@
|
|||
.text
|
||||
.globl foo
|
||||
.type foo, %function
|
||||
foo:
|
||||
.size foo, . - foo
|
||||
|
||||
.data
|
||||
.dc.a bar
|
9
ld/testsuite/ld-elf/pr21233.sd
Normal file
9
ld/testsuite/ld-elf/pr21233.sd
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Make sure the `bar' reference is global rather than local
|
||||
# in the dynamic symbol table, e.g.:
|
||||
# Num: Value Size Type Bind Vis Ndx Name
|
||||
# 1: 00000000 0 OBJECT GLOBAL DEFAULT UND bar
|
||||
# vs:
|
||||
# 1: 00000000 0 OBJECT LOCAL DEFAULT UND bar
|
||||
#...
|
||||
*[0-9]+: +[0-9a-f]+ +0 +OBJECT +GLOBAL +DEFAULT +UND +bar
|
||||
#pass
|
|
@ -115,6 +115,45 @@ if { [check_gc_sections_available] } {
|
|||
{{objdump -p pr20828-v.od}} \
|
||||
"pr20828-v-2"]]
|
||||
}
|
||||
# PR ld/21233 check for correct dynamic symbol table entries where:
|
||||
# - a symbol has been defined in a shared library used in the link,
|
||||
# - the symbol has been referenced from a section swept in garbage collection,
|
||||
# - the symbol has also been forced to be entered in the output file as an
|
||||
# undefined symbol, either with a command-line option or a linker script
|
||||
# command.
|
||||
# Verify that the undefined symbol is global rather than local.
|
||||
if { [check_gc_sections_available] } {
|
||||
run_ld_link_tests [list \
|
||||
[list \
|
||||
"PR ld/21233 dynamic symbols with section GC\
|
||||
(auxiliary shared library)" \
|
||||
"$LFLAGS -shared -T pr21233.ld" "" "$AFLAGS_PIC" \
|
||||
{pr21233-l.s} \
|
||||
{{readelf --dyn-syms pr21233-l.sd}} \
|
||||
"libpr21233.so"] \
|
||||
[list \
|
||||
"PR ld/21233 dynamic symbols with section GC (--undefined)" \
|
||||
"$LFLAGS --gc-sections -e foo --undefined=bar -T pr21233.ld" \
|
||||
"tmpdir/libpr21233.so" "" \
|
||||
{pr21233.s} \
|
||||
{{readelf --dyn-syms pr21233.sd}} \
|
||||
"pr21233-1"] \
|
||||
[list \
|
||||
"PR ld/21233 dynamic symbols with section GC (--require-defined)" \
|
||||
"$LFLAGS --gc-sections -e foo --require-defined=bar\
|
||||
-T pr21233.ld" \
|
||||
"tmpdir/libpr21233.so" "" \
|
||||
{pr21233.s} \
|
||||
{{readelf --dyn-syms pr21233.sd}} \
|
||||
"pr21233-2"] \
|
||||
[list \
|
||||
"PR ld/21233 dynamic symbols with section GC (EXTERN)" \
|
||||
"$LFLAGS --gc-sections -e foo -T pr21233-e.ld" \
|
||||
"tmpdir/libpr21233.so" "" \
|
||||
{pr21233.s} \
|
||||
{{readelf --dyn-syms pr21233.sd}} \
|
||||
"pr21233-3"]]
|
||||
}
|
||||
|
||||
# Check to see if the C compiler works
|
||||
if { [which $CC] == 0 } {
|
||||
|
|
Loading…
Add table
Reference in a new issue