Index: test/wasm/archive.ll =================================================================== --- test/wasm/archive.ll +++ test/wasm/archive.ll @@ -2,30 +2,41 @@ ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/archive1.ll -o %t.a1.o ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/archive2.ll -o %t.a2.o ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/hello.ll -o %t.a3.o -; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o -; RUN: lld -flavor wasm %t.a %t.o -o %t.wasm +; RUN: mkdir -p %t.dir +; RUN: rm %t.dir/libtest.imports +; RUN: llvm-ar rcs %t.dir/libtest.a %t.a1.o %t.a2.o %t.a3.o +; RUN: not lld -flavor wasm %t.dir/libtest.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED %s +; RUN: not lld -flavor wasm -L%t.dir -ltest %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED %s + +; CHECK-UNDEFINED: undefined symbol: missing_func + +; RUN: echo 'missing_func' > %t.dir/libtest.imports +; RUN: lld -flavor wasm -L%t.dir -ltest %t.o -o %t.wasm + ; RUN: llvm-nm -a %t.wasm | FileCheck %s declare i32 @foo() local_unnamed_addr #1 +declare i32 @missing_func() local_unnamed_addr #1 define i32 @_start() local_unnamed_addr #0 { entry: - %call = tail call i32 @foo() #2 - ret i32 %call + %call1 = call i32 @foo() #2 + %call2 = call i32 @missing_func() #2 + ret i32 %call2 } ; Verify that multually dependant object files in an archive is handled ; correctly. -; CHECK: 00000002 T _start -; CHECK-NEXT: 00000002 T _start -; CHECK-NEXT: 00000000 T bar -; CHECK-NEXT: 00000000 T bar -; CHECK-NEXT: 00000001 T foo -; CHECK-NEXT: 00000001 T foo +; CHECK: 00000003 T _start +; CHECK-NEXT: 00000003 T _start +; CHECK-NEXT: 00000001 T bar +; CHECK-NEXT: 00000001 T bar +; CHECK-NEXT: 00000002 T foo +; CHECK-NEXT: 00000002 T foo ; Verify that symbols from unused objects don't appear in the symbol table ; CHECK-NOT: hello ; Specifying the same archive twice is allowed. -; RUN: lld -flavor wasm %t.a %t.a %t.o -o %t.wasm +; RUN: lld -flavor wasm -L%t.dir -ltest -ltest %t.o -o %t.wasm Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -173,11 +173,21 @@ Files.push_back(make(MBRef)); } +static void processImportFile(StringRef Filename) { + if (Optional Buf = readFile(Filename)) + for (StringRef Sym : args::getLines(*Buf)) + Config->AllowUndefinedSymbols.insert(Sym); +} + // Add a given library by searching it from input search paths. void LinkerDriver::addLibrary(StringRef Name) { for (StringRef Dir : Config->SearchPaths) { if (Optional S = findFile(Dir, "lib" + Name + ".a")) { addFile(*S); + SmallString<128> ImportFile = Dir; + path::append(ImportFile, "lib" + Name + ".imports"); + if (fs::exists(ImportFile)) + processImportFile(ImportFile.str()); return; } } @@ -257,9 +267,7 @@ args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize); if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file)) - if (Optional Buf = readFile(Arg->getValue())) - for (StringRef Sym : args::getLines(*Buf)) - Config->AllowUndefinedSymbols.insert(Sym); + processImportFile(Arg->getValue()); if (Config->OutputFile.empty()) error("no output file specified");