x86: Mark __bss_start, _end and _edata locally defined
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 14 May 2018 10:47:47 +0000 (03:47 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 14 May 2018 10:48:02 +0000 (03:48 -0700)
__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/ChangeLog
bfd/elfxx-x86.c
ld/ChangeLog
ld/testsuite/ld-elf/pr23162.map [new file with mode: 0644]
ld/testsuite/ld-elf/pr23162.rd [new file with mode: 0644]
ld/testsuite/ld-elf/pr23162a.c [new file with mode: 0644]
ld/testsuite/ld-elf/pr23162b.c [new file with mode: 0644]
ld/testsuite/ld-elf/shared.exp

index d8b3773e396954b961cd843d5472dccd179f89ea..10b96794b25ca433a3c47f96dce92e43edf72f4d 100644 (file)
@@ -1,3 +1,10 @@
+2018-05-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       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.
+
 2018-05-12  Alan Modra  <amodra@gmail.com>
 
        PR 20659
index 40157b8ed769d98078b4a5966a66f52a89d74d26..6c1f4c32fcffe132fee35bc7021f072c575393be 100644 (file)
@@ -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");
            }
        }
     }
index 336095998d7f75c92c8e5823b4359f4d4eb89eda..178ca68ce8672c342f16ff2c0525e58caf15c13c 100644 (file)
@@ -1,3 +1,12 @@
+2018-05-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       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.
+
 2018-05-12  Alan Modra  <amodra@gmail.com>
 
        PR 20659
diff --git a/ld/testsuite/ld-elf/pr23162.map b/ld/testsuite/ld-elf/pr23162.map
new file mode 100644 (file)
index 0000000..cc817dc
--- /dev/null
@@ -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 (file)
index 0000000..3ac848f
--- /dev/null
@@ -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 (file)
index 0000000..cd0130c
--- /dev/null
@@ -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 (file)
index 0000000..8476120
--- /dev/null
@@ -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 ();
+}
index eb54eb9239a4a1fc464b925cdc05315eaba24ff8..ef517bac42ec227cff61dffc8fd37ff5f41c7a59 100644 (file)
@@ -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" \
+       ] \
+    ]
+}