Define various symbols conditionally in shared libraries executables

H.J. Lu hjl.tools@gmail.com
Wed Jun 6 13:30:00 GMT 2018


On Wed, Jun 06, 2018 at 10:00:43PM +0930, Alan Modra wrote:
> This should be applied on top of the patches attached to
> https://sourceware.org/ml/binutils/2018-06/msg00034.html
> 
> The values of symbols in shared libraries like _end, _edata, and
> __bss_start are generally not that useful outside of the shared
> library.  This patch defines them conditionally with PROVIDE, since a
> shared library might need the local value.  An example is glibc ld.so
> local access to "_begin", "_etext" and "_end".  We can't use
> PROVIDE_HIDDEN because the shared library might need the value of the
> symbol in the executable.  An example is freebsd libc dynamic access
> to "_end".
> 
> 	PR ld/23161
> 	* emulparams/aarch64cloudabi.sh: PROVIDE __bss_start__, _bss_end__,
> 	and __end__ in shared libraries.
> 	* emulparams/aarch64fbsd.sh: Likewise.
> 	* emulparams/aarch64linux.sh: Likewise.
> 	* emulparams/aarch64linux32.sh: Likewise.
> 	* emulparams/armelf_fuchsia.sh: Likewise.
> 	* emulparams/armelf_linux.sh: Likewise.
> 	* emulparams/armelf_phoenix.sh: Likewise.
> 	* emulparams/aarch64elf.sh: Likewise, and __data_start
> 	* emulparams/aarch64elf32.sh: Likewise.
> 	* emulparams/armelf.sh: Likewise.
> 	* emulparams/armnto.sh: Likewise.
> 	* emulparams/elf32bmip.sh: Remove duplicate ". = ." from
> 	OTHER_GOT_SYMBOLS.  PROVIDE _ftext, _fdata, and _fbss in shared libs.
> 	* emulparams/elf32bmipn32-defs.sh: Likewise.
> 	* emulparams/elf32frv.sh: PROVIDE __end and __data_start in shared libs.
> 	* emulparams/elf32lriscv-defs.sh: Tidy.
> 	* emulparams/elf32mcore.sh: PROVIDE __bss_start and _bss_end in
> 	shared libs
> 	* emulparams/elf32ppccommon.sh: PROVIDE __end in shared libs.
> 	* emulparams/elf32rl78.sh: Tidy.
> 	* emulparams/i386nto.sh: PROVIDE _btext in shared libs.
> 	* emulparams/shelf_nto.sh: Likewise.
> 	* emulparams/shlelf_nto.sh: Likewise.
> 	* emulparams/score3_elf.sh: PROVIDE _gp, _bss_start__, _bss_end__,
> 	__bss_end__, __end__, _fdata, _sdata_begin, and _bss_start in
> 	shared libs.
> 	* scripttempl/elf.sc: Don't use EXECUTABLE_SYMBOLS for shared
> 	libraries.  PROVIDE _edata, edata, __bss_start, and _end in shared
> 	libraries.
> 	* testsuite/ld-elf/pr23161.map,
> 	* testsuite/ld-elf/pr23161.rd,
> 	* testsuite/ld-elf/pr23161a.c,
> 	* testsuite/ld-elf/pr23161b.c: New files.
> 	* testsuite/ld-elf/shared.exp: Run ld/23161 tests.
> 	* testsuite/ld-elf/pr23162.rd,

Here is a different approach for x86, which includes more testcases
for PR ld/23161.  Do they pass with your patch?


H.J.
---
_edata, __bss_start, and _end are defined by linker script.  FreeBSD's
libc.so uses executable's _end to initialize curbrk.  Glibc's ld.so
references _end as hidden symbol.  But there is no good reason to export
unreferenced _edata, __bss_start, and _end defined in shared libraries.
We should hide unreferenced _edata, __bss_start, and _end in shared
libraries.

bfd/

	PR ld/23161
	* elfxx-x86.c (elf_x86_hide_linker_defined): New function.
	(_bfd_x86_elf_link_check_relocs): Use it to hide unrefernced
	__bss_start, _end and _edata in shared libraries.

ld/

	PR ld/23161
	* testsuite/ld-elf/pr23161.map: New file.
	* testsuite/ld-elf/pr23161a.c: Likewise.
	* testsuite/ld-elf/pr23161a.rd: Likewise.
	* testsuite/ld-elf/pr23161b.c: Likewise.
	* testsuite/ld-elf/pr23161b.rd: Likewise.
	* testsuite/ld-elf/pr23161c.c: Likewise.
	* testsuite/ld-elf/pr23161c.rd: Likewise.
	* testsuite/ld-elf/pr23161d.rd: Likewise.
	* testsuite/ld-elf/pr23162.rd: Remove  _edata, __bss_start, and
	_end.
	* testsuite/ld-elf/shared.exp: Run ld/23161 tests.
