aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elflink.c68
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/testsuite/ld-plugin/lto.exp9
-rw-r--r--ld/testsuite/ld-plugin/pr22502a.c16
-rw-r--r--ld/testsuite/ld-plugin/pr22502b.c3
6 files changed, 109 insertions, 3 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3903b1d..abd7c96 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2017-11-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/22502
+ * elflink.c (_bfd_elf_merge_symbol): Also skip definition from
+ an IR object.
+ (elf_link_add_object_symbols): If linker plugin is enabled, set
+ non_ir_ref_regular on symbols referenced in regular objects so
+ that linker plugin will get the correct symbol resolution.
+
2017-11-27 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR ld/22263
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 99f867d..ddd088c 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -1555,10 +1555,13 @@ _bfd_elf_merge_symbol (bfd *abfd,
sec = *psec;
}
- /* There are multiple definitions of a normal symbol.
- Skip the default symbol as well. */
+ /* There are multiple definitions of a normal symbol. Skip the
+ default symbol as well as definition from an IR object. */
if (olddef && !olddyn && !oldweak && newdef && !newdyn && !newweak
- && !default_sym && h->def_regular)
+ && !default_sym && h->def_regular
+ && !(oldbfd != NULL
+ && (oldbfd->flags & BFD_PLUGIN) != 0
+ && (abfd->flags & BFD_PLUGIN) == 0))
{
/* Handle a multiple definition. */
(*info->callbacks->multiple_definition) (info, &h->root,
@@ -4931,6 +4934,65 @@ error_free_dyn:
}
}
+ if (info->lto_plugin_active
+ && !bfd_link_relocatable (info)
+ && (abfd->flags & BFD_PLUGIN) == 0
+ && !just_syms
+ && extsymcount)
+ {
+ int r_sym_shift;
+
+ if (bed->s->arch_size == 32)
+ r_sym_shift = 8;
+ else
+ r_sym_shift = 32;
+
+ /* If linker plugin is enabled, set non_ir_ref_regular on symbols
+ referenced in regular objects so that linker plugin will get
+ the correct symbol resolution. */
+
+ sym_hash = elf_sym_hashes (abfd);
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *rel, *relend;
+
+ /* Don't check relocations in excluded sections. */
+ if ((s->flags & SEC_RELOC) == 0
+ || s->reloc_count == 0
+ || (s->flags & SEC_EXCLUDE) != 0
+ || ((info->strip == strip_all
+ || info->strip == strip_debugger)
+ && (s->flags & SEC_DEBUGGING) != 0))
+ continue;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, s, NULL,
+ NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_free_vers;
+
+ rel = internal_relocs;
+ relend = rel + s->reloc_count;
+ for ( ; rel < relend; rel++)
+ {
+ unsigned long r_symndx = rel->r_info >> r_sym_shift;
+ struct elf_link_hash_entry *h;
+
+ /* Skip local symbols. */
+ if (r_symndx < extsymoff)
+ continue;
+
+ h = sym_hash[r_symndx - extsymoff];
+ if (h != NULL)
+ h->root.non_ir_ref_regular = 1;
+ }
+
+ if (elf_section_data (s)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+ }
+
if (extversym != NULL)
{
free (extversym);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 9c10c7e..ed63236 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/22502
+ * testsuite/ld-plugin/lto.exp: Run PR ld/22502 test.
+ * testsuite/ld-plugin/pr22502a.c: New file.
+ * testsuite/ld-plugin/pr22502b.c: Likewise.
+
2017-11-24 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-elf/pr21562c.t: Also provide ___start_scnfoo and
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index d34479f..56c852d 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -208,6 +208,12 @@ set lto_link_tests [list \
"-flto -Wl,-plugin,$plug_so" "-flto" \
{pr20321.c} {{warning ".*: duplicated plugin"}} \
"pr20321" "c"] \
+ [list "Build pr22502a.o" \
+ "" "" \
+ {pr22502a.c}] \
+ [list "Build pr22502b.o" \
+ "$plug_opt" "-flto $lto_no_fat" \
+ {pr22502b.c}] \
]
if { [at_least_gcc_version 4 7] } {
@@ -391,6 +397,9 @@ set lto_run_tests [list \
[list "Run pr20267b" \
"-O2 -flto tmpdir/pr20267a.o tmpdir/libpr20267b.a" "" \
{dummy.c} "pr20267b" "pass.out" "-flto -O2" "c"] \
+ [list "Run pr22502" \
+ "-O2 -flto tmpdir/pr22502a.o tmpdir/pr22502b.o" "" \
+ {dummy.c} "pr20267" "pass.out" "-flto -O2" "c"] \
]
if { [at_least_gcc_version 4 7] } {
diff --git a/ld/testsuite/ld-plugin/pr22502a.c b/ld/testsuite/ld-plugin/pr22502a.c
new file mode 100644
index 0000000..0eaa1af
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr22502a.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+volatile int x;
+extern void abort ();
+
+__attribute__((weak))
+void foobar (void) { x++; }
+
+int main (void)
+{
+ foobar ();
+ if (x != -1)
+ abort ();
+ printf ("PASS\n");
+ return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr22502b.c b/ld/testsuite/ld-plugin/pr22502b.c
new file mode 100644
index 0000000..87389b9
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr22502b.c
@@ -0,0 +1,3 @@
+extern volatile int x;
+
+void foobar (void) { x--; }