[lld] r214824 - [PECOFF] Fix /include option in .drectve section.

Rui Ueyama ruiu at google.com
Mon Aug 4 16:48:58 PDT 2014


Author: ruiu
Date: Mon Aug  4 18:48:57 2014
New Revision: 214824

URL: http://llvm.org/viewvc/llvm-project?rev=214824&view=rev
Log:
[PECOFF] Fix /include option in .drectve section.

/INCLUDE arguments passed as command line options are handled in the
same way as Unix -u. All option values are converted to an undefined
symbol and added to a dummy input file, so that the specified symbols
are resolved.

One tricky thing on Windows is that the option is also allowed to
appear in the object file's directive section. At the time when
it's being read, all (regular) command line options have already
been processed. We cannot add undefined atoms to the dummy file
anymore.

Previously, we added such /INCLUDE to a set that has already been
processed. As a result the options were ignored.

This patch fixes the issue. Now, /INCLUDE symbols in the directive
section are handled as real undefined symbol in the COFF file.
We create an undefined symbol for each /INCLUDE argument and add
it to the file being parsed.

Added:
    lld/trunk/test/pecoff/Inputs/drectve2.obj.yaml
Modified:
    lld/trunk/include/lld/Driver/Driver.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
    lld/trunk/test/pecoff/drectve.test

Modified: lld/trunk/include/lld/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/Driver.h?rev=214824&r1=214823&r2=214824&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/Driver.h (original)
+++ lld/trunk/include/lld/Driver/Driver.h Mon Aug  4 18:48:57 2014
@@ -24,6 +24,7 @@
 #include "llvm/Support/raw_ostream.h"
 
 #include <memory>
+#include <set>
 #include <vector>
 
 namespace lld {
@@ -112,7 +113,8 @@ public:
   /// Returns true iff there was an error.
   static bool parse(int argc, const char *argv[], PECOFFLinkingContext &info,
                     raw_ostream &diagnostics = llvm::errs(),
-                    bool isDirective = false);
+                    bool isDirective = false,
+                    std::set<StringRef> *undefinedSymbols = nullptr);
 
 private:
   WinLinkDriver() LLVM_DELETED_FUNCTION;

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=214824&r1=214823&r2=214824&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Mon Aug  4 18:48:57 2014
@@ -811,7 +811,8 @@ bool WinLinkDriver::linkPECOFF(int argc,
 
 bool WinLinkDriver::parse(int argc, const char *argv[],
                           PECOFFLinkingContext &ctx, raw_ostream &diag,
-                          bool isReadingDirectiveSection) {
+                          bool isReadingDirectiveSection,
+                          std::set<StringRef> *undefinedSymbols) {
   // Parse may be called from multiple threads simultaneously to parse .drectve
   // sections. This function is not thread-safe because it mutates the context
   // object. So acquire the lock.
@@ -1183,9 +1184,15 @@ bool WinLinkDriver::parse(int argc, cons
       break;
     }
 
-    case OPT_incl:
-      ctx.addInitialUndefinedSymbol(ctx.allocate(inputArg->getValue()));
+    case OPT_incl: {
+      StringRef sym = ctx.allocate(inputArg->getValue());
+      if (isReadingDirectiveSection) {
+        undefinedSymbols->insert(sym);
+      } else {
+        ctx.addInitialUndefinedSymbol(sym);
+      }
       break;
+    }
 
     case OPT_noentry:
       ctx.setHasEntry(false);

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=214824&r1=214823&r2=214824&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Mon Aug  4 18:48:57 2014
@@ -92,6 +92,10 @@ public:
     _definedAtoms._atoms.push_back(atom);
   }
 
+  void addUndefinedSymbol(StringRef sym) {
+    _undefinedAtoms._atoms.push_back(new (_alloc) COFFUndefinedAtom(*this, sym));
+  }
+
   mutable llvm::BumpPtrAllocator _alloc;
 
 private:
@@ -954,10 +958,15 @@ public:
     if (ec)
       return ec;
 
+    // The set to contain the symbols specified as arguments of
+    // /INCLUDE option.
+    std::set<StringRef> undefinedSymbols;
+
     // Interpret .drectve section if the section has contents.
     StringRef directives = file->getLinkerDirectives();
     if (!directives.empty())
-      if (std::error_code ec = handleDirectiveSection(directives))
+      if (std::error_code ec = handleDirectiveSection(
+              directives, &undefinedSymbols))
         return ec;
 
     if (std::error_code ec = file->parse())
@@ -980,6 +989,12 @@ public:
     // function iterate over defined atoms and create alias atoms if needed.
     createAlternateNameAtoms(*file);
 
+    for (StringRef sym : undefinedSymbols) {
+      file->addUndefinedSymbol(sym);
+      if (_ctx.deadStrip())
+        _ctx.addDeadStripRoot(sym);
+    }
+
     result.push_back(std::move(file));
     return std::error_code();
   }
@@ -991,7 +1006,8 @@ private:
   //
   // The section mainly contains /defaultlib (-l in Unix), but can contain any
   // options as long as they are valid.
-  std::error_code handleDirectiveSection(StringRef directives) const {
+  std::error_code handleDirectiveSection(StringRef directives,
+                                         std::set<StringRef> *undefinedSymbols) const {
     DEBUG(llvm::dbgs() << ".drectve: " << directives << "\n");
 
     // Split the string into tokens, as the shell would do for argv.
@@ -1007,7 +1023,8 @@ private:
     std::string errorMessage;
     llvm::raw_string_ostream stream(errorMessage);
     bool parseFailed = !WinLinkDriver::parse(argc, argv, _ctx, stream,
-                                             /*isDirective*/ true);
+                                             /*isDirective*/ true,
+                                             undefinedSymbols);
     stream.flush();
     // Print error message if error.
     if (parseFailed) {

Added: lld/trunk/test/pecoff/Inputs/drectve2.obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/drectve2.obj.yaml?rev=214824&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/drectve2.obj.yaml (added)
+++ lld/trunk/test/pecoff/Inputs/drectve2.obj.yaml Mon Aug  4 18:48:57 2014
@@ -0,0 +1,45 @@
+---
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     558BEC56FF15000000008B0D000000008B3103F0FF150000000003C65E5DC3
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       2147483648
+    SectionData:     2f696e636c7564653a666f6f00
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          31
+      NumberOfRelocations: 3
+      NumberOfLinenumbers: 0
+      CheckSum:        3595596940
+      Number:          0
+  - Name:            _main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            .drectve
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          13
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+...

Modified: lld/trunk/test/pecoff/drectve.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/drectve.test?rev=214824&r1=214823&r2=214824&view=diff
==============================================================================
--- lld/trunk/test/pecoff/drectve.test (original)
+++ lld/trunk/test/pecoff/drectve.test Mon Aug  4 18:48:57 2014
@@ -22,3 +22,11 @@ IMPORT-NEXT:        1  fn
 IMPORT-NEXT:        1
 
 ERROR-NOT: foo
+
+
+# drectve2.obj contains "/include:foo".
+# RUN: yaml2obj %p/Inputs/drectve2.obj.yaml > %t2.obj
+# RUN: not lld -flavor link /out:%t2.exe /entry:main -- %t2.obj >& %t2.log
+# RUN: FileCheck -check-prefix=UNDEF %s < %t2.log
+
+UNDEF: Undefined symbol: {{.*}}: foo





More information about the llvm-commits mailing list