---
 bfd/elfxx-x86.c                 | 29 ++++++++++++++++
 ld/testsuite/ld-elf/pr23161.map |  4 +++
 ld/testsuite/ld-elf/pr23161a.c  |  9 +++++
 ld/testsuite/ld-elf/pr23161a.rd | 19 +++++++++++
 ld/testsuite/ld-elf/pr23161b.c  | 23 +++++++++++++
 ld/testsuite/ld-elf/pr23161b.rd | 14 ++++++++
 ld/testsuite/ld-elf/pr23161c.c  |  9 +++++
 ld/testsuite/ld-elf/pr23161c.rd | 12 +++++++
 ld/testsuite/ld-elf/pr23161d.rd |  8 +++++
 ld/testsuite/ld-elf/pr23162.rd  |  9 +----
 ld/testsuite/ld-elf/shared.exp  | 60 +++++++++++++++++++++++++++++++++
 11 files changed, 188 insertions(+), 8 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr23161.map
 create mode 100644 ld/testsuite/ld-elf/pr23161a.c
 create mode 100644 ld/testsuite/ld-elf/pr23161a.rd
 create mode 100644 ld/testsuite/ld-elf/pr23161b.c
 create mode 100644 ld/testsuite/ld-elf/pr23161b.rd
 create mode 100644 ld/testsuite/ld-elf/pr23161c.c
 create mode 100644 ld/testsuite/ld-elf/pr23161c.rd
 create mode 100644 ld/testsuite/ld-elf/pr23161d.rd

diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 3a7573f7a2..e0298edddf 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -876,6 +876,27 @@ elf_x86_linker_defined (struct bfd_link_info *info, const char *name)
     }
 }
 
+/* Hide a linker-defined symbol, NAME, if it isn't referenced in a
+   relocatable object file.  */
+
+static void
+elf_x86_hide_linker_defined (struct bfd_link_info *info,
+			     const char *name)
+{
+  struct elf_link_hash_entry *h;
+
+  h = elf_link_hash_lookup (elf_hash_table (info), name,
+			    FALSE, FALSE, FALSE);
+  if (h == NULL)
+    return;
+
+  while (h->root.type == bfd_link_hash_indirect)
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+  if (!h->ref_regular)
+    _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
+}
+
 bfd_boolean
 _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
 {
@@ -916,6 +937,14 @@ _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
 	      elf_x86_linker_defined (info, "_end");
 	      elf_x86_linker_defined (info, "_edata");
 	    }
+	  else
+	    {
+	      /* Hide unreferenced __bss_start, _end and _edata in
+	         shared libraries.  */
+	      elf_x86_hide_linker_defined (info, "__bss_start");
+	      elf_x86_hide_linker_defined (info, "_end");
+	      elf_x86_hide_linker_defined (info, "_edata");
+	    }
 	}
     }
 
diff --git a/ld/testsuite/ld-elf/pr23161.map b/ld/testsuite/ld-elf/pr23161.map
new file mode 100644
index 0000000000..cc817dc52a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161.map
@@ -0,0 +1,4 @@
+FOO {
+  global:
+    *;
+};
diff --git a/ld/testsuite/ld-elf/pr23161a.c b/ld/testsuite/ld-elf/pr23161a.c
new file mode 100644
index 0000000000..707ed04bfd
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161a.c
@@ -0,0 +1,9 @@
+extern char *_end;
+extern char *_edata;
+extern char *__bss_start;
+
+int
+foo (void)
+{
+  return _end[0] + _edata[0] + __bss_start[0];
+}
diff --git a/ld/testsuite/ld-elf/pr23161a.rd b/ld/testsuite/ld-elf/pr23161a.rd
new file mode 100644
index 0000000000..1a7e563949
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161a.rd
@@ -0,0 +1,19 @@
+Relocation section '\.rel(a|)\.dyn' at offset 0x[0-9a-f]+ contains [0-9]+ entries:
+ +Offset +Info +Type +Sym.* Value +Sym.* Name( \+ Addend|)
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_GLOB_DAT +[a-f0-9]+ +__bss_start(@@FOO|)( \+ 0|)
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_GLOB_DAT +[a-f0-9]+ +_edata(@@FOO|)( \+ 0|)
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_GLOB_DAT +[a-f0-9]+ +_end(@@FOO|)( \+ 0|)
+#...
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_edata(@@FOO|)
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_end(@@FOO|)
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +__bss_start(@@FOO|)
+#...
diff --git a/ld/testsuite/ld-elf/pr23161b.c b/ld/testsuite/ld-elf/pr23161b.c
new file mode 100644
index 0000000000..0112f771b1
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161b.c
@@ -0,0 +1,23 @@
+static char *_edata_p;
+static char *_end_p;
+static char *__bss_start_p;
+extern char *_end;
+extern char *_edata;
+extern char *__bss_start;
+
+extern int foo (void);
+
+void
+bar (void)
+{
+  _edata_p = (char*) &_edata;
+  _end_p = (char*) &_end;
+  __bss_start_p = (char*) &__bss_start;
+}
+
+void
+_start ()
+{
+  bar ();
+  foo ();
+}
diff --git a/ld/testsuite/ld-elf/pr23161b.rd b/ld/testsuite/ld-elf/pr23161b.rd
new file mode 100644
index 0000000000..c8529a515f
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161b.rd
@@ -0,0 +1,14 @@
+Relocation section '\.rel(a|)\.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Sym.* Value +Sym.* Name( \+ Addend|)
+[a-f0-9]+ +[0-9a-f]+ +R_.*_JUMP_SLOT +[a-f0-9]+ +foo(@FOO|)( \+ 0|)
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_edata
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_end
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +__bss_start
+#...
diff --git a/ld/testsuite/ld-elf/pr23161c.c b/ld/testsuite/ld-elf/pr23161c.c
new file mode 100644
index 0000000000..db5ec4a334
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161c.c
@@ -0,0 +1,9 @@
+extern char *_end __attribute__ ((visibility("hidden")));
+extern char *_edata __attribute__ ((visibility("hidden")));
+extern char *__bss_start __attribute__ ((visibility("hidden")));
+
+int
+foo (void)
+{
+  return _end[0] + _edata[0] + __bss_start[0];
+}
diff --git a/ld/testsuite/ld-elf/pr23161c.rd b/ld/testsuite/ld-elf/pr23161c.rd
new file mode 100644
index 0000000000..904f126690
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161c.rd
@@ -0,0 +1,12 @@
+There are no relocations in this file.
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +__bss_start
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +_edata
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +LOCAL +DEFAULT +[0-9]+ +_end
+#...
diff --git a/ld/testsuite/ld-elf/pr23161d.rd b/ld/testsuite/ld-elf/pr23161d.rd
new file mode 100644
index 0000000000..338cfad336
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23161d.rd
@@ -0,0 +1,8 @@
+Relocation section '\.rel(a|)\.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Sym.* Value +Sym.* Name( \+ Addend|)
+[a-f0-9]+ +[0-9a-f]+ +R_.*_JUMP_SLOT +[a-f0-9]+ +foo( \+ 0|)
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+ +[0-9]+: +[a-f0-9]+ +0 +FUNC +GLOBAL +DEFAULT +UND +foo
diff --git a/ld/testsuite/ld-elf/pr23162.rd b/ld/testsuite/ld-elf/pr23162.rd
index 3ac848fe05..48351ffea7 100644
--- a/ld/testsuite/ld-elf/pr23162.rd
+++ b/ld/testsuite/ld-elf/pr23162.rd
@@ -1,12 +1,5 @@
 There are no relocations in this file\.
 
