This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] PR ld/20276: Set non_ir_ref on common symbol
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: binutils at sourceware dot org
- Date: Sat, 18 Jun 2016 18:45:13 -0700
- Subject: [PATCH] PR ld/20276: Set non_ir_ref on common symbol
- Authentication-results: sourceware.org; auth=none
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.
OK for master?
H.J.
--
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.
---
bfd/elflink.c | 3 +-
ld/plugin.c | 98 +++++++++++++++++++++------------------
ld/testsuite/ld-plugin/lto.exp | 12 +++++
ld/testsuite/ld-plugin/pass.out | 1 +
ld/testsuite/ld-plugin/pr20276a.c | 12 +++++
ld/testsuite/ld-plugin/pr20276b.c | 1 +
6 files changed, 80 insertions(+), 47 deletions(-)
create mode 100644 ld/testsuite/ld-plugin/pass.out
create mode 100644 ld/testsuite/ld-plugin/pr20276a.c
create mode 100644 ld/testsuite/ld-plugin/pr20276b.c
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6d591de..d4e8db6 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 cb61318..abb685f 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 7a13abb..9fa73e1 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 0000000..7ef22e9
--- /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 0000000..0b37bc7
--- /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 0000000..2ecbc2c
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr20276b.c
@@ -0,0 +1 @@
+int global_var = 20;
--
2.5.5