diff --git a/lld/test/wasm/lto/stub-library.s b/lld/test/wasm/lto/stub-library.s index 20e2a62211413..36d6b7b3f38aa 100644 --- a/lld/test/wasm/lto/stub-library.s +++ b/lld/test/wasm/lto/stub-library.s @@ -1,12 +1,21 @@ +## The function `bar` is declared in stub.so and depends on `foo` which is +## defined in an LTO object. We also test the case where the LTO object is +## with an archive file. +## This verifies that stub library dependencies (which are required exports) can +## be defined in LTO objects, even when they are within archive files. + # RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s -# RUN: llvm-as %S/Inputs/foo.ll -o %t1.o -# RUN: wasm-ld %t.o %t1.o %p/Inputs/stub.so -o %t.wasm +# RUN: mkdir -p %t +# RUN: llvm-as %S/Inputs/foo.ll -o %t/foo.o +# RUN: wasm-ld %t.o %t/foo.o %p/Inputs/stub.so -o %t.wasm # RUN: obj2yaml %t.wasm | FileCheck %s -# The function `bar` is declared in stub.so and depends on `foo`, which happens -# be in an LTO object. -# This verifies that stub library dependencies (required exports) can be defined -# in LTO objects. +## Run the same test but with foo.o inside of an archive file. +# RUN: rm -f %t/libfoo.a +# RUN: llvm-ar rcs %t/libfoo.a %t/foo.o +# RUN: wasm-ld %t.o %t/libfoo.a %p/Inputs/stub.so -o %t2.wasm +# RUN: obj2yaml %t2.wasm | FileCheck %s + .functype bar () -> () .globl _start diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index 8c83d17db02f5..5368fe79b7eb8 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -949,6 +949,17 @@ static void processStubLibrariesPreLTO() { auto* needed = symtab->find(dep); if (needed ) { needed->isUsedInRegularObj = true; + // Like with handleLibcall we have to extract any LTO archive + // members that might need to be exported due to stub library + // symbols being referenced. Without this the LTO object could be + // extracted during processStubLibraries, which is too late since + // LTO has already being performed at that point. + if (needed->isLazy() && isa(needed->getFile())) { + if (!config->whyExtract.empty()) + ctx.whyExtractRecords.emplace_back(toString(stub_file), + needed->getFile(), *needed); + cast(needed)->extract(); + } } } } diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index f3f0ef9a99497..706ee25d5aae2 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -744,7 +744,7 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &sym, bool isCalledDirectly) { llvm_unreachable("unknown symbol kind"); } -StringRef strip(StringRef s) { return s.trim(' '); } +static StringRef strip(StringRef s) { return s.trim(' '); } void StubFile::parse() { bool first = true; @@ -761,7 +761,7 @@ void StubFile::parse() { } // Lines starting with # are considered comments - if (line.starts_with("#")) + if (line.starts_with("#") || !line.size()) continue; StringRef sym;