x86: Mark __bss_start, _end and _edata locally defined

Message ID 20180511023732.32604-1-hjl.tools@gmail.com
State New
Headers show
Series
  • x86: Mark __bss_start, _end and _edata locally defined
Related show

Commit Message

H.J. Lu May 11, 2018, 2:37 a.m.
__bss_start, _end and _edata are defined by linker to mark regions
within executables and shared libraries.  All references within
executables should be locally resolved.

This patch doesn't change how their references within shared librarie
are resolved.

bfd/

	PR ld/23162
	* elfxx-x86.c (elf_x86_linker_defined): New function.
	(_bfd_x86_elf_link_check_relocs): Use it to mark __bss_start,
	_end and _edata locally defined within executables.

ld/

	PR ld/23162
	* testsuite/ld-elf/pr23162.map: New file.
	* testsuite/ld-elf/pr23162.rd: Likewise.
	* testsuite/ld-elf/pr23162a.c: Likewise.
	* testsuite/ld-elf/pr23162b.c: Likewise.
	* testsuite/ld-elf/shared.exp: Run PR ld/23162 tests.
---
 bfd/elfxx-x86.c                 | 45 +++++++++++++++++++++++++-------
 ld/testsuite/ld-elf/pr23162.map |  4 +++
 ld/testsuite/ld-elf/pr23162.rd  | 12 +++++++++
 ld/testsuite/ld-elf/pr23162a.c  |  4 +++
 ld/testsuite/ld-elf/pr23162b.c  | 20 ++++++++++++++
 ld/testsuite/ld-elf/shared.exp  | 46 +++++++++++++++++++++++++++++++++
 6 files changed, 121 insertions(+), 10 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr23162.map
 create mode 100644 ld/testsuite/ld-elf/pr23162.rd
 create mode 100644 ld/testsuite/ld-elf/pr23162a.c
 create mode 100644 ld/testsuite/ld-elf/pr23162b.c

-- 
2.17.0

Comments

H.J. Lu May 14, 2018, 10:51 a.m. | #1
On Thu, May 10, 2018 at 7:37 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> __bss_start, _end and _edata are defined by linker to mark regions

> within executables and shared libraries.  All references within

> executables should be locally resolved.

>

> This patch doesn't change how their references within shared librarie

> are resolved.

>

> bfd/

>

>         PR ld/23162

>         * elfxx-x86.c (elf_x86_linker_defined): New function.

>         (_bfd_x86_elf_link_check_relocs): Use it to mark __bss_start,

>         _end and _edata locally defined within executables.

>

> ld/

>

>         PR ld/23162

>         * testsuite/ld-elf/pr23162.map: New file.

>         * testsuite/ld-elf/pr23162.rd: Likewise.

>         * testsuite/ld-elf/pr23162a.c: Likewise.

>         * testsuite/ld-elf/pr23162b.c: Likewise.

>         * testsuite/ld-elf/shared.exp: Run PR ld/23162 tests.


This is what I checked in.


-- 
H.J.
From c0b68558bd4fa13e1bdc183e2c67bb21cfd9aaf0 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 10 May 2018 19:05:34 -0700
Subject: [PATCH] x86: Mark __bss_start, _end and _edata locally defined

__bss_start, _end and _edata are defined by linker to mark regions
within executables and shared libraries.  All references within
executables should be locally resolved.

This patch doesn't change how their references within shared libraries
are resolved.

bfd/

	PR ld/23162
	* elfxx-x86.c (elf_x86_linker_defined): New function.
	(_bfd_x86_elf_link_check_relocs): Use it to mark __bss_start,
	_end and _edata locally defined within executables.

ld/

	PR ld/23162
	* testsuite/ld-elf/pr23162.map: New file.
	* testsuite/ld-elf/pr23162.rd: Likewise.
	* testsuite/ld-elf/pr23162a.c: Likewise.
	* testsuite/ld-elf/pr23162b.c: Likewise.
	* testsuite/ld-elf/shared.exp: Run PR ld/23162 tests.
---
 bfd/elfxx-x86.c                 | 45 +++++++++++++++++++++++++-------
 ld/testsuite/ld-elf/pr23162.map |  4 +++
 ld/testsuite/ld-elf/pr23162.rd  | 12 +++++++++
 ld/testsuite/ld-elf/pr23162a.c  |  4 +++
 ld/testsuite/ld-elf/pr23162b.c  | 20 ++++++++++++++
 ld/testsuite/ld-elf/shared.exp  | 46 +++++++++++++++++++++++++++++++++
 6 files changed, 121 insertions(+), 10 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr23162.map
 create mode 100644 ld/testsuite/ld-elf/pr23162.rd
 create mode 100644 ld/testsuite/ld-elf/pr23162a.c
 create mode 100644 ld/testsuite/ld-elf/pr23162b.c

diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 40157b8ed7..6c1f4c32fc 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -849,6 +849,33 @@ _bfd_x86_elf_compare_relocs (const void *ap, const void *bp)
     return 0;
 }
 
