diff --git a/lld/test/wasm/ctor-no-gc-whole-archive.test b/lld/test/wasm/ctor-no-gc-whole-archive.test new file mode 100644 --- /dev/null +++ b/lld/test/wasm/ctor-no-gc-whole-archive.test @@ -0,0 +1,12 @@ +; Like ctor-gc.test, but uses `--whole-archive` to force the entire archive +; to be linked in, including the constructors. +; +; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/ctor-ctor.s -o %t.ctor.o +; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/ctor-lib.s -o %t.lib.o +; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/ctor-start.s -o %t.start.o +; RUN: rm -f %t.lib.a +; RUN: llvm-ar rcs %t.lib.a %t.lib.o %t.ctor.o +; RUN: wasm-ld %t.start.o --whole-archive %t.lib.a --no-whole-archive -o %t.wasm +; RUN: obj2yaml %t.wasm | FileCheck %s + +; CHECK: Name: test_ctor diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -253,7 +253,7 @@ // Handle -whole-archive. if (inWholeArchive) { for (MemoryBufferRef &m : getArchiveMembers(mbref)) - files.push_back(createObjectFile(m, path)); + files.push_back(createObjectFile(m, path, true)); return; } diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h --- a/lld/wasm/InputFiles.h +++ b/lld/wasm/InputFiles.h @@ -96,12 +96,12 @@ // .o file (wasm object file) class ObjFile : public InputFile { public: - explicit ObjFile(MemoryBufferRef m, StringRef archiveName) + explicit ObjFile(MemoryBufferRef m, StringRef archiveName, bool inWholeArchive) : InputFile(ObjectKind, m) { this->archiveName = std::string(archiveName); // If this isn't part of an archive, it's eagerly linked, so mark it live. - if (archiveName.empty()) + if (archiveName.empty() || inWholeArchive) markLive(); } static bool classof(const InputFile *f) { return f->kind() == ObjectKind; } @@ -164,12 +164,12 @@ // .bc file class BitcodeFile : public InputFile { public: - explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName) + explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName, bool inWholeArchive) : InputFile(BitcodeKind, m) { this->archiveName = std::string(archiveName); // If this isn't part of an archive, it's eagerly linked, so mark it live. - if (archiveName.empty()) + if (archiveName.empty() || inWholeArchive) markLive(); } static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } @@ -188,7 +188,8 @@ // Will report a fatal() error if the input buffer is not a valid bitcode // or wasm object file. -InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = ""); +InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = "", + bool inWholeArchive = false); // Opens a given file. llvm::Optional readFile(StringRef path); diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -60,7 +60,8 @@ } InputFile *createObjectFile(MemoryBufferRef mb, - StringRef archiveName) { + StringRef archiveName, + bool inWholeArchive) { file_magic magic = identify_magic(mb.getBuffer()); if (magic == file_magic::wasm_object) { std::unique_ptr bin = @@ -68,11 +69,11 @@ auto *obj = cast(bin.get()); if (obj->isSharedObject()) return make(mb); - return make(mb, archiveName); + return make(mb, archiveName, inWholeArchive); } if (magic == file_magic::bitcode) - return make(mb, archiveName); + return make(mb, archiveName, inWholeArchive); fatal("unknown file type: " + mb.getBufferIdentifier()); } diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -77,7 +77,7 @@ lto->add(*f); for (StringRef filename : lto->compile()) { - auto *obj = make(MemoryBufferRef(filename, "lto.tmp"), ""); + auto *obj = make(MemoryBufferRef(filename, "lto.tmp"), "", false); obj->parse(true); objectFiles.push_back(obj); }