aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-05-14 03:47:47 -0700
committerH.J. Lu <hjl.tools@gmail.com>2018-05-14 03:48:02 -0700
commit9bc935ef3380a2d471b9447e2bf8e61297654e2f (patch)
tree7a3dcd50c0392966eceef1ab218a8650d071d603 /bfd
parentAutomatic date update in version.in (diff)
downloadbinutils-gdb-9bc935ef3380a2d471b9447e2bf8e61297654e2f.tar.gz
binutils-gdb-9bc935ef3380a2d471b9447e2bf8e61297654e2f.tar.bz2
binutils-gdb-9bc935ef3380a2d471b9447e2bf8e61297654e2f.zip
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elfxx-x86.c45
2 files changed, 42 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d8b3773e396..10b96794b25 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 40157b8ed76..6c1f4c32fcf 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");
}
}
}