[PATCH] ELF/LD: Avoid producing hidden and internal dynamic symbols

Maciej W. Rozycki macro@imgtec.com
Mon Apr 4 16:49:00 GMT 2016


Always turn hidden and internal symbols which have a dynamic index into 
local ones.  This is required by the the ELF gABI[1]:

"A hidden symbol contained in a relocatable object must be either 
removed or converted to STB_LOCAL binding by the link-editor when the 
relocatable object is included in an executable file or shared object."

"An internal symbol contained in a relocatable object must be either 
removed or converted to STB_LOCAL binding by the link-editor when the 
relocatable object is included in an executable file or shared object."

The ELF linker usually respects this requirement, however in the case 
where a dynamic symbol has been preallocated due to a reference of the 
default export class aka visibility from the object being linked, and 
then merged with a hidden or internal symbol definition from within the 
same object, then the original export class is carried over to the 
output dynamic symbol table, because while merging the generic ELF 
linker only converts affected dynamic symbols to local when they are 
defined or referenced by the object being linked and a dynamic object 
involved in the link both at a time.

The dynamic symbol produced confuses then the dynamic loader at the run 
time -- the hidden or internal export class is ignored and the symbol 
follows preemption rules as with the default export class.

In the MIPS target it happens when `mips_elf_record_global_got_symbol' 
creates a dynamic symbol when a call relocation is encountered. 
Additionally if the undefined symbol referred by such a relocation does 
specify the intended export class, then a local dynamic symbol is 
created instead, which is harmless and allowed, but useless.  Normally
no local dynamic symbols are created, except for a single dummy one at 
the beginning.

Correct the problem by removing the extra check for a dynamic symbol
being defined or referenced by the object being linked and a dynamic
object involved in the link both at a time.  The test cases included 
cover the internal and hidden symbol cases, as well as a protected 
symbol for a reference, the handling of which is unchanged by this fix.
Both cases described above are covered, that is where an internal or 
hidden dynamic symbol is produced and where a local one is.

NB this change affects CRIS results where some symbols in the static 
table produced in a final link are now converted from STV_HIDDEN to 
STB_LOCAL.  This happens whenever the `elf_backend_hide_symbol' handler 
is called, so the affected symbols must have been chosen for entering 
into the dynamic symbol table, except in these test cases no such symbol 
table is produced.  In fully linked binaries the static symbol table is 
only used for debugging though, so such a change is fine.

References:

[1] "System V Application Binary Interface - DRAFT - 24 April 2001",
    The Santa Cruz Operation, Inc., "Symbol Table",
    <http://www.sco.com/developers/gabi/2001-04-24/ch4.symtab.html>

2016-04-04  Maciej W. Rozycki  <macro@imgtec.com>

	bfd/
	PR ld/19908
	* elflink.c (elf_link_add_object_symbols): Always turn hidden
	and internal symbols which have a dynamic index into local
	ones.

	ld/testsuite/
	PR ld/19908
	* ld-cris/tls-e-20.d: Adjust for hidden symbol handling fix.
	* ld-cris/tls-e-20a.d: Likewise.
	* ld-cris/tls-e-21.d: Likewise.
	* ld-cris/tls-e-23.d: Likewise.
	* ld-cris/tls-e-80.d: Likewise.
	* ld-cris/tls-gd-3h.d: Likewise.
	* ld-cris/tls-leie-19.d: Likewise.
	* ld-mips-elf/export-class-ref-lib.sd: New test.
	* ld-mips-elf/export-hidden-ref.sd: New test.
	* ld-mips-elf/export-internal-ref.sd: New test.
	* ld-mips-elf/export-protected-ref.sd: New test.
	* ld-mips-elf/export-class-ref-f0.s: New test source.
	* ld-mips-elf/export-class-ref-f1.s: New test source.
	* ld-mips-elf/export-class-ref-f2.s: New test source.
	* ld-mips-elf/mips-elf.exp: Run the new tests.
---

 OK to apply?

  Maciej

binutils-bfd-elf-add-symbol-dynindx-export-class.diff
Index: binutils/bfd/elflink.c
===================================================================
--- binutils.orig/bfd/elflink.c	2016-04-04 02:11:17.482717336 +0100
+++ binutils/bfd/elflink.c	2016-04-04 02:55:57.179886886 +0100
@@ -4569,7 +4569,7 @@ elf_link_add_object_symbols (bfd *abfd, 
 		    goto error_free_vers;
 		}
 	    }
