diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elflink.c | 6 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/bfdlink.h | 4 | ||||
-rw-r--r-- | ld/ChangeLog | 11 | ||||
-rw-r--r-- | ld/plugin.c | 23 | ||||
-rw-r--r-- | ld/testsuite/ld-plugin/lto.exp | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-plugin/pr21382a.c | 17 | ||||
-rw-r--r-- | ld/testsuite/ld-plugin/pr21382b.c | 7 |
9 files changed, 83 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 11fbdab..214d0a8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2017-04-20 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/21382 + * elflink.c (elf_link_add_object_symbols): Preserve + dynamic_ref_after_ir_def when restoring the symbol table for + unneeded dynamic object. + 2017-04-19 H.J. Lu <hongjiu.lu@intel.com> PR ld/21401 diff --git a/bfd/elflink.c b/bfd/elflink.c index 0add01b..972b6f8 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4932,6 +4932,7 @@ error_free_dyn: struct elf_link_hash_entry *h; bfd_size_type size; unsigned int alignment_power; + unsigned int dynamic_ref_after_ir_def; for (p = htab->root.table.table[i]; p != NULL; p = p->next) { @@ -4953,6 +4954,10 @@ error_free_dyn: size = 0; alignment_power = 0; } + /* Preserve dynamic_ref_after_ir_def so that this symbol + will be exported when the dynamic lib becomes needed + in the second pass. */ + dynamic_ref_after_ir_def = h->root.dynamic_ref_after_ir_def; memcpy (p, old_ent, htab->root.table.entsize); old_ent = (char *) old_ent + htab->root.table.entsize; h = (struct elf_link_hash_entry *) p; @@ -4969,6 +4974,7 @@ error_free_dyn: if (alignment_power > h->root.u.c.p->alignment_power) h->root.u.c.p->alignment_power = alignment_power; } + h->root.dynamic_ref_after_ir_def = dynamic_ref_after_ir_def; } } diff --git a/include/ChangeLog b/include/ChangeLog index 90c4c8d..31dc68f 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2017-04-20 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/21382 + * bfdlink.h (bfd_link_hash_entry): Add dynamic_ref_after_ir_def. + 2017-04-19 Alan Modra <amodra@gmail.com> * bfdlink.h (struct bfd_link_info <dynamic_undefined_weak>): diff --git a/include/bfdlink.h b/include/bfdlink.h index 18dea0c..cb4bad9 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -104,6 +104,10 @@ struct bfd_link_hash_entry IR object file. */ unsigned int non_ir_ref : 1; + /* Symbol is referenced in a dynamic object after it has been defined + in an IR object. */ + unsigned int dynamic_ref_after_ir_def : 1; + /* Symbol is a built-in define. These will be overridden by PROVIDE in a linker script. */ unsigned int linker_def : 1; diff --git a/ld/ChangeLog b/ld/ChangeLog index bccd2be..208c119 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2017-04-20 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/21382 + * plugin.c (is_visible_from_outside): Symbol may be visible + from outside if dynamic_ref_after_ir_def is set. + (plugin_notice): Set dynamic_ref_after_ir_def if the symbol is + defined in an IR object and referenced in a dynamic object. + * testsuite/ld-plugin/lto.exp: Run PR ld/21382 tests. + * testsuite/ld-plugin/pr21382a.c: New file. + * testsuite/ld-plugin/pr21382b.c: Likewise. + 2017-04-19 H.J. Lu <hongjiu.lu@intel.com> PR ld/21401 diff --git a/ld/plugin.c b/ld/plugin.c index 03e2e69..164b5db 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -629,7 +629,9 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym, if (bfd_link_relocatable (&link_info)) return TRUE; - if (link_info.export_dynamic || bfd_link_dll (&link_info)) + if (blhe->dynamic_ref_after_ir_def + || link_info.export_dynamic + || bfd_link_dll (&link_info)) { /* Check if symbol is hidden by version script. */ if (bfd_hide_sym_by_version (link_info.version_info, @@ -1316,12 +1318,21 @@ plugin_notice (struct bfd_link_info *info, /* If this is a ref, set non_ir_ref. */ else if (bfd_is_und_section (section)) { + if (h->type == bfd_link_hash_defweak + || h->type == bfd_link_hash_defined) + { + /* Check if the symbol is referenced in a dynamic object + after it has been defined in an IR object. */ + if ((abfd->flags & DYNAMIC) != 0 + && is_ir_dummy_bfd (h->u.def.section->owner)) + h->dynamic_ref_after_ir_def = TRUE; + } /* Replace the undefined dummy bfd with the real one. */ - if ((h->type == bfd_link_hash_undefined - || h->type == bfd_link_hash_undefweak) - && (h->u.undef.abfd == NULL - || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0)) - h->u.undef.abfd = abfd; + else if ((h->type == bfd_link_hash_undefined + || h->type == bfd_link_hash_undefweak) + && (h->u.undef.abfd == NULL + || (h->u.undef.abfd->flags & BFD_PLUGIN) != 0)) + h->u.undef.abfd = abfd; h->non_ir_ref = TRUE; } diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp index 80c084b..f0bc345 100644 --- a/ld/testsuite/ld-plugin/lto.exp +++ b/ld/testsuite/ld-plugin/lto.exp @@ -289,6 +289,12 @@ set lto_link_elf_tests [list \ [list "PR ld/14918" \ "-flto" "-flto" \ {pr14918.c} {{"readelf" {-d --wide} "pr14918.d"}} "pr14918.exe" "c"] \ + [list "Build pr21382a.o" \ + "" "-O2 -flto" \ + {pr21382a.c} {} "" "c"] \ + [list "Build pr21382.so" \ + "-shared" "-O2 -fpic" \ + {pr21382b.c} {} "pr21382.so" "c"] \ ] # Check final symbols in executables. @@ -387,6 +393,9 @@ set lto_run_elf_shared_tests [list \ [list "LTO 7" \ "-O2 -flto -fuse-linker-plugin tmpdir/lto-7b.o tmpdir/lto-7c.o tmpdir/lto-7a.o -Wl,--no-as-needed tmpdir/liblto-7.so" "" \ {dummy.c} "lto-7.exe" "lto-7.out" "" "c"] \ + [list "Run pr21382" \ + "-O2 -flto -fuse-linker-plugin -Wl,--as-needed tmpdir/pr21382a.o tmpdir/pr21382.so" "" \ + {dummy.c} "pr21382.exe" "pass.out" "" "c"] \ ] # LTO run-time tests for ELF diff --git a/ld/testsuite/ld-plugin/pr21382a.c b/ld/testsuite/ld-plugin/pr21382a.c new file mode 100644 index 0000000..09b9d75 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr21382a.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +extern void y (void); + +void +x (void) +{ + printf ("PASS\n"); +} + + +int +main (void) +{ + y (); + return 0; +} diff --git a/ld/testsuite/ld-plugin/pr21382b.c b/ld/testsuite/ld-plugin/pr21382b.c new file mode 100644 index 0000000..c5b74a9 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr21382b.c @@ -0,0 +1,7 @@ +extern void x (void); + +void +y (void) +{ + x (); +} |