ld: Properly override the IR definition
We change the previous definition in the IR object to undefweak only after all LTO symbols have been read. include/ PR ld/26262 PR ld/26267 * bfdlink.h (bfd_link_info): Add lto_all_symbols_read. ld/ PR ld/26262 PR ld/26267 * ldlang.c (lang_process): Set lto_all_symbols_read after all LTO IR symbols have been read. * plugin.c (plugin_notice): Override the IR definition only if all LTO IR symbols have been read or the new definition is non-weak and the the IR definition is weak * testsuite/ld-plugin/lto.exp: Run PR ld/26262 and ld/26267 tests. * testsuite/ld-plugin/pr26262a.c: New file. * testsuite/ld-plugin/pr26262b.c: Likewise. * testsuite/ld-plugin/pr26262c.c: Likewise. * testsuite/ld-plugin/pr26267.err: Likewise. * testsuite/ld-plugin/pr26267a.c: Likewise. * testsuite/ld-plugin/pr26267b.c: Likewise. * testsuite/ld-plugin/pr26267c.c: Likewise. (cherry picked from commit 0e6a3f07f50723d1831291492b96fdf74bcbdc11)
This commit is contained in:
parent
544fb88902
commit
041d1c2d4f
|
@ -1,3 +1,9 @@
|
|||
2020-07-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/26262
|
||||
PR ld/26267
|
||||
* bfdlink.h (bfd_link_info): Add lto_all_symbols_read.
|
||||
|
||||
2020-07-04 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
Binutils 2.35 branch created.
|
||||
|
|
|
@ -361,6 +361,9 @@ struct bfd_link_info
|
|||
/* TRUE if the LTO plugin is active. */
|
||||
unsigned int lto_plugin_active: 1;
|
||||
|
||||
/* TRUE if all LTO IR symbols have been read. */
|
||||
unsigned int lto_all_symbols_read : 1;
|
||||
|
||||
/* TRUE if global symbols in discarded sections should be stripped. */
|
||||
unsigned int strip_discarded: 1;
|
||||
|
||||
|
|
19
ld/ChangeLog
19
ld/ChangeLog
|
@ -1,3 +1,22 @@
|
|||
2020-07-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/26262
|
||||
PR ld/26267
|
||||
* ldlang.c (lang_process): Set lto_all_symbols_read after all
|
||||
LTO IR symbols have been read.
|
||||
* plugin.c (plugin_notice): Override the IR definition only if
|
||||
all LTO IR symbols have been read or the new definition is
|
||||
non-weak and the the IR definition is weak
|
||||
* testsuite/ld-plugin/lto.exp: Run PR ld/26262 and ld/26267
|
||||
tests.
|
||||
* testsuite/ld-plugin/pr26262a.c: New file.
|
||||
* testsuite/ld-plugin/pr26262b.c: Likewise.
|
||||
* testsuite/ld-plugin/pr26262c.c: Likewise.
|
||||
* testsuite/ld-plugin/pr26267.err: Likewise.
|
||||
* testsuite/ld-plugin/pr26267a.c: Likewise.
|
||||
* testsuite/ld-plugin/pr26267b.c: Likewise.
|
||||
* testsuite/ld-plugin/pr26267c.c: Likewise.
|
||||
|
||||
2020-07-20 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* testsuite/ld-powerpc/powerpc.exp (ppcelftests): Use section name
|
||||
|
|
|
@ -7874,6 +7874,7 @@ lang_process (void)
|
|||
if (plugin_call_all_symbols_read ())
|
||||
einfo (_("%F%P: %s: plugin reported error after all symbols read\n"),
|
||||
plugin_error_plugin ());
|
||||
link_info.lto_all_symbols_read = TRUE;
|
||||
/* Open any newly added files, updating the file chains. */
|
||||
plugin_undefs = link_info.hash->undefs_tail;
|
||||
open_input_bfds (*added.tail, OPEN_BFD_NORMAL);
|
||||
|
|
16
ld/plugin.c
16
ld/plugin.c
|
@ -1433,12 +1433,16 @@ plugin_notice (struct bfd_link_info *info,
|
|||
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)))
|
||||
this by making the symbol appear to be undefined.
|
||||
|
||||
NB: We change the previous definition in the IR object to
|
||||
undefweak only after all LTO symbols have been read. */
|
||||
else if (info->lto_all_symbols_read
|
||||
&& (((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;
|
||||
|
|
|
@ -210,6 +210,36 @@ set lto_link_tests [list \
|
|||
[list "Build pr26163a.o" \
|
||||
"" "-O2 -fno-lto" \
|
||||
{pr26163a.c}] \
|
||||
[list "Build pr26262b.o" \
|
||||
"" "-O2" \
|
||||
{pr26262b.c} {} "" "c"] \
|
||||
[list "Build pr26262c.o" \
|
||||
"" "-O2" \
|
||||
{pr26262c.c} {} "" "c"] \
|
||||
[list "Build pr26267a.o" \
|
||||
"" "-O2 -flto $lto_no_fat" \
|
||||
{pr26267a.c} {} "" "c"] \
|
||||
[list "Build pr26267b.o" \
|
||||
"" "-O2" \
|
||||
{pr26267b.c} {} "" "c"] \
|
||||
[list "Build pr26267c.o" \
|
||||
"" "-O2" \
|
||||
{pr26267c.c} {} "" "c"] \
|
||||
[list "Build pr26267a" \
|
||||
"" "-O2" \
|
||||
{pr26267a.c} {} "" "c"] \
|
||||
[list "Build pr26267a" \
|
||||
"-flto tmpdir/pr26267a.o tmpdir/pr26267b.o tmpdir/pr26267c.o" \
|
||||
"-flto $lto_no_fat" \
|
||||
{dummy.c} \
|
||||
{{error_output "pr26267.err"}} \
|
||||
"pr26267a"] \
|
||||
[list "Build pr26267b" \
|
||||
"-flto tmpdir/pr26267b.o tmpdir/pr26267c.o tmpdir/pr26267a.o" \
|
||||
"-flto $lto_no_fat" \
|
||||
{dummy.c} \
|
||||
{{error_output "pr26267.err"}} \
|
||||
"pr26267b"] \
|
||||
]
|
||||
|
||||
if { [at_least_gcc_version 10 0] } {
|
||||
|
@ -510,6 +540,16 @@ set lto_run_tests [list \
|
|||
{pr26163b.c} "pr24406-2" "pass.out" \
|
||||
"-flto -O2" "c" "" \
|
||||
"tmpdir/pr26163a.o -Wl,--defsym,g=real_g"] \
|
||||
[list "Run pr26262a" \
|
||||
"-O2 -flto" "" \
|
||||
{pr26262a.c} "pr26262a" "pass.out" \
|
||||
"-flto -O2" "c" "" \
|
||||
"tmpdir/pr26262b.o tmpdir/pr26262c.o"] \
|
||||
[list "Run pr26262b" \
|
||||
"-flto -O2 tmpdir/pr26262b.o tmpdir/pr26262c.o" "" \
|
||||
{pr26262a.c} "pr26262b" "pass.out" \
|
||||
"-flto -O2" "c" "" \
|
||||
""] \
|
||||
]
|
||||
|
||||
if { [at_least_gcc_version 4 7] } {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int counter;
|
||||
extern void foo (void);
|
||||
extern void xxx (void);
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
bar ();
|
||||
foo ();
|
||||
xxx ();
|
||||
if (counter == 1)
|
||||
printf ("PASS\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
extern int counter;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
abort ();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
extern void bar (void);
|
||||
void
|
||||
xxx (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#...
|
||||
.*: multiple definition of `bar'; .*
|
||||
#...
|
|
@ -0,0 +1,21 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int counter;
|
||||
extern void foo (void);
|
||||
extern void xxx (void);
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
bar ();
|
||||
foo ();
|
||||
xxx ();
|
||||
if (counter == 1)
|
||||
printf ("PASS\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
extern int counter;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
abort ();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
extern void bar (void);
|
||||
void
|
||||
xxx (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
Loading…
Reference in New Issue