-	  else if (dynsym && h->dynindx != -1)
+	  else if (h->dynindx != -1)
 	    /* If the symbol already has a dynamic index, but
 	       visibility says it should not be visible, turn it into
 	       a local symbol.  */
Index: binutils/ld/testsuite/ld-cris/tls-e-20.d
===================================================================
--- binutils.orig/ld/testsuite/ld-cris/tls-e-20.d	2016-04-04 02:11:17.491806432 +0100
+++ binutils/ld/testsuite/ld-cris/tls-e-20.d	2016-04-04 02:18:21.995389532 +0100
@@ -35,8 +35,8 @@ Idx Name          Size      VMA       LM
 0+80094 l    d  \.text	0+ \.text
 0+820b0 l    d  \.tdata	0+ \.tdata
 0+820bc l    d  \.got	0+ \.got
+0+ l       \.tdata	0+4 x
 0+820bc l     O \.got	0+ _GLOBAL_OFFSET_TABLE_
-0+ g       \.tdata	0+4 \.hidden x
 0+80098 g     F \.text	0+6 tlsdsofn2
 0+8 g       \.tdata	0+4 \.hidden x2
 0+80094 g       \.text	0+ _start
Index: binutils/ld/testsuite/ld-cris/tls-e-20a.d
===================================================================
--- binutils.orig/ld/testsuite/ld-cris/tls-e-20a.d	2016-04-04 02:11:17.497841393 +0100
+++ binutils/ld/testsuite/ld-cris/tls-e-20a.d	2016-04-04 02:18:22.009797212 +0100
@@ -43,8 +43,8 @@ Idx Name          Size      VMA       LM
 0+ l    df \*ABS\*	0+ .*
 0+ l       \.tdata	0+80 tls128
 0+ l    df \*ABS\*	0+ .*
+0+80 l       \.tdata	0+4 x
 0+82168 l     O \.got	0+ _GLOBAL_OFFSET_TABLE_
-0+80 g       \.tdata	0+4 \.hidden x
 0+800c4 g     F \.text	0+6 tlsdsofn2
 0+821b4 g     O \.data	0+4 got7var5
 0+88 g       \.tdata	0+4 \.hidden x2
Index: binutils/ld/testsuite/ld-cris/tls-e-21.d
===================================================================
--- binutils.orig/ld/testsuite/ld-cris/tls-e-21.d	2016-04-04 02:11:17.508056408 +0100
+++ binutils/ld/testsuite/ld-cris/tls-e-21.d	2016-04-04 02:18:22.026221376 +0100
@@ -19,7 +19,7 @@
 #...
 SYMBOL TABLE:
 #...
-0+80 g       \.tdata	0+4 \.hidden x
+0+80 l       \.tdata	0+4 x
 #...
 Contents of section \.text:
 #...
Index: binutils/ld/testsuite/ld-cris/tls-e-23.d
===================================================================
--- binutils.orig/ld/testsuite/ld-cris/tls-e-23.d	2016-04-04 02:11:17.519228229 +0100
+++ binutils/ld/testsuite/ld-cris/tls-e-23.d	2016-04-04 02:18:22.048799946 +0100
@@ -19,7 +19,7 @@
 #...
 SYMBOL TABLE:
 #...
-0+80 g       \.tdata	0+4 \.hidden x
+0+80 l       \.tdata	0+4 x
 #...
 Contents of section \.text:
 #...
Index: binutils/ld/testsuite/ld-cris/tls-e-80.d
===================================================================
--- binutils.orig/ld/testsuite/ld-cris/tls-e-80.d	2016-04-04 02:11:17.523346614 +0100
+++ binutils/ld/testsuite/ld-cris/tls-e-80.d	2016-04-04 02:18:22.065386640 +0100
@@ -42,8 +42,8 @@ Idx Name          Size      VMA       LM
 0+820c0 l    d  \.tdata	0+ \.tdata
 0+820d0 l    d  \.tbss	0+ \.tbss
 0+820d0 l    d  \.got	0+ \.got
+0+ l       \.tdata	0+4 x
 0+820d0 l     O \.got	0+ _GLOBAL_OFFSET_TABLE_
