mirror of
https://github.com/rui314/mold.git
synced 2024-11-09 16:05:58 +03:00
[ELF][LTO] Export symbols from DSOs correctly
With this change, mold can now build Clang with LTO and all Clang tests pass.
This commit is contained in:
parent
e18eaac3eb
commit
70ec56f8bb
@ -486,6 +486,7 @@ ObjectFile<E> *read_lto_object(Context<E> &ctx, MappedFile<Context<E>> *mf) {
|
||||
|
||||
// Create mold's object instance
|
||||
ObjectFile<E> *obj = new ObjectFile<E>;
|
||||
obj->filename = mf->name;
|
||||
obj->symbols.push_back(new Symbol<E>);
|
||||
obj->first_global = 1;
|
||||
obj->is_lto_obj = true;
|
||||
@ -563,6 +564,12 @@ void do_lto(Context<E> &ctx) {
|
||||
file->is_alive = false;
|
||||
|
||||
std::erase_if(ctx.objs, [](ObjectFile<E> *file) { return file->is_lto_obj; });
|
||||
|
||||
// Re-compute symbol versions and import/export information
|
||||
// because `resolve_symbols` may have overwrite them.
|
||||
apply_version_script(ctx);
|
||||
parse_symbol_version(ctx);
|
||||
compute_import_export(ctx);
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
|
18
elf/main.cc
18
elf/main.cc
@ -469,6 +469,15 @@ static int elf_main(int argc, char **argv) {
|
||||
// included to the final output.
|
||||
resolve_symbols(ctx);
|
||||
|
||||
// Apply version scripts.
|
||||
apply_version_script(ctx);
|
||||
|
||||
// Parse symbol version suffixes (e.g. "foo@ver1").
|
||||
parse_symbol_version(ctx);
|
||||
|
||||
// Set is_import and is_export bits for each symbol.
|
||||
compute_import_export(ctx);
|
||||
|
||||
// Do LTO
|
||||
if (ctx.has_lto_object)
|
||||
do_lto(ctx);
|
||||
@ -482,15 +491,6 @@ static int elf_main(int argc, char **argv) {
|
||||
// Create .bss sections for common symbols.
|
||||
convert_common_symbols(ctx);
|
||||
|
||||
// Apply version scripts.
|
||||
apply_version_script(ctx);
|
||||
|
||||
// Parse symbol version suffixes (e.g. "foo@ver1").
|
||||
parse_symbol_version(ctx);
|
||||
|
||||
// Set is_import and is_export bits for each symbol.
|
||||
compute_import_export(ctx);
|
||||
|
||||
// Garbage-collect unreachable sections.
|
||||
if (ctx.arg.gc_sections)
|
||||
gc_sections(ctx);
|
||||
|
20
test/elf/lto-dso.sh
Executable file
20
test/elf/lto-dso.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
export LANG=
|
||||
set -e
|
||||
CC="${CC:-cc}"
|
||||
CXX="${CXX:-c++}"
|
||||
testname=$(basename "$0" .sh)
|
||||
echo -n "Testing $testname ... "
|
||||
cd "$(dirname "$0")"/../..
|
||||
mold="$(pwd)/mold"
|
||||
t=out/test/elf/$testname
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | $CC -flto -c -fPIC -o $t/a.o -xc -
|
||||
void foo() {}
|
||||
EOF
|
||||
|
||||
$CC -B. -shared -o $t/b.so -flto $t/a.o
|
||||
nm -D $t/b.so | grep -q 'T foo'
|
||||
|
||||
echo OK
|
29
test/elf/lto-version-script.sh
Executable file
29
test/elf/lto-version-script.sh
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
export LANG=
|
||||
set -e
|
||||
CC="${CC:-cc}"
|
||||
CXX="${CXX:-c++}"
|
||||
testname=$(basename "$0" .sh)
|
||||
echo -n "Testing $testname ... "
|
||||
cd "$(dirname "$0")"/../..
|
||||
mold="$(pwd)/mold"
|
||||
t=out/test/elf/$testname
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | $CC -flto -c -fPIC -o $t/a.o -xc -
|
||||
void foo() {}
|
||||
void bar() {}
|
||||
EOF
|
||||
|
||||
cat <<EOF > $t/b.script
|
||||
{
|
||||
global: foo;
|
||||
local: *;
|
||||
};
|
||||
EOF
|
||||
|
||||
$CC -B. -shared -o $t/c.so -flto $t/a.o -Wl,-version-script=$t/b.script
|
||||
nm -D $t/c.so | grep -q 'T foo'
|
||||
! nm -D $t/c.so | grep -q 'T bar' || false
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user