summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Hsieh <andrewhsieh@google.com>2012-10-31 19:28:10 -0700
committerAndrew Hsieh <andrewhsieh@google.com>2012-10-31 19:28:10 -0700
commit6b95f5ef54a29597409e24d7fe6670238d58ff04 (patch)
treea3f85bcb7e93f3affcadef8ccb41c37be961efd5
parent9a293bee6360288fc2c6dad7fc02e1c326bd8fb9 (diff)
downloadtoolchain_binutils-6b95f5ef54a29597409e24d7fe6670238d58ff04.tar.gz
toolchain_binutils-6b95f5ef54a29597409e24d7fe6670238d58ff04.tar.bz2
toolchain_binutils-6b95f5ef54a29597409e24d7fe6670238d58ff04.zip
Fixed ld --gc-sections bug
Related CL: https://android-review.googlesource.com/#/c/36585/ https://android-review.googlesource.com/#/c/36608/ Change-Id: I73c5b0afdab582824fb853b89464745d4e5b065f
-rw-r--r--binutils-2.22/bfd/elf32-arm.c4
-rw-r--r--binutils-2.22/bfd/elf32-i386.c4
-rw-r--r--binutils-2.22/bfd/elf64-ppc.c4
-rw-r--r--binutils-2.22/bfd/elf64-x86-64.c4
-rw-r--r--binutils-2.22/bfd/elflink.c26
-rw-r--r--binutils-2.22/ld/testsuite/ld-elf/pr13177.d12
-rw-r--r--binutils-2.22/ld/testsuite/ld-elf/pr13177.s9
7 files changed, 53 insertions, 10 deletions
diff --git a/binutils-2.22/bfd/elf32-arm.c b/binutils-2.22/bfd/elf32-arm.c
index b1228d87..46638cb6 100644
--- a/binutils-2.22/bfd/elf32-arm.c
+++ b/binutils-2.22/bfd/elf32-arm.c
@@ -10387,7 +10387,9 @@ elf32_arm_relocate_section (bfd * output_bfd,
not process them. */
if (unresolved_reloc
&& !((input_section->flags & SEC_DEBUGGING) != 0
- && h->def_dynamic))
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
{
(*_bfd_error_handler)
(_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
diff --git a/binutils-2.22/bfd/elf32-i386.c b/binutils-2.22/bfd/elf32-i386.c
index d518d014..7ef1fc1e 100644
--- a/binutils-2.22/bfd/elf32-i386.c
+++ b/binutils-2.22/bfd/elf32-i386.c
@@ -4237,7 +4237,9 @@ elf_i386_relocate_section (bfd *output_bfd,
not process them. */
if (unresolved_reloc
&& !((input_section->flags & SEC_DEBUGGING) != 0
- && h->def_dynamic))
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
{
(*_bfd_error_handler)
(_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
diff --git a/binutils-2.22/bfd/elf64-ppc.c b/binutils-2.22/bfd/elf64-ppc.c
index 93d1314d..351ebc15 100644
--- a/binutils-2.22/bfd/elf64-ppc.c
+++ b/binutils-2.22/bfd/elf64-ppc.c
@@ -13502,7 +13502,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
not process them. */
if (unresolved_reloc
&& !((input_section->flags & SEC_DEBUGGING) != 0
- && h->elf.def_dynamic))
+ && h->elf.def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
{
info->callbacks->einfo
(_("%P: %H: unresolvable %s relocation against symbol `%s'\n"),
diff --git a/binutils-2.22/bfd/elf64-x86-64.c b/binutils-2.22/bfd/elf64-x86-64.c
index 3a2444b9..42ed936a 100644
--- a/binutils-2.22/bfd/elf64-x86-64.c
+++ b/binutils-2.22/bfd/elf64-x86-64.c
@@ -4086,7 +4086,9 @@ elf_x86_64_relocate_section (bfd *output_bfd,
not process them. */
if (unresolved_reloc
&& !((input_section->flags & SEC_DEBUGGING) != 0
- && h->def_dynamic))
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
(*_bfd_error_handler)
(_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
input_bfd,
diff --git a/binutils-2.22/bfd/elflink.c b/binutils-2.22/bfd/elflink.c
index fc4266b3..1c5abd4b 100644
--- a/binutils-2.22/bfd/elflink.c
+++ b/binutils-2.22/bfd/elflink.c
@@ -11577,6 +11577,13 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ h->mark = 1;
+ /* If this symbol is weak and there is a non-weak definition, we
+ keep the non-weak definition because many backends put
+ dynamic reloc info on the non-weak definition for code
+ handling copy relocs. */
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
}
@@ -11724,14 +11731,21 @@ struct elf_gc_sweep_symbol_info
static bfd_boolean
elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
{
- if ((h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && !h->root.u.def.section->gc_mark
- && !(h->root.u.def.section->owner->flags & DYNAMIC))
+ if (!h->mark
+ && (((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && !(h->def_regular
+ && h->root.u.def.section->gc_mark))
+ || h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
{
- struct elf_gc_sweep_symbol_info *inf =
- (struct elf_gc_sweep_symbol_info *) data;
+ struct elf_gc_sweep_symbol_info *inf;
+
+ inf = (struct elf_gc_sweep_symbol_info *) data;
(*inf->hide_symbol) (inf->info, h, TRUE);
+ h->def_regular = 0;
+ h->ref_regular = 0;
+ h->ref_regular_nonweak = 0;
}
return TRUE;
diff --git a/binutils-2.22/ld/testsuite/ld-elf/pr13177.d b/binutils-2.22/ld/testsuite/ld-elf/pr13177.d
new file mode 100644
index 00000000..e56e8652
--- /dev/null
+++ b/binutils-2.22/ld/testsuite/ld-elf/pr13177.d
@@ -0,0 +1,12 @@
+#source: pr13177.s
+#ld: --gc-sections -shared
+#readelf: -s -D --wide
+#target: *-*-linux* *-*-gnu*
+#notarget: arc-*-* d30v-*-* dlx-*-* i960-*-* or32-*-* pj*-*-*
+#notarget: hppa64-*-* i370-*-* i860-*-* ia64-*-* mep-*-* mn10200-*-*
+# generic linker targets don't support --gc-sections, nor do a bunch of others
+
+#failif
+#...
+.*: 0+0 +0 +NOTYPE +GLOBAL +DEFAULT +UND bar
+#...
diff --git a/binutils-2.22/ld/testsuite/ld-elf/pr13177.s b/binutils-2.22/ld/testsuite/ld-elf/pr13177.s
new file mode 100644
index 00000000..d7caad36
--- /dev/null
+++ b/binutils-2.22/ld/testsuite/ld-elf/pr13177.s
@@ -0,0 +1,9 @@
+ .section .text.foo,"ax",%progbits
+ .globl foo
+ .type foo, %function
+foo:
+ .byte 0
+ .section .data.opt_out,"aw",%progbits
+ .type opt_out, %object
+opt_out:
+ .dc.a bar