+/* Mark symbol, NAME, as locally defined by linker if it is referenced
+   and not defined in a relocatable object file.  */
+
+static void
+elf_x86_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->root.type == bfd_link_hash_new
+      || h->root.type == bfd_link_hash_undefined
+      || h->root.type == bfd_link_hash_undefweak
+      || h->root.type == bfd_link_hash_common
+      || (!h->def_regular && h->def_dynamic))
+    {
+      elf_x86_hash_entry (h)->local_ref = 2;
+      elf_x86_hash_entry (h)->linker_def = 1;
+    }
+}
+
 bfd_boolean
 _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
 {
@@ -879,17 +906,15 @@ _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
 
 	  /* "__ehdr_start" will be defined by linker as a hidden symbol
 	     later if it is referenced and not defined.  */
-	  h = elf_link_hash_lookup (elf_hash_table (info),
-				    "__ehdr_start",
-				    FALSE, FALSE, FALSE);
-	  if (h != NULL
-	      && (h->root.type == bfd_link_hash_new
-		  || h->root.type == bfd_link_hash_undefined
-		  || h->root.type == bfd_link_hash_undefweak
-		  || h->root.type == bfd_link_hash_common))
+	  elf_x86_linker_defined (info, "__ehdr_start");
+
+	  if (bfd_link_executable (info))
 	    {
-	      elf_x86_hash_entry (h)->local_ref = 2;
-	      elf_x86_hash_entry (h)->linker_def = 1;
+	      /* References to __bss_start, _end and _edata should be
+		 locally resolved within executables.  */
+	      elf_x86_linker_defined (info, "__bss_start");
+	      elf_x86_linker_defined (info, "_end");
+	      elf_x86_linker_defined (info, "_edata");
 	    }
 	}
     }
diff --git a/ld/testsuite/ld-elf/pr23162.map b/ld/testsuite/ld-elf/pr23162.map
new file mode 100644
index 0000000000..cc817dc52a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162.map
@@ -0,0 +1,4 @@
+FOO {
+  global:
+    *;
+};
diff --git a/ld/testsuite/ld-elf/pr23162.rd b/ld/testsuite/ld-elf/pr23162.rd
new file mode 100644
index 0000000000..3ac848fe05
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162.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 +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/pr23162a.c b/ld/testsuite/ld-elf/pr23162a.c
new file mode 100644
index 0000000000..cd0130cacd
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162a.c
@@ -0,0 +1,4 @@
+void
+foo (void)
+{
+}
diff --git a/ld/testsuite/ld-elf/pr23162b.c b/ld/testsuite/ld-elf/pr23162b.c
new file mode 100644
index 0000000000..8476120d40
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162b.c
@@ -0,0 +1,20 @@
+static char *_edata_p;
+static char *_end_p;
+static char *__bss_start_p;
+extern char *_end;
+extern char *_edata;
+extern char *__bss_start;
+
+void
+bar (void)
+{
+  _edata_p = (char*) &_edata;
+  _end_p = (char*) &_end;
+  __bss_start_p = (char*) &__bss_start;
+}
+
+void
+_start ()
+{
+  bar ();
+}
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index eb54eb9239..ef517bac42 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -1349,3 +1349,49 @@ proc mix_pic_and_non_pic {xfails cflags ldflags exe} {
 
 mix_pic_and_non_pic [list "arm*-*-*" "aarch64*-*-*"] "" "" "pr19719"
 mix_pic_and_non_pic [] "-fPIE" "-pie" "pr19719pie"
+
+if { ([istarget "i?86-*-*"]
+      || [istarget "x86_64-*-*"]) } {
+    run_ld_link_tests [list \
+	[list \
+	    "Build libpr23162a.so" \
+	    "-shared" \
+	    "" \
+	    "$AFLAGS_PIC" \
+	    { pr23162a.c } \
+	    "" \
+	    "libpr23162a.so" \
+	    "-fPIC -O2" \
+	] \
+	[list \
+	    "Build pr23162a" \
+	    "-pie --no-as-needed tmpdir/libpr23162a.so" \
+	    "" \
+	    "-mrelax-relocations=yes" \
+	    { pr23162b.c } \
+	    {{readelf {--dyn-syms -rW} pr23162.rd}} \
+	    "pr23162a" \
+	    "-fPIC -O0" \
+	] \
+	[list \
+	    "Build libpr23162b.so" \
+	    "-shared --version-script=pr23162.map" \
+	    "" \
+	    "$AFLAGS_PIC" \
+	    { pr23162a.c } \
+	    "" \
+	    "libpr23162b.so" \
+	    "-fPIC -O2" \
+	] \
+	[list \
+	    "Build pr23162b" \
+	    "-pie --no-as-needed tmpdir/libpr23162b.so" \
+	    "" \
+	    "-mrelax-relocations=yes" \
+	    { pr23162b.c } \
+	    {{readelf {--dyn-syms -rW} pr23162.rd}} \
+	    "pr23162b" \
+	    "-fPIC -O0" \
+	] \
+    ]
+}

Patch

diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 40157b8ed7..6c1f4c32fc 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -849,6 +849,33 @@  _bfd_x86_elf_compare_relocs (const void *ap, const void *bp)
     return 0;
 }
 