-0+ g       \.tdata	0+4 \.hidden x
 0+800a0 g     F \.text	0+6 tlsdsofn2
 0+800a8 g     F \.text	0+6 tlsfn12
 0+c g       \.tdata	0+4 \.hidden x2
Index: binutils/ld/testsuite/ld-cris/tls-gd-3h.d
===================================================================
--- binutils.orig/ld/testsuite/ld-cris/tls-gd-3h.d	2016-04-04 02:11:17.530413598 +0100
+++ binutils/ld/testsuite/ld-cris/tls-gd-3h.d	2016-04-04 02:18:22.077650334 +0100
@@ -19,7 +19,7 @@
 #...
 SYMBOL TABLE:
 #...
-0+80 g       \.tdata	0+4 \.hidden x
+0+80 l       \.tdata	0+4 x
 #...
 Contents of section \.text:
 #...
Index: binutils/ld/testsuite/ld-cris/tls-leie-19.d
===================================================================
--- binutils.orig/ld/testsuite/ld-cris/tls-leie-19.d	2016-04-04 02:11:17.539511136 +0100
+++ binutils/ld/testsuite/ld-cris/tls-leie-19.d	2016-04-04 02:18:22.087797215 +0100
@@ -26,13 +26,13 @@
                   CONTENTS.*
 SYMBOL TABLE:
 #...
-0+88 g       .tdata	0+4 x
+0+84 l       \.tdata	0+4 x2
 #...
-0+84 g       \.tdata	0+4 \.hidden x2
+0+80 l       \.tdata	0+4 x1
 #...
-0+8c g       .tdata	0+4 z
+0+88 g       .tdata	0+4 x
 #...
-0+80 g       \.tdata	0+4 \.hidden x1
+0+8c g       .tdata	0+4 z
 #...
 Contents of section \.text:
 #...
