LTO: Properly handle wrapper symbols in IR
When a wrapper symbol, __wrap_FOO, is defined in IR, its resolution should be LDPR_PREVAILING_DEF, not PREVAILING_DEF_IRONLY, since LTO doesn't know that __wrap_FOO provides definition of FOO. And resolution of FOO should be LDPR_RESOLVED_IR since it is resolved by __wrap_FOO in IR. PR ld/24406 * ld.texi: Remove LTO warning from --wrap. * plugin.c (get_symbols): Update resolution for wrapper and wrapped symbols. * testsuite/ld-plugin/lto.exp: Run ld/24406 tests. * testsuite/ld-plugin/pr24406-1.c: New file. * testsuite/ld-plugin/pr24406-2a.c: Likewise. * testsuite/ld-plugin/pr24406-2b.c: Likewise.
This commit is contained in:
parent
723adb650a
commit
6fe014bcd3
11
ld/ChangeLog
11
ld/ChangeLog
@ -1,3 +1,14 @@
|
||||
2019-04-25 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/24406
|
||||
* ld.texi: Remove LTO warning from --wrap.
|
||||
* plugin.c (get_symbols): Update resolution for wrapper and
|
||||
wrapped symbols.
|
||||
* testsuite/ld-plugin/lto.exp: Run ld/24406 tests.
|
||||
* testsuite/ld-plugin/pr24406-1.c: New file.
|
||||
* testsuite/ld-plugin/pr24406-2a.c: Likewise.
|
||||
* testsuite/ld-plugin/pr24406-2b.c: Likewise.
|
||||
|
||||
2019-04-25 Sudakshina Das <sudi.das@arm.com>
|
||||
|
||||
* testsuite/ld-aarch64/bti-pac-plt-1.d: Update.
|
||||
|
@ -2438,9 +2438,6 @@ g (void)
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
Please keep in mind that with link-time optimization (LTO) enabled, your whole
|
||||
program may be a translation unit.
|
||||
|
||||
@kindex --eh-frame-hdr
|
||||
@kindex --no-eh-frame-hdr
|
||||
@item --eh-frame-hdr
|
||||
|
35
ld/plugin.c
35
ld/plugin.c
@ -741,13 +741,32 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
|
||||
struct bfd_link_hash_entry *blhe;
|
||||
asection *owner_sec;
|
||||
int res;
|
||||
struct bfd_link_hash_entry *h
|
||||
= bfd_link_hash_lookup (link_info.hash, syms[n].name,
|
||||
FALSE, FALSE, TRUE);
|
||||
enum { wrap_none, wrapper, wrapped } wrap_status = wrap_none;
|
||||
|
||||
if (syms[n].def != LDPK_UNDEF)
|
||||
blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
|
||||
FALSE, FALSE, TRUE);
|
||||
if (syms[n].def != LDPK_UNDEF && syms[n].def != LDPK_WEAKUNDEF)
|
||||
{
|
||||
blhe = h;
|
||||
if (blhe)
|
||||
{
|
||||
/* Check if a symbol is a wrapper symbol. */
|
||||
struct bfd_link_hash_entry *unwrap
|
||||
= unwrap_hash_lookup (&link_info, (bfd *) abfd, blhe);
|
||||
if (unwrap && unwrap != h)
|
||||
wrap_status = wrapper;
|
||||
}
|
||||
}
|
||||
else
|
||||
blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
|
||||
syms[n].name, FALSE, FALSE, TRUE);
|
||||
{
|
||||
blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
|
||||
&link_info, syms[n].name,
|
||||
FALSE, FALSE, TRUE);
|
||||
/* Check if a symbol is a wrapped symbol. */
|
||||
if (blhe && blhe != h)
|
||||
wrap_status = wrapped;
|
||||
}
|
||||
if (!blhe)
|
||||
{
|
||||
/* The plugin is called to claim symbols in an archive element
|
||||
@ -833,9 +852,11 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
|
||||
/* We need to know if the sym is referenced from non-IR files. Or
|
||||
even potentially-referenced, perhaps in a future final link if
|
||||
this is a partial one, perhaps dynamically at load-time if the
|
||||
symbol is externally visible. */
|
||||
if (blhe->non_ir_ref_regular)
|
||||
symbol is externally visible. Also check for wrapper symbol. */
|
||||
if (blhe->non_ir_ref_regular || wrap_status == wrapper)
|
||||
res = LDPR_PREVAILING_DEF;
|
||||
else if (wrap_status == wrapped)
|
||||
res = LDPR_RESOLVED_IR;
|
||||
else if (is_visible_from_outside (&syms[n], blhe))
|
||||
res = def_ironly_exp;
|
||||
}
|
||||
|
@ -231,6 +231,9 @@ set lto_link_tests [list \
|
||||
{pr23958.c} \
|
||||
"" \
|
||||
"libpr23958.so"] \
|
||||
[list "Build pr24406-2b.o" \
|
||||
"" "-O2 -fno-lto" \
|
||||
{pr24406-2b.c}] \
|
||||
]
|
||||
|
||||
if { [at_least_gcc_version 4 7] } {
|
||||
@ -434,6 +437,15 @@ set lto_run_tests [list \
|
||||
"-O2 -flto" "" \
|
||||
{dummy.c} "pr22751" "pass.out" "-flto -O2" "c" "" \
|
||||
"-Wl,--whole-archive tmpdir/pr22751.a -Wl,--no-whole-archive"] \
|
||||
[list "Run pr24406-1" \
|
||||
"-O2 -flto" "" \
|
||||
{pr24406-1.c} "pr24406-1" "pass.out" "-flto -O2" "c" "" \
|
||||
"-Wl,--wrap=read"] \
|
||||
[list "Run pr24406-2" \
|
||||
"-O2 -flto" "" \
|
||||
{pr24406-2a.c} "pr24406-2" "pass.out" \
|
||||
"-flto -O2" "c" "" \
|
||||
"tmpdir/pr24406-2b.o -Wl,--wrap=cook"] \
|
||||
]
|
||||
|
||||
if { [at_least_gcc_version 4 7] } {
|
||||
|
17
ld/testsuite/ld-plugin/pr24406-1.c
Normal file
17
ld/testsuite/ld-plugin/pr24406-1.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
ssize_t
|
||||
__wrap_read (int fd, void *buffer, size_t count)
|
||||
{
|
||||
puts ("PASS");
|
||||
return fd + count + sizeof (buffer);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i = read (1, "abc", 5);
|
||||
return i == 0;
|
||||
}
|
17
ld/testsuite/ld-plugin/pr24406-2a.c
Normal file
17
ld/testsuite/ld-plugin/pr24406-2a.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern int cook(void);
|
||||
|
||||
int __wrap_cook(void)
|
||||
{
|
||||
puts ("PASS");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if (cook () == -1)
|
||||
__builtin_abort ();
|
||||
|
||||
return 0;
|
||||
}
|
4
ld/testsuite/ld-plugin/pr24406-2b.c
Normal file
4
ld/testsuite/ld-plugin/pr24406-2b.c
Normal file
@ -0,0 +1,4 @@
|
||||
int cook(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user