summaryrefslogtreecommitdiff
path: root/lld/wasm/Driver.cpp
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2018-07-23 23:51:19 +0000
committerSam Clegg <sbc@chromium.org>2018-07-23 23:51:19 +0000
commit270119b876cc41fa828b5da209225a543d02adbb (patch)
treeedc1579dbf81ce7553a6678888f7c6299e4cc028 /lld/wasm/Driver.cpp
parentbc27e6ef4f291fcfb9c082a91e8ac11dccf91385 (diff)
[WebAssembly] Add support for --whole-archive.
Subscribers: dschuff, jgravelle-google, aheejin, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D49706
Diffstat (limited to 'lld/wasm/Driver.cpp')
-rw-r--r--lld/wasm/Driver.cpp53
1 files changed, 51 insertions, 2 deletions
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index ccaf90fc785..329b5ae80a9 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -68,6 +68,10 @@ private:
void createFiles(opt::InputArgList &Args);
void addFile(StringRef Path);
void addLibrary(StringRef Name);
+
+ // True if we are in --whole-archive and --no-whole-archive.
+ bool InWholeArchive = false;
+
std::vector<InputFile *> Files;
};
} // anonymous namespace
@@ -180,6 +184,37 @@ static void readImportFile(StringRef Filename) {
Config->AllowUndefinedSymbols.insert(Sym);
}
+// Returns slices of MB by parsing MB as an archive file.
+// Each slice consists of a member file in the archive.
+std::vector<MemoryBufferRef> static getArchiveMembers(
+ MemoryBufferRef MB) {
+ std::unique_ptr<Archive> File =
+ CHECK(Archive::create(MB),
+ MB.getBufferIdentifier() + ": failed to parse archive");
+
+ std::vector<MemoryBufferRef> V;
+ Error Err = Error::success();
+ for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
+ Archive::Child C =
+ CHECK(COrErr, MB.getBufferIdentifier() +
+ ": could not get the child of the archive");
+ MemoryBufferRef MBRef =
+ CHECK(C.getMemoryBufferRef(),
+ MB.getBufferIdentifier() +
+ ": could not get the buffer for a child of the archive");
+ V.push_back(MBRef);
+ }
+ if (Err)
+ fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
+ toString(std::move(Err)));
+
+ // Take ownership of memory buffers created for members of thin archives.
+ for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
+ make<std::unique_ptr<MemoryBuffer>>(std::move(MB));
+
+ return V;
+}
+
void LinkerDriver::addFile(StringRef Path) {
Optional<MemoryBufferRef> Buffer = readFile(Path);
if (!Buffer.hasValue())
@@ -188,6 +223,13 @@ void LinkerDriver::addFile(StringRef Path) {
switch (identify_magic(MBRef.getBuffer())) {
case file_magic::archive: {
+ // Handle -whole-archive.
+ if (InWholeArchive) {
+ for (MemoryBufferRef &M : getArchiveMembers(MBRef))
+ Files.push_back(createObjectFile(M));
+ return;
+ }
+
SmallString<128> ImportFile = Path;
path::replace_extension(ImportFile, ".imports");
if (fs::exists(ImportFile))
@@ -197,10 +239,11 @@ void LinkerDriver::addFile(StringRef Path) {
return;
}
case file_magic::bitcode:
- Files.push_back(make<BitcodeFile>(MBRef));
+ case file_magic::wasm_object:
+ Files.push_back(createObjectFile(MBRef));
break;
default:
- Files.push_back(make<ObjFile>(MBRef));
+ error("unknown file type: " + MBRef.getBufferIdentifier());
}
}
@@ -225,6 +268,12 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
case OPT_INPUT:
addFile(Arg->getValue());
break;
+ case OPT_whole_archive:
+ InWholeArchive = true;
+ break;
+ case OPT_no_whole_archive:
+ InWholeArchive = false;
+ break;
}
}
}