[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