-Symbol table '\.dynsym' contains [0-9]+ entries:
+Symbol table '\.dynsym' contains 1 entry:
  +Num: +Value +Size Type +Bind +Vis +Ndx Name
  +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
-#...
- +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_edata
-#...
- +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_end
-#...
- +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +__bss_start
-#...
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index ef517bac42..f357b867c3 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -1393,5 +1393,65 @@ if { ([istarget "i?86-*-*"]
 	    "pr23162b" \
 	    "-fPIC -O0" \
 	] \
+	[list \
+	    "Build libpr23161a.so" \
+	    "-shared" \
+	    "" \
+	    "$AFLAGS_PIC" \
+	    { pr23161a.c } \
+	    {{readelf {--dyn-syms -rW} pr23161a.rd}} \
+	    "libpr23161a.so" \
+	    "-fPIC -O2" \
+	] \
+	[list \
+	    "Build pr23161a" \
+	    "-pie --no-as-needed tmpdir/libpr23161a.so" \
+	    "" \
+	    "-mrelax-relocations=yes" \
+	    { pr23161b.c } \
+	    {{readelf {--dyn-syms -rW} pr23161b.rd}} \
+	    "pr23161a" \
+	    "-fPIC -O0" \
+	] \
+	[list \
+	    "Build libpr23161b.so" \
+	    "-shared --version-script=pr23161.map" \
+	    "" \
+	    "$AFLAGS_PIC" \
+	    { pr23161a.c } \
+	    {{readelf {--dyn-syms -rW} pr23161a.rd}} \
+	    "libpr23161b.so" \
+	    "-fPIC -O2" \
+	] \
+	[list \
+	    "Build pr23161b" \
+	    "-pie --no-as-needed tmpdir/libpr23161b.so" \
+	    "" \
+	    "-mrelax-relocations=yes" \
+	    { pr23161b.c } \
+	    {{readelf {--dyn-syms -rW} pr23161b.rd}} \
+	    "pr23161b" \
+	    "-fPIC -O0" \
+	] \
+	[list \
+	    "Build libpr23161c.so" \
+	    "-shared" \
+	    "" \
+	    "$AFLAGS_PIC" \
+	    { pr23161c.c } \
+	    {{readelf {--dyn-syms -rW} pr23161c.rd}} \
+	    "libpr23161c.so" \
+	    "-fPIC -O2" \
+	] \
+	[list \
+	    "Build pr23161c" \
+	    "-pie --no-as-needed tmpdir/libpr23161c.so" \
+	    "" \
+	    "-mrelax-relocations=yes" \
+	    { pr23161b.c } \
+	    {{readelf {--dyn-syms -rW} pr23161d.rd}} \
+	    "pr23161c" \
+	    "-fPIC -O0" \
+	] \
     ]
 }
-- 
2.17.1



More information about the Binutils mailing list