1
1
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:
Rui Ueyama 2022-02-13 11:54:04 +09:00
parent e18eaac3eb
commit 70ec56f8bb
4 changed files with 65 additions and 9 deletions

View File

@ -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>

View File

@ -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
View 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
View 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