[lld] r313123 - [COFF] Add support for the -wholearchive option
Martin Storsjo via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 13 00:28:04 PDT 2017
Author: mstorsjo
Date: Wed Sep 13 00:28:03 2017
New Revision: 313123
URL: http://llvm.org/viewvc/llvm-project?rev=313123&view=rev
Log:
[COFF] Add support for the -wholearchive option
This fixes PR31824.
Differential Revision: https://reviews.llvm.org/D37709
Added:
lld/trunk/test/COFF/wholearchive.s
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Driver.h
lld/trunk/COFF/Options.td
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=313123&r1=313122&r2=313123&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Wed Sep 13 00:28:03 2017
@@ -110,7 +110,8 @@ MemoryBufferRef LinkerDriver::takeBuffer
return MBRef;
}
-void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB) {
+void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB,
+ bool WholeArchive) {
MemoryBufferRef MBRef = takeBuffer(std::move(MB));
// File type is detected by contents, not by file extension.
@@ -121,10 +122,24 @@ void LinkerDriver::addBuffer(std::unique
}
FilePaths.push_back(MBRef.getBufferIdentifier());
- if (Magic == file_magic::archive)
- return Symtab->addFile(make<ArchiveFile>(MBRef));
- if (Magic == file_magic::bitcode)
- return Symtab->addFile(make<BitcodeFile>(MBRef));
+ if (Magic == file_magic::archive) {
+ if (WholeArchive) {
+ std::unique_ptr<Archive> File =
+ check(Archive::create(MBRef),
+ MBRef.getBufferIdentifier() + ": failed to parse archive");
+
+ for (MemoryBufferRef M : getArchiveMembers(File.get()))
+ addArchiveBuffer(M, "<whole-archive>", MBRef.getBufferIdentifier());
+ return;
+ }
+ Symtab->addFile(make<ArchiveFile>(MBRef));
+ return;
+ }
+
+ if (Magic == file_magic::bitcode) {
+ Symtab->addFile(make<BitcodeFile>(MBRef));
+ return;
+ }
if (Magic == file_magic::coff_cl_gl_object)
error(MBRef.getBufferIdentifier() + ": is not a native COFF file. "
@@ -133,7 +148,7 @@ void LinkerDriver::addBuffer(std::unique
Symtab->addFile(make<ObjFile>(MBRef));
}
-void LinkerDriver::enqueuePath(StringRef Path) {
+void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) {
auto Future =
std::make_shared<std::future<MBErrPair>>(createFutureForFile(Path));
std::string PathStr = Path;
@@ -142,7 +157,7 @@ void LinkerDriver::enqueuePath(StringRef
if (MBOrErr.second)
error("could not open " + PathStr + ": " + MBOrErr.second.message());
else
- Driver->addBuffer(std::move(MBOrErr.first));
+ Driver->addBuffer(std::move(MBOrErr.first), WholeArchive);
});
}
@@ -215,7 +230,7 @@ void LinkerDriver::parseDirectives(Strin
break;
case OPT_defaultlib:
if (Optional<StringRef> Path = findLib(Arg->getValue()))
- enqueuePath(*Path);
+ enqueuePath(*Path, false);
break;
case OPT_export: {
Export E = parseExport(Arg->getValue());
@@ -953,19 +968,29 @@ void LinkerDriver::link(ArrayRef<const c
if (ErrorCount)
return;
+ bool WholeArchiveFlag = Args.hasArg(OPT_wholearchive_flag);
// Create a list of input files. Files can be given as arguments
// for /defaultlib option.
std::vector<MemoryBufferRef> MBs;
- for (auto *Arg : Args.filtered(OPT_INPUT))
- if (Optional<StringRef> Path = findFile(Arg->getValue()))
- enqueuePath(*Path);
+ for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file)) {
+ switch (Arg->getOption().getID()) {
+ case OPT_INPUT:
+ if (Optional<StringRef> Path = findFile(Arg->getValue()))
+ enqueuePath(*Path, WholeArchiveFlag);
+ break;
+ case OPT_wholearchive_file:
+ if (Optional<StringRef> Path = findFile(Arg->getValue()))
+ enqueuePath(*Path, true);
+ break;
+ }
+ }
for (auto *Arg : Args.filtered(OPT_defaultlib))
if (Optional<StringRef> Path = findLib(Arg->getValue()))
- enqueuePath(*Path);
+ enqueuePath(*Path, false);
// Windows specific -- Create a resource file containing a manifest file.
if (Config->Manifest == Configuration::Embed)
- addBuffer(createManifestRes());
+ addBuffer(createManifestRes(), false);
// Read all input files given via the command line.
run();
@@ -981,7 +1006,7 @@ void LinkerDriver::link(ArrayRef<const c
// WindowsResource to convert resource files to a regular COFF file,
// then link the resulting file normally.
if (!Resources.empty())
- addBuffer(convertResToCOFF(Resources));
+ addBuffer(convertResToCOFF(Resources), false);
if (Tar)
Tar->append("response.txt",
Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=313123&r1=313122&r2=313123&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Wed Sep 13 00:28:03 2017
@@ -110,11 +110,11 @@ private:
void invokeMSVC(llvm::opt::InputArgList &Args);
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
- void addBuffer(std::unique_ptr<MemoryBuffer> MB);
+ void addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive);
void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
StringRef ParentName);
- void enqueuePath(StringRef Path);
+ void enqueuePath(StringRef Path, bool WholeArchive);
void enqueueTask(std::function<void()> Task);
bool run();
Modified: lld/trunk/COFF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Options.td?rev=313123&r1=313122&r2=313123&view=diff
==============================================================================
--- lld/trunk/COFF/Options.td (original)
+++ lld/trunk/COFF/Options.td Wed Sep 13 00:28:03 2017
@@ -47,6 +47,7 @@ def stack : P<"stack", "Size of the st
def stub : P<"stub", "Specify DOS stub file">;
def subsystem : P<"subsystem", "Specify subsystem">;
def version : P<"version", "Specify a version number in the PE header">;
+def wholearchive_file : P<"wholearchive", "Include all object files from this archive">;
def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;
@@ -78,6 +79,7 @@ def profile : F<"profile">;
def swaprun_cd : F<"swaprun:cd">;
def swaprun_net : F<"swaprun:net">;
def verbose : F<"verbose">;
+def wholearchive_flag : F<"wholearchive">;
def force : F<"force">,
HelpText<"Allow undefined symbols when creating executables">;
Added: lld/trunk/test/COFF/wholearchive.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/wholearchive.s?rev=313123&view=auto
==============================================================================
--- lld/trunk/test/COFF/wholearchive.s (added)
+++ lld/trunk/test/COFF/wholearchive.s Wed Sep 13 00:28:03 2017
@@ -0,0 +1,19 @@
+# REQEUIRES: x86
+
+# RUN: yaml2obj < %p/Inputs/export.yaml > %t.archive.obj
+# RUN: llvm-ar rcs %t.archive.lib %t.archive.obj
+# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.main.obj
+
+# RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj -wholearchive:%t.archive.lib -implib:%t.lib
+# RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB
+
+# RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj -wholearchive %t.archive.lib -implib:%t.lib
+# RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB
+
+# CHECK-IMPLIB: Symbol: __imp_exportfn3
+# CHECK-IMPLIB: Symbol: exportfn3
+
+.global main
+.text
+main:
+ ret
More information about the llvm-commits
mailing list