From: H.J. Lu Date: Tue, 28 Nov 2017 11:48:25 +0000 (-0800) Subject: ld: Set non_ir_ref_regular on symbols referenced in regular objects X-Git-Tag: users/ARM/embedded-binutils-master-2017q4~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a83ef4d139c377e0e87d105977d85c6ef9fbb162;p=external%2Fbinutils.git ld: Set non_ir_ref_regular on symbols referenced in regular objects 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. bfd/ 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. ld/ 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. --- 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 + + 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 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 + + 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 * 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 + +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--; }