This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] PR ld/21233: Avoid sweeping forced-undefined symbols in section GC


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=80070c0d3491347f11283c5791b9dd040fedbd4f

commit 80070c0d3491347f11283c5791b9dd040fedbd4f
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Mon Mar 27 12:39:07 2017 +0100

    PR ld/21233: Avoid sweeping forced-undefined symbols in section GC
    
    Complement commit 902e9fc76a0e ("PR ld/20828: Move symbol version
    processing ahead of GC symbol sweep"), commit b531344c34b0 ("PR
    ld/20828: Reorder the symbol sweep stage of section GC") and commit
    81ff47b3a546 ("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.

Diff:
---
 ld/ChangeLog                     | 12 ++++++++++++
 ld/ldlang.c                      |  2 ++
 ld/testsuite/ld-elf/pr21233-e.ld |  2 ++
 ld/testsuite/ld-elf/pr21233-l.s  |  6 ++++++
 ld/testsuite/ld-elf/pr21233-l.sd |  6 ++++++
 ld/testsuite/ld-elf/pr21233.ld   | 17 +++++++++++++++++
 ld/testsuite/ld-elf/pr21233.s    |  8 ++++++++
 ld/testsuite/ld-elf/pr21233.sd   |  9 +++++++++
 ld/testsuite/ld-elf/shared.exp   | 39 +++++++++++++++++++++++++++++++++++++++
 9 files changed, 101 insertions(+)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index c9298e9..d8b9a22 100644
--- a/ld/ChangeLog
+++ b/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
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 5a42659..266c099 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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);
     }
 }
diff --git a/ld/testsuite/ld-elf/pr21233-e.ld b/ld/testsuite/ld-elf/pr21233-e.ld
new file mode 100644
index 0000000..f0bc281
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21233-e.ld
@@ -0,0 +1,2 @@
+EXTERN (bar)
+INCLUDE pr21233.ld
diff --git a/ld/testsuite/ld-elf/pr21233-l.s b/ld/testsuite/ld-elf/pr21233-l.s
new file mode 100644
index 0000000..1d02f9a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21233-l.s
@@ -0,0 +1,6 @@
+	.data
+	.globl	bar
+	.type	bar, %object
+bar:
+	.byte	1
+	.size	bar, . - bar
diff --git a/ld/testsuite/ld-elf/pr21233-l.sd b/ld/testsuite/ld-elf/pr21233-l.sd
new file mode 100644
index 0000000..724fdd4
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21233-l.sd
@@ -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
diff --git a/ld/testsuite/ld-elf/pr21233.ld b/ld/testsuite/ld-elf/pr21233.ld
new file mode 100644
index 0000000..a3b547b
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21233.ld
@@ -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/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-elf/pr21233.s b/ld/testsuite/ld-elf/pr21233.s
new file mode 100644
index 0000000..0c405c6
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21233.s
@@ -0,0 +1,8 @@
+	.text
+	.globl	foo
+	.type	foo, %function
+foo:
+	.size	foo, . - foo
+
+	.data
+	.dc.a	bar
diff --git a/ld/testsuite/ld-elf/pr21233.sd b/ld/testsuite/ld-elf/pr21233.sd
new file mode 100644
index 0000000..74d446d
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21233.sd
@@ -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
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 300100a..be30ec0 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -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 } {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]