1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-17 16:09:43 +03:00

[ELF] Make --wrap work with LTO

Fixes https://github.com/rui314/mold/issues/916
This commit is contained in:
Rui Ueyama 2022-12-16 12:23:52 +08:00
parent cc3e5fd1a8
commit 07d89116a8
4 changed files with 62 additions and 6 deletions

View File

@ -270,7 +270,7 @@ get_symbols_v1(const void *handle, int nsyms, PluginSymbol *psyms) {
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.
//
// 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)
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_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()
LOG << "all symbols read\n";
if (PluginStatus st = all_symbols_read_hook(); st != LDPS_OK)

0
test/elf/ifunc-alias.sh Normal file → Executable file
View File

43
test/elf/wrap-lto.sh Executable file
View 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$'

View File

@ -1,7 +1,7 @@
#!/bin/bash
. $(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>
void foo() {
@ -33,11 +33,11 @@ int main() {
}
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$'
$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$'
$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$'