[lld] r187084 - [PECOFF] Add /include command line option.

Rui Ueyama ruiu at google.com
Wed Jul 24 15:53:24 PDT 2013


Author: ruiu
Date: Wed Jul 24 17:53:23 2013
New Revision: 187084

URL: http://llvm.org/viewvc/llvm-project?rev=187084&view=rev
Log:
[PECOFF] Add /include command line option.

The /include command line option is equivalent to Unix --undefined
option, which forces the linker to resolve the given symbol name
as if it's an unresolved symbol in one of its input files. This feature
is used to link an additional object file or a shared library that no
input files refer to.

Added:
    lld/trunk/test/pecoff/include.test
Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/Driver/WinLinkOptions.td
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
    lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h Wed Jul 24 17:53:23 2013
@@ -46,6 +46,8 @@ public:
 
   virtual void addPasses(PassManager &pm) const;
 
+  virtual void addImplicitFiles(InputFiles &) const;
+
   void appendInputSearchPath(StringRef dirPath) {
     _inputSearchPaths.push_back(dirPath);
   }
@@ -92,7 +94,7 @@ public:
   virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 
   StringRef allocateString(const StringRef &ref) {
-    char *x = _extraStrings.Allocate<char>(ref.size() + 1);
+    char *x = _alloc.Allocate<char>(ref.size() + 1);
     memcpy(x, ref.data(), ref.size());
     x[ref.size()] = '\0';
     return x;
@@ -117,7 +119,7 @@ private:
   std::vector<StringRef> _inputSearchPaths;
   mutable std::unique_ptr<Reader> _reader;
   mutable std::unique_ptr<Writer> _writer;
-  llvm::BumpPtrAllocator _extraStrings;
+  mutable llvm::BumpPtrAllocator _alloc;
 };
 
 } // end namespace lld

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Wed Jul 24 17:53:23 2013
@@ -351,6 +351,10 @@ bool WinLinkDriver::parse(int argc, cons
   if (parsedArgs->getLastArg(OPT_no_tsaware))
     info.setTerminalServerAware(false);
 
+  // Handle -include
+  if (llvm::opt::Arg *sym = parsedArgs->getLastArg(OPT_incl))
+    info.addInitialUndefinedSymbol(sym->getValue());
+
   // Handle -out
   if (llvm::opt::Arg *outpath = parsedArgs->getLastArg(OPT_out))
     info.setOutputPath(outpath->getValue());

Modified: lld/trunk/lib/Driver/WinLinkOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkOptions.td?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkOptions.td (original)
+++ lld/trunk/lib/Driver/WinLinkOptions.td Wed Jul 24 17:53:23 2013
@@ -60,5 +60,9 @@ def tsaware : Flag<["-", "/"], "tsaware"
 def no_tsaware : Flag<["-", "/"], "tsaware:no">,
     HelpText<"Create non-Terminal Server aware executable">;
 
+def incl : Separate<["-", "/"], "include">,
+    HelpText<"Force symbol to be added to symbol table as undefined one">;
+def incl_c : Joined<["-", "/"], "include:">, Alias<incl>;
+
 def help : Flag<["-", "/"], "help">;
 def help_q : Flag<["-", "/"], "?">, Alias<help>;

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp Wed Jul 24 17:53:23 2013
@@ -7,15 +7,19 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Atoms.h"
 #include "GroupedSectionsPass.h"
 #include "IdataPass.h"
 
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/Path.h"
+#include "lld/Core/InputFiles.h"
 #include "lld/Core/PassManager.h"
 #include "lld/Passes/LayoutPass.h"
 #include "lld/ReaderWriter/PECOFFTargetInfo.h"
 #include "lld/ReaderWriter/Reader.h"
+#include "lld/ReaderWriter/Simple.h"
 #include "lld/ReaderWriter/Writer.h"
 
 namespace lld {
@@ -26,6 +30,24 @@ bool containDirectoryName(StringRef path
   llvm::sys::path::remove_filename(smallStr);
   return !smallStr.str().empty();
 }
+
+/// An instance of UndefinedSymbolFile has a list of undefined symbols
+/// specified by "/include" command line option. This will be added to the
+/// input file list to force the core linker to try to resolve the undefined
+/// symbols.
+class UndefinedSymbolFile : public SimpleFile {
+public:
+  UndefinedSymbolFile(const TargetInfo &ti)
+      : SimpleFile(ti, "Linker Internal File") {
+    for (StringRef symbol : ti.initialUndefinedSymbols()) {
+      UndefinedAtom *atom = new (_alloc) coff::COFFUndefinedAtom(*this, symbol);
+      addAtom(*atom);
+    }
+  };
+
+private:
+  llvm::BumpPtrAllocator _alloc;
+};
 } // anonymous namespace
 
 error_code PECOFFTargetInfo::parseFile(
@@ -59,6 +81,12 @@ bool PECOFFTargetInfo::validateImpl(raw_
   return false;
 }
 
+void PECOFFTargetInfo::addImplicitFiles(InputFiles &files) const {
+  // Add a pseudo file for "/include" linker option.
+  auto *file = new (_alloc) UndefinedSymbolFile(*this);
+  files.prependFile(*file);
+}
+
 /// Append the given file to the input file list. The file must be an object
 /// file or an import library file.
 bool PECOFFTargetInfo::appendInputFileOrLibrary(std::string path) {

Added: lld/trunk/test/pecoff/include.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/include.test?rev=187084&view=auto
==============================================================================
--- lld/trunk/test/pecoff/include.test (added)
+++ lld/trunk/test/pecoff/include.test Wed Jul 24 17:53:23 2013
@@ -0,0 +1,7 @@
+# RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj
+#
+# RUN: not lld -flavor link -out %t1 -subsystem console \
+# RUN:   -include nosuchsym -- %t.obj 2> %t1
+# RUN: FileCheck %s < %t1
+
+CHECK: Undefined Symbol: Linker Internal File : nosuchsym
\ No newline at end of file

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=187084&r1=187083&r2=187084&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Wed Jul 24 17:53:23 2013
@@ -54,6 +54,7 @@ TEST_F(WinLinkParserTest, Basic) {
   EXPECT_FALSE(_info.getLargeAddressAware());
   EXPECT_TRUE(_info.getBaseRelocationEnabled());
   EXPECT_TRUE(_info.isTerminalServerAware());
+  EXPECT_TRUE(_info.initialUndefinedSymbols().empty());
 }
 
 TEST_F(WinLinkParserTest, WindowsStyleOption) {
@@ -172,6 +173,15 @@ TEST_F(WinLinkParserTest, NoTerminalServ
   EXPECT_FALSE(_info.isTerminalServerAware());
 }
 
+TEST_F(WinLinkParserTest, Include) {
+  EXPECT_FALSE(parse("link.exe", "-include", "foo", "a.out", nullptr));
+  auto symbols = _info.initialUndefinedSymbols();
+  EXPECT_FALSE(symbols.empty());
+  EXPECT_EQ("foo", symbols[0]);
+  symbols.pop_front();
+  EXPECT_TRUE(symbols.empty());
+}
+
 TEST_F(WinLinkParserTest, NoInputFiles) {
   EXPECT_TRUE(parse("link.exe", nullptr));
   EXPECT_EQ("No input files\n", errorMessage());





More information about the llvm-commits mailing list