+/* Mark symbol, NAME, as locally defined by linker if it is referenced
+   and not defined in a relocatable object file.  */
+
+static void
+elf_x86_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->root.type == bfd_link_hash_new
+      || h->root.type == bfd_link_hash_undefined
+      || h->root.type == bfd_link_hash_undefweak
+      || h->root.type == bfd_link_hash_common
+      || (!h->def_regular && h->def_dynamic))
+    {
+      elf_x86_hash_entry (h)->local_ref = 2;
+      elf_x86_hash_entry (h)->linker_def = 1;
+    }
+}
+
 bfd_boolean
 _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
 {
@@ -879,17 +906,15 @@  _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
 
 	  /* "__ehdr_start" will be defined by linker as a hidden symbol
 	     later if it is referenced and not defined.  */
-	  h = elf_link_hash_lookup (elf_hash_table (info),
-				    "__ehdr_start",
-				    FALSE, FALSE, FALSE);
-	  if (h != NULL
-	      && (h->root.type == bfd_link_hash_new
-		  || h->root.type == bfd_link_hash_undefined
-		  || h->root.type == bfd_link_hash_undefweak
-		  || h->root.type == bfd_link_hash_common))
+	  elf_x86_linker_defined (info, "__ehdr_start");
+
+	  if (bfd_link_executable (info))
 	    {
-	      elf_x86_hash_entry (h)->local_ref = 2;
-	      elf_x86_hash_entry (h)->linker_def = 1;
+	      /* References to __bss_start, _end and _edata should be
+		 locally resolved within executables.  */
+	      elf_x86_linker_defined (info, "__bss_start");
+	      elf_x86_linker_defined (info, "_end");
+	      elf_x86_linker_defined (info, "_edata");
 	    }
 	}
     }
diff --git a/ld/testsuite/ld-elf/pr23162.map b/ld/testsuite/ld-elf/pr23162.map
new file mode 100644
index 0000000000..cc817dc52a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162.map
@@ -0,0 +1,4 @@ 
+FOO {
+  global:
+    *;
+};
diff --git a/ld/testsuite/ld-elf/pr23162.rd b/ld/testsuite/ld-elf/pr23162.rd
new file mode 100644
index 0000000000..3ac848fe05
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162.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 +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/pr23162a.c b/ld/testsuite/ld-elf/pr23162a.c
new file mode 100644
index 0000000000..cd0130cacd
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162a.c
@@ -0,0 +1,4 @@ 
+void
+foo (void)
+{
+}
diff --git a/ld/testsuite/ld-elf/pr23162b.c b/ld/testsuite/ld-elf/pr23162b.c
new file mode 100644
index 0000000000..8476120d40
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr23162b.c
@@ -0,0 +1,20 @@ 
+static char *_edata_p;
+static char *_end_p;
+static char *__bss_start_p;
+extern char *_end;
+extern char *_edata;
+extern char *__bss_start;
+
+void
+bar (void)
+{
+  _edata_p = (char*) &_edata;
+  _end_p = (char*) &_end;
+  __bss_start_p = (char*) &__bss_start;
+}
+
+void
+_start ()
+{
+  bar ();
+}
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index eb54eb9239..a0e6eb8a09 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -1349,3 +1349,49 @@  proc mix_pic_and_non_pic {xfails cflags ldflags exe} {
 
 mix_pic_and_non_pic [list "arm*-*-*" "aarch64*-*-*"] "" "" "pr19719"
 mix_pic_and_non_pic [] "-fPIE" "-pie" "pr19719pie"
+
+if { ([istarget "i?86-*-*"]
+      || [istarget "x86_64-*-*"]) } {
+    run_ld_link_tests [list \
+	[list \
+	    "Build libpr23162a.so" \
+	    "-shared" \
+	    "" \
+	    "$AFLAGS_PIC" \
+	    { pr23162a.c } \
+	    "" \
+	    "libpr23162a.so" \
+	    "-fPIC -O2" \
+	] \
+	[list \
+	    "Build pr23162a" \
+	    "-pie tmpdir/libpr23162a.so" \
+	    "" \
+	    "-mrelax-relocations=yes" \
+	    { pr23162b.c } \
+	    {{readelf {--dyn-syms -rW} pr23162.rd}} \
+	    "pr23162a" \
+	    "-fPIC -O0" \
+	] \
+	[list \
+	    "Build libpr23162b.so" \
+	    "-shared --version-script=pr23162.map" \
+	    "" \
+	    "$AFLAGS_PIC" \
+	    { pr23162a.c } \
+	    "" \
+	    "libpr23162b.so" \
+	    "-fPIC -O2" \
+	] \
+	[list \
+	    "Build pr23162b" \
+	    "-pie tmpdir/libpr23162b.so" \
+	    "" \
+	    "-mrelax-relocations=yes" \
+	    { pr23162b.c } \
+	    {{readelf {--dyn-syms -rW} pr23162.rd}} \
+	    "pr23162b" \
+	    "-fPIC -O0" \
+	] \
+    ]
+}