diff options
author | Rui Ueyama <ruiu@google.com> | 2013-09-24 00:16:27 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2013-09-24 00:16:27 +0000 |
commit | f062c84aac5672459de98f9ff62fabe79b3aa825 (patch) | |
tree | e56111b8205752c437e87a85f73ebff1bb2238cf | |
parent | 799856259ff5ca52d6ffe5e3eefae4869ab6e22a (diff) | |
download | bcm5719-llvm-f062c84aac5672459de98f9ff62fabe79b3aa825.tar.gz bcm5719-llvm-f062c84aac5672459de98f9ff62fabe79b3aa825.zip |
[PECOFF] Add /nodefaultlib command line option.
llvm-svn: 191254
-rw-r--r-- | lld/include/lld/ReaderWriter/PECOFFLinkingContext.h | 16 | ||||
-rw-r--r-- | lld/lib/Driver/WinLinkDriver.cpp | 31 | ||||
-rw-r--r-- | lld/lib/Driver/WinLinkOptions.td | 3 | ||||
-rw-r--r-- | lld/unittests/DriverTests/WinLinkDriverTest.cpp | 39 |
4 files changed, 72 insertions, 17 deletions
diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h index 474d641dad7..3cc827aab83 100644 --- a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h @@ -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 LinkingContext { 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; diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp index ca9c9d3774d..324eef7f048 100644 --- a/lld/lib/Driver/WinLinkDriver.cpp +++ b/lld/lib/Driver/WinLinkDriver.cpp @@ -276,14 +276,23 @@ bool WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ct 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, const char *argv[], PECOFFLinkingContext &ct 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, const char *argv[], PECOFFLinkingContext &ct 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"; diff --git a/lld/lib/Driver/WinLinkOptions.td b/lld/lib/Driver/WinLinkOptions.td index 1a489856129..c0e66bc0776 100644 --- a/lld/lib/Driver/WinLinkOptions.td +++ b/lld/lib/Driver/WinLinkOptions.td @@ -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">; diff --git a/lld/unittests/DriverTests/WinLinkDriverTest.cpp b/lld/unittests/DriverTests/WinLinkDriverTest.cpp index 60e316c5ac3..30bfee6c550 100644 --- a/lld/unittests/DriverTests/WinLinkDriverTest.cpp +++ b/lld/unittests/DriverTests/WinLinkDriverTest.cpp @@ -160,15 +160,6 @@ TEST_F(WinLinkParserTest, MinMajorMinorOSVersion) { 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. // |