Index: binutils/ld/testsuite/ld-mips-elf/export-class-ref-f0.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-class-ref-f0.s	2016-04-04 17:46:54.691435206 +0100
@@ -0,0 +1,37 @@
+	.abicalls
+	.text
+
+	.if	refv == 3
+	.protected f1
+	.elseif	refv == 2
+	.hidden	f1
+	.elseif	refv == 1
+	.internal f1
+	.endif
+
+	.globl	f0
+	.ent	f0
+f0:
+	.frame	$sp, 32, $31
+	.mask	0x80000000, -4
+	.fmask	0x00000000, 0
+	.set	noreorder
+	.cpload	$25
+	.set	reorder
+	addiu	$sp, $sp, -32
+	sw	$31, 28($sp)
+	.cprestore 16
+
+	lw	$25, %call16(f1)($28)
+	jalr	$25
+	lw	$28, 16($sp)
+
+	lw	$25, %call16(f2)($28)
+	jalr	$25
+	lw	$28, 16($sp)
+
+	move	$2, $0
+	lw	$31, 28($sp)
+	addiu	$sp, $sp, 32
+	jr	$31
+	.end	f0
Index: binutils/ld/testsuite/ld-mips-elf/export-class-ref-f1.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-class-ref-f1.s	2016-04-04 02:20:33.265839001 +0100
@@ -0,0 +1,18 @@
+	.abicalls
+	.text
+
+	.globl	f1
+	.if	defv == 3
+	.protected f1
+	.elseif	defv == 2
+	.hidden	f1
+	.elseif	defv == 1
+	.internal f1
+	.endif
+	.ent	f1
+f1:
+	.frame	$sp, 0, $31
+	.mask	0x00000000, 0
+	.fmask	0x00000000, 0
+	jr	$31
+	.end	f1
Index: binutils/ld/testsuite/ld-mips-elf/export-class-ref-f2.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-class-ref-f2.s	2016-04-04 02:18:22.152518507 +0100
@@ -0,0 +1,20 @@
+	.abicalls
+	.text
+
+	.globl	f1
+	.ent	f1
+f1:
+	.frame	$sp, 0, $31
+	.mask	0x00000000, 0
+	.fmask	0x00000000, 0
+	jr	$31
+	.end	f1
+
+	.globl	f2
+	.ent	f2
+f2:
+	.frame	$sp, 0, $31
+	.mask	0x00000000, 0
+	.fmask	0x00000000, 0
+	jr	$31
+	.end	f2
Index: binutils/ld/testsuite/ld-mips-elf/export-class-ref-lib.sd
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-class-ref-lib.sd	2016-04-04 02:18:22.170814493 +0100
@@ -0,0 +1,6 @@
+# Make sure `f1' is present in the dynamic symbol table, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      6: 000002d0     8 FUNC    GLOBAL DEFAULT    7 f1
+#...
+ *[0-9]+: +[0-9a-f]+ +[0-9]+ FUNC +GLOBAL +DEFAULT +[0-9]+ f1
+#pass
Index: binutils/ld/testsuite/ld-mips-elf/export-hidden-ref.sd
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-hidden-ref.sd	2016-04-04 02:18:22.185140491 +0100
@@ -0,0 +1,7 @@
+# Make sure no hidden symbol is present in the dynamic symbol table, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      6: 004003f0     8 FUNC    GLOBAL HIDDEN     8 f1
+#failif
+#...
+.+ +HIDDEN +.+ +f1
+#pass
Index: binutils/ld/testsuite/ld-mips-elf/export-internal-ref.sd
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-internal-ref.sd	2016-04-04 02:18:22.196436449 +0100
@@ -0,0 +1,7 @@
+# Make sure no internal symbol is present in the dynamic symbol table, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      6: 004003f0     8 FUNC    GLOBAL INTERNAL   8 f1
+#failif
+#...
+.+ +INTERNAL +.+ +f1
+#pass
Index: binutils/ld/testsuite/ld-mips-elf/export-local-ref.sd
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-local-ref.sd	2016-04-04 02:18:22.225153971 +0100
@@ -0,0 +1,7 @@
+# Make sure no local symbol is present in the dynamic symbol table, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      6: 004003f0     8 FUNC    LOCAL  DEFAULT    8 f1
+#failif
+#...
+.+ +LOCAL +.+ +f1
+#pass
Index: binutils/ld/testsuite/ld-mips-elf/export-protected-ref.sd
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/ld/testsuite/ld-mips-elf/export-protected-ref.sd	2016-04-04 02:18:22.211966274 +0100
@@ -0,0 +1,6 @@
+# Make sure a protected symbol is present in the dynamic symbol table, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      6: 004003f0     8 FUNC    GLOBAL PROTECTED    8 f1
+#...
+ *[0-9]+: +[0-9a-f]+ +[0-9]+ FUNC +GLOBAL +PROTECTED +[0-9]+ f1
+#pass
Index: binutils/ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- binutils.orig/ld/testsuite/ld-mips-elf/mips-elf.exp	2016-04-04 02:11:17.572090593 +0100
+++ binutils/ld/testsuite/ld-mips-elf/mips-elf.exp	2016-04-04 17:38:01.625645616 +0100
@@ -899,3 +899,31 @@ if { $linux_gnu } {
 	    n32 -1 1 umips
     }
 }
+
+# PR ld/19908 export class tests.
+if { $linux_gnu } {
+    run_ld_link_tests [list \
+	[list "Shared library for MIPS export class symbol reference test" \
+	      "$abi_ldflags(o32) -shared" "" \
+	      "$abi_asflags(o32)" \
+	      { export-class-ref-f2.s } \
+	      { { readelf --dyn-syms export-class-ref-lib.sd } } \
+	      "export-class-ref-lib.so"]]
+    foreach { class flag } { internal 1 hidden 2 protected 3 } {
+	run_ld_link_tests [list \
+	    [list "MIPS $class symbol reference test 1" \
+		  "$abi_ldflags(o32) -e f0" "tmpdir/export-class-ref-lib.so" \
+		  "$abi_asflags(o32) --defsym defv=$flag" \
+		  { export-class-ref-f0.s export-class-ref-f1.s } \
+		  [list [list readelf --dyn-syms export-$class-ref.sd] \
+			[list readelf --dyn-syms export-local-ref.sd]] \
+		  "export-$class-ref"] \
+	    [list "MIPS $class symbol reference test 2" \
+		  "$abi_ldflags(o32) -e f0" "tmpdir/export-class-ref-lib.so" \
+		  "$abi_asflags(o32) --defsym defv=$flag --defsym refv=$flag" \
+		  { export-class-ref-f0.s export-class-ref-f1.s } \
+		  [list [list readelf --dyn-syms export-$class-ref.sd] \
+			[list readelf --dyn-syms export-local-ref.sd]] \
+		  "export-$class-ref"]]
+    }
+}



More information about the Binutils mailing list