summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-06-18 14:54:09 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-06-18 18:44:22 -0700
commit6614e881c6420aecbf83dff9e5d2ba3495ea9027 (patch)
tree97ba1e588e32b726d178cf54f96efd86055de9de
parent49f30d83f659591d7d2b14a18dc8308b3fdb8dd5 (diff)
downloadbinutils-gdb-users/hjl/pr20276.tar.gz
Set non_ir_ref on common symbolusers/hjl/pr20276
Linker backend sets non_ir_ref during relocation scan. When relocations are scanned after opening all input files, get_symbols in plugin.c returns the incorrect symbol resulotion since non_ir_ref isn't set on common symbols. plugin_notice should set non_ir_ref on common symbols. Also, we shouldn't check alignment on symbol from plugin dummy input. bfd/ PR ld/20276 * elflink.c (elf_link_add_object_symbols): Don't check alignment on symbol from plugin dummy input. ld/ PR ld/20276 * plugin.c (plugin_notice): Set non_ir_ref on common symbols. * testsuite/ld-plugin/lto.exp (lto_link_tests): Add test for PR ld/20276. (lto_run_tests): Likewise. * testsuite/ld-plugin/pass.out: New file. * testsuite/ld-plugin/pr20276a.c: Likewise. * testsuite/ld-plugin/pr20276b.c: Likewise.
-rw-r--r--bfd/elflink.c3
-rw-r--r--ld/plugin.c98
-rw-r--r--ld/testsuite/ld-plugin/lto.exp12
-rw-r--r--ld/testsuite/ld-plugin/pass.out1
-rw-r--r--ld/testsuite/ld-plugin/pr20276a.c12
-rw-r--r--ld/testsuite/ld-plugin/pr20276b.c1
6 files changed, 80 insertions, 47 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6d591de58da..d4e8db67ea5 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4556,7 +4556,8 @@ error_free_dyn:
symbol_align = ffs (h->root.u.def.value) - 1;
if (h->root.u.def.section->owner != NULL
- && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
+ && (h->root.u.def.section->owner->flags
+ & (DYNAMIC | BFD_PLUGIN)) == 0)
{
normal_align = h->root.u.def.section->alignment_power;
if (normal_align > symbol_align)
diff --git a/ld/plugin.c b/ld/plugin.c
index cb6131841d6..abb685fb22f 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -1286,59 +1286,65 @@ plugin_notice (struct bfd_link_info *info,
h = h->u.i.link;
/* Nothing to do here if this def/ref is from an IR dummy BFD. */
- if (is_ir_dummy_bfd (abfd))
- ;
-
- /* Making an indirect symbol counts as a reference unless this
- is a brand new symbol. */
- else if (bfd_is_ind_section (section)
- || (flags & BSF_INDIRECT) != 0)
+ if (!is_ir_dummy_bfd (abfd))
{
- /* ??? Some of this is questionable. See comments in
- _bfd_generic_link_add_one_symbol for case IND. */
- if (h->type != bfd_link_hash_new)
+ /* Making an indirect symbol counts as a reference unless this
+ is a brand new symbol. */
+ if (bfd_is_ind_section (section)
+ || (flags & BSF_INDIRECT) != 0)
{
- h->non_ir_ref = TRUE;
- inh->non_ir_ref = TRUE;
+ /* ??? Some of this is questionable. See comments in
+ _bfd_generic_link_add_one_symbol for case IND. */
+ if (h->type != bfd_link_hash_new)
+ {
+ h->non_ir_ref = TRUE;
+ inh->non_ir_ref = TRUE;
+ }
+ else if (inh->type == bfd_link_hash_new)
+ inh->non_ir_ref = TRUE;
}
- else if (inh->type == bfd_link_hash_new)
- inh->non_ir_ref = TRUE;
- }
- /* Nothing to do here for warning symbols. */
- else if ((flags & BSF_WARNING) != 0)
- ;
+ /* Nothing to do here for warning symbols. */
+ else if ((flags & BSF_WARNING) != 0)
+ ;
- /* Nothing to do here for constructor symbols. */
- else if ((flags & BSF_CONSTRUCTOR) != 0)
- ;
+ /* Nothing to do here for constructor symbols. */
+ else if ((flags & BSF_CONSTRUCTOR) != 0)
+ ;
- /* If this is a ref, set non_ir_ref. */
- else if (bfd_is_und_section (section))
- {
- /* 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;
- h->non_ir_ref = TRUE;
- }
+ /* If this is a ref, set non_ir_ref. */
+ else if (bfd_is_und_section (section))
+ {
+ /* 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;
+ h->non_ir_ref = TRUE;
+ }
- /* Otherwise, it must be a new def. Ensure any symbol defined
- in an IR dummy BFD takes on a new value from a real BFD.
- Weak symbols are not normally overridden by a new weak
- definition, and strong symbols will normally cause multiple
- definition errors. Avoid this by making the symbol appear
- to be undefined. */
- else if (((h->type == bfd_link_hash_defweak
- || h->type == bfd_link_hash_defined)
- && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
- || (h->type == bfd_link_hash_common
- && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
- {
- h->type = bfd_link_hash_undefweak;
- h->u.undef.abfd = sym_bfd;
+ /* Otherwise, it must be a new def. Ensure any symbol defined
+ in an IR dummy BFD takes on a new value from a real BFD.
+ Weak symbols are not normally overridden by a new weak
+ definition, and strong symbols will normally cause multiple
+ definition errors. Avoid this by making the symbol appear
+ to be undefined. */
+ else if (((h->type == bfd_link_hash_defweak
+ || h->type == bfd_link_hash_defined)
+ && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
+ || (h->type == bfd_link_hash_common
+ && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
+ {
+ h->type = bfd_link_hash_undefweak;
+ h->u.undef.abfd = sym_bfd;
+ }
+
+ /* If this is a common symbol, set non_ir_ref so that we get
+ the corrrect symbol resulotion when it is overridden by IR
+ objects. */
+ if (bfd_is_com_section (section))
+ h->non_ir_ref = TRUE;
}
}
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 7a13abbfdb6..9fa73e19cad 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -183,6 +183,12 @@ set lto_link_tests [list \
[list "PR ld/19317 (1)" \
"$plug_opt" "-flto $lto_no_fat" \
{pr19317.c} {} "libpr19317.a"] \
+ [list "Build pr20276a.o" \
+ "" "-fno-lto" \
+ {pr20276a.c}] \
+ [list "Build pr20276b.o" \
+ "$plug_opt" "-flto $lto_no_fat" \
+ {pr20276b.c}] \
]
if { [at_least_gcc_version 4 7] } {
@@ -332,6 +338,12 @@ set lto_run_tests [list \
[list "PR ld/19317 (3)" \
"-O2 -flto tmpdir/pr19317-r.o" "" \
{dummy.c} "pr19317.exe" "pr19317.out" "-flto -O2" "c"] \
+ [list "PR ld/20267b" \
+ "-O2 -flto tmpdir/pr19317-r.o" "" \
+ {dummy.c} "pr19317.exe" "pr19317.out" "-flto -O2" "c"] \
+ [list "Run pr20276" \
+ "-O2 -flto tmpdir/pr20276a.o tmpdir/pr20267b.o" "" \
+ {dummy.c} "pr20267" "pass.out" "-flto -O2" "c"] \
]
if { [at_least_gcc_version 4 7] } {
diff --git a/ld/testsuite/ld-plugin/pass.out b/ld/testsuite/ld-plugin/pass.out
new file mode 100644
index 00000000000..7ef22e9a431
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pass.out
@@ -0,0 +1 @@
+PASS
diff --git a/ld/testsuite/ld-plugin/pr20276a.c b/ld/testsuite/ld-plugin/pr20276a.c
new file mode 100644
index 00000000000..0b37bc7d309
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr20276a.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int global_var;
+extern void abort ();
+
+int main(void)
+{
+ if (global_var != 20)
+ abort ();
+ printf ("PASS\n");
+ return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr20276b.c b/ld/testsuite/ld-plugin/pr20276b.c
new file mode 100644
index 00000000000..2ecbc2ca908
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr20276b.c
@@ -0,0 +1 @@
+int global_var = 20;