mirror of
https://github.com/rui314/mold.git
synced 2024-09-19 08:57:39 +03:00
[ELF] Make --wrap work with LTO
Fixes https://github.com/rui314/mold/issues/916
This commit is contained in:
parent
cc3e5fd1a8
commit
07d89116a8
@ -270,7 +270,7 @@ get_symbols_v1(const void *handle, int nsyms, PluginSymbol *psyms) {
|
|||||||
unreachable();
|
unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_symbols teaches the LTO plugin as to how we resolved symbols.
|
// get_symbols teaches the LTO plugin as to how we have resolved symbols.
|
||||||
// The plugin uses the symbol resolution info to optimize the program.
|
// The plugin uses the symbol resolution info to optimize the program.
|
||||||
//
|
//
|
||||||
// For example, if a definition in an IR file is not referenced by
|
// For example, if a definition in an IR file is not referenced by
|
||||||
@ -308,7 +308,8 @@ get_symbols(const void *handle, int nsyms, PluginSymbol *psyms, bool is_v2) {
|
|||||||
|
|
||||||
if (sym.file->is_dso)
|
if (sym.file->is_dso)
|
||||||
return LDPR_RESOLVED_DYN;
|
return LDPR_RESOLVED_DYN;
|
||||||
if (((ObjectFile<E> *)sym.file)->is_lto_obj)
|
|
||||||
|
if (((ObjectFile<E> *)sym.file)->is_lto_obj && !sym.wrap)
|
||||||
return esym.is_undef() ? LDPR_RESOLVED_IR : LDPR_PREEMPTED_IR;
|
return esym.is_undef() ? LDPR_RESOLVED_IR : LDPR_PREEMPTED_IR;
|
||||||
return esym.is_undef() ? LDPR_RESOLVED_EXEC : LDPR_PREEMPTED_REG;
|
return esym.is_undef() ? LDPR_RESOLVED_EXEC : LDPR_PREEMPTED_REG;
|
||||||
};
|
};
|
||||||
@ -679,6 +680,18 @@ std::vector<ObjectFile<E> *> do_lto(Context<E> &ctx) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Symbols specified by the --wrap option needs to be visible from
|
||||||
|
// regular object files.
|
||||||
|
for (std::string_view name : ctx.arg.wrap) {
|
||||||
|
get_symbol(ctx, name)->referenced_by_regular_obj = true;
|
||||||
|
|
||||||
|
std::string_view x = save_string(ctx, "__wrap_" + std::string(name));
|
||||||
|
std::string_view y = save_string(ctx, "__real_" + std::string(name));
|
||||||
|
|
||||||
|
get_symbol(ctx, x)->referenced_by_regular_obj = true;
|
||||||
|
get_symbol(ctx, x)->referenced_by_regular_obj = true;
|
||||||
|
}
|
||||||
|
|
||||||
// all_symbols_read_hook() calls add_input_file() and add_input_library()
|
// all_symbols_read_hook() calls add_input_file() and add_input_library()
|
||||||
LOG << "all symbols read\n";
|
LOG << "all symbols read\n";
|
||||||
if (PluginStatus st = all_symbols_read_hook(); st != LDPS_OK)
|
if (PluginStatus st = all_symbols_read_hook(); st != LDPS_OK)
|
||||||
|
0
test/elf/ifunc-alias.sh
Normal file → Executable file
0
test/elf/ifunc-alias.sh
Normal file → Executable file
43
test/elf/wrap-lto.sh
Executable file
43
test/elf/wrap-lto.sh
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
. $(dirname $0)/common.inc
|
||||||
|
|
||||||
|
cat <<EOF | $CC -fPIC -shared -o $t/a.so -xc -
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void foo() {
|
||||||
|
printf("foo\n");
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF | $CC -c -o $t/b.o -xc - -flto
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void foo();
|
||||||
|
|
||||||
|
void __wrap_foo() {
|
||||||
|
printf("wrap_foo\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF | $CC -c -o $t/c.o -xc - -flto
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void __real_foo();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
__real_foo();
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
$CC -B. -o $t/exe $t/a.so $t/b.o -flto
|
||||||
|
$QEMU $t/exe | grep -q '^foo$'
|
||||||
|
|
||||||
|
$CC -B. -o $t/exe $t/a.so $t/b.o -Wl,-wrap,foo -flto
|
||||||
|
$QEMU $t/exe | grep -q '^wrap_foo$'
|
||||||
|
|
||||||
|
$CC -B. -o $t/exe $t/a.so $t/c.o -Wl,-wrap,foo -flto
|
||||||
|
$QEMU $t/exe | grep -q '^foo$'
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
. $(dirname $0)/common.inc
|
. $(dirname $0)/common.inc
|
||||||
|
|
||||||
cat <<EOF | $CC -c -o $t/a.o -xc -
|
cat <<EOF | $CC -fPIC -shared -o $t/a.so -xc -
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void foo() {
|
void foo() {
|
||||||
@ -33,11 +33,11 @@ int main() {
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
$CC -B. -o $t/exe $t/a.o $t/b.o
|
$CC -B. -o $t/exe $t/a.so $t/b.o
|
||||||
$QEMU $t/exe | grep -q '^foo$'
|
$QEMU $t/exe | grep -q '^foo$'
|
||||||
|
|
||||||
$CC -B. -o $t/exe $t/a.o $t/b.o -Wl,-wrap,foo
|
$CC -B. -o $t/exe $t/a.so $t/b.o -Wl,-wrap,foo
|
||||||
$QEMU $t/exe | grep -q '^wrap_foo$'
|
$QEMU $t/exe | grep -q '^wrap_foo$'
|
||||||
|
|
||||||
$CC -B. -o $t/exe $t/a.o $t/c.o -Wl,-wrap,foo
|
$CC -B. -o $t/exe $t/a.so $t/c.o -Wl,-wrap,foo
|
||||||
$QEMU $t/exe | grep -q '^foo$'
|
$QEMU $t/exe | grep -q '^foo$'
|
||||||
|
Loading…
Reference in New Issue
Block a user