[lld] r191254 - [PECOFF] Add /nodefaultlib command line option.
Rui Ueyama
ruiu at google.com
Mon Sep 23 17:16:27 PDT 2013
Author: ruiu
Date: Mon Sep 23 19:16:27 2013
New Revision: 191254
URL: http://llvm.org/viewvc/llvm-project?rev=191254&view=rev
Log:
[PECOFF] Add /nodefaultlib command line option.
Modified:
lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
lld/trunk/lib/Driver/WinLinkDriver.cpp
lld/trunk/lib/Driver/WinLinkOptions.td
lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=191254&r1=191253&r2=191254&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Mon Sep 23 19:16:27 2013
@@ -10,6 +10,7 @@
#ifndef LLD_READER_WRITER_PECOFF_LINKER_CONTEXT_H
#define LLD_READER_WRITER_PECOFF_LINKER_CONTEXT_H
+#include <set>
#include <vector>
#include "lld/Core/LinkingContext.h"
@@ -29,7 +30,8 @@ class PECOFFLinkingContext : public Link
public:
PECOFFLinkingContext()
: _baseAddress(0x400000), _stackReserve(1024 * 1024), _stackCommit(4096),
- _heapReserve(1024 * 1024), _heapCommit(4096), _sectionAlignment(4096),
+ _heapReserve(1024 * 1024), _heapCommit(4096), _noDefaultLibAll(false),
+ _sectionAlignment(4096),
_subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN),
_machineType(llvm::COFF::IMAGE_FILE_MACHINE_I386), _imageVersion(0, 0),
_minOSVersion(6, 0), _nxCompat(true), _largeAddressAware(false),
@@ -142,6 +144,14 @@ public:
void setImageType(ImageType type) { _imageType = type; }
ImageType getImageType() const { return _imageType; }
+ void addNoDefaultLib(StringRef libName) { _noDefaultLibs.insert(libName); }
+ const std::set<std::string> &getNoDefaultLibs() const {
+ return _noDefaultLibs;
+ }
+
+ void setNoDefaultLibAll(bool val) { _noDefaultLibAll = val; }
+ bool getNoDefaultLibAll() const { return _noDefaultLibAll; }
+
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
@@ -174,6 +184,7 @@ private:
uint64_t _stackCommit;
uint64_t _heapReserve;
uint64_t _heapCommit;
+ bool _noDefaultLibAll;
uint32_t _sectionAlignment;
WindowsSubsystem _subsystem;
MachineTypes _machineType;
@@ -188,6 +199,9 @@ private:
bool _dynamicBaseEnabled;
ImageType _imageType;
+ // The set to store /nodefaultlib arguments.
+ std::set<std::string> _noDefaultLibs;
+
std::vector<StringRef> _inputSearchPaths;
mutable std::unique_ptr<Reader> _reader;
mutable std::unique_ptr<Writer> _writer;
Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=191254&r1=191253&r2=191254&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Mon Sep 23 19:16:27 2013
@@ -276,14 +276,23 @@ bool WinLinkDriver::parse(int argc, cons
InputGraph &inputGraph = ctx.inputGraph();
- // handle /help
+ // Handle /help
if (parsedArgs->getLastArg(OPT_help)) {
WinLinkOptTable table;
table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
return true;
}
- // handle /defaultlib
+ // Handle /nodefaultlib:<lib>. The same option without argument is handled in
+ // the following for loop.
+ for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_nodefaultlib),
+ ie = parsedArgs->filtered_end();
+ it != ie; ++it) {
+ ctx.addNoDefaultLib((*it)->getValue());
+ }
+
+ // Handle /defaultlib. Argument of the option is added to the input file list
+ // unless it's blacklisted by /nodefaultlib.
std::vector<StringRef> defaultLibs;
for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_defaultlib),
ie = parsedArgs->filtered_end();
@@ -472,6 +481,11 @@ bool WinLinkDriver::parse(int argc, cons
ctx.addInitialUndefinedSymbol(ctx.allocateString(inputArg->getValue()));
break;
+ case OPT_nodefaultlib_all:
+ // handle /nodefaultlib
+ ctx.setNoDefaultLibAll(true);
+ break;
+
case OPT_out:
// handle /out
ctx.setOutputPath(ctx.allocateString(inputArg->getValue()));
@@ -515,11 +529,14 @@ bool WinLinkDriver::parse(int argc, cons
std::unique_ptr<InputElement>(new PECOFFFileNode(ctx, value)));
}
- // Add ".lib" extension if the path does not already have the extension to
- // mimic link.exe behavior.
- for (auto defaultLibPath : defaultLibs)
- inputGraph.addInputElement(std::unique_ptr<InputElement>(
- new PECOFFLibraryNode(ctx, defaultLibPath)));
+ // Add the libraries specified by /defaultlib unless they are blacklisted by
+ // /nodefaultlib.
+ if (!ctx.getNoDefaultLibAll())
+ for (auto defaultLibPath : defaultLibs)
+ if (ctx.getNoDefaultLibs().find(defaultLibPath) ==
+ ctx.getNoDefaultLibs().end())
+ inputGraph.addInputElement(std::unique_ptr<InputElement>(
+ new PECOFFLibraryNode(ctx, defaultLibPath)));
if (!inputGraph.numFiles()) {
diagnostics << "No input files\n";
Modified: lld/trunk/lib/Driver/WinLinkOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkOptions.td?rev=191254&r1=191253&r2=191254&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkOptions.td (original)
+++ lld/trunk/lib/Driver/WinLinkOptions.td Mon Sep 23 19:16:27 2013
@@ -17,6 +17,7 @@ multiclass B<string name, string help> {
def base : P<"base", "Base address of the program">;
def defaultlib : P<"defaultlib", "Add the library to the list of input files">;
+def nodefaultlib : P<"nodefaultlib", "Remove a default library">;
def entry : P<"entry", "Name of entry point symbol">;
// No help text because /failifmismatch is not intended to be used by the user.
def failifmismatch : P<"failifmismatch", "">;
@@ -37,6 +38,8 @@ def incl : Joined<["/", "-"], "include:"
HelpText<"Force symbol to be added to symbol table as undefined one">;
def incl_c : Separate<["/", "-"], "include">, Alias<incl>;
+def nodefaultlib_all : F<"nodefaultlib">;
+
def force : F<"force">,
HelpText<"Allow undefined symbols when creating executables">;
def force_unresolved : F<"force:unresolved">;
Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=191254&r1=191253&r2=191254&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Mon Sep 23 19:16:27 2013
@@ -160,15 +160,6 @@ TEST_F(WinLinkParserTest, MinMajorMinorO
EXPECT_EQ(1, _context.getMinOSVersion().minorVersion);
}
-TEST_F(WinLinkParserTest, DefaultLib) {
- EXPECT_FALSE(parse("link.exe", "/defaultlib:user32.lib",
- "/defaultlib:kernel32", "a.obj", nullptr));
- EXPECT_EQ(3, inputFileCount());
- EXPECT_EQ("a.obj", inputFile(0));
- EXPECT_EQ("user32.lib", inputFile(1));
- EXPECT_EQ("kernel32.lib", inputFile(2));
-}
-
TEST_F(WinLinkParserTest, Base) {
EXPECT_FALSE(parse("link.exe", "/base:8388608", "a.obj", nullptr));
EXPECT_EQ(0x800000U, _context.getBaseAddress());
@@ -235,6 +226,36 @@ TEST_F(WinLinkParserTest, Include) {
}
//
+// Tests for /defaultlib and /nodefaultlib.
+//
+
+TEST_F(WinLinkParserTest, DefaultLib) {
+ EXPECT_FALSE(parse("link.exe", "/defaultlib:user32.lib",
+ "/defaultlib:kernel32", "a.obj", nullptr));
+ EXPECT_EQ(3, inputFileCount());
+ EXPECT_EQ("a.obj", inputFile(0));
+ EXPECT_EQ("user32.lib", inputFile(1));
+ EXPECT_EQ("kernel32.lib", inputFile(2));
+}
+
+TEST_F(WinLinkParserTest, NoDefaultLib) {
+ EXPECT_FALSE(parse("link.exe", "/defaultlib:user32.lib",
+ "/defaultlib:kernel32", "/nodefaultlib:user32.lib",
+ "a.obj", nullptr));
+ EXPECT_EQ(2, inputFileCount());
+ EXPECT_EQ("a.obj", inputFile(0));
+ EXPECT_EQ("kernel32.lib", inputFile(1));
+}
+
+TEST_F(WinLinkParserTest, NoDefaultLibAll) {
+ EXPECT_FALSE(parse("link.exe", "/defaultlib:user32.lib",
+ "/defaultlib:kernel32", "/nodefaultlib", "a.obj",
+ nullptr));
+ EXPECT_EQ(1, inputFileCount());
+ EXPECT_EQ("a.obj", inputFile(0));
+}
+
+//
// Tests for boolean flags.
//
More information about the llvm-commits
mailing list