[lld] r241236 - COFF: Infer entry point as early as possible, but not too early.

Rui Ueyama ruiu at google.com
Wed Jul 1 20:15:15 PDT 2015


Author: ruiu
Date: Wed Jul  1 22:15:15 2015
New Revision: 241236

URL: http://llvm.org/viewvc/llvm-project?rev=241236&view=rev
Log:
COFF: Infer entry point as early as possible, but not too early.

On Windows, we have four different main functions, {w,}{main,WinMain}.
The linker has to choose a corresponding entry point function among
{w,}{main,WinMain}CRTStartup. These entry point functions are defined
in the standard library. The linker resolves one of them by looking at
which main function is defined and adding a corresponding undefined
symbol to the symbol table.

Object files containing entry point functions conflicts each other.
For example, we cannot resolve both mainCRTStartup and WinMainCRTStartup
because other symbols defined in the files conflict.

Previously, we inferred CRT function name at the very end of name
resolution. I found that that is sometimes too late. If the linker
already linked one of these four archive member objects, it's too late
to change the decision.

The right thing to do here is to infer entry point name after adding
all symbols from command line files and before adding any other files
(which are specified by directive sections). This patch does that.

Added:
    lld/trunk/test/COFF/entry-inference2.test
Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/COFF/SymbolTable.h

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=241236&r1=241235&r2=241236&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Wed Jul  1 22:15:15 2015
@@ -526,15 +526,11 @@ bool LinkerDriver::link(llvm::ArrayRef<c
     OwningMBs.push_back(std::move(MB)); // take ownership
   }
 
-  // Parse all input files and put all symbols to the symbol table.
-  // The symbol table will take care of name resolution.
+  // Read all input files given via the command line. Note that step()
+  // doesn't read files that are specified by directive sections.
   for (MemoryBufferRef MB : Inputs)
     Symtab.addFile(createFile(MB));
-  if (auto EC = Symtab.readObjects()) {
-    llvm::errs() << EC.message() << "\n";
-    return false;
-  }
-  if (auto EC = Symtab.run()) {
+  if (auto EC = Symtab.step()) {
     llvm::errs() << EC.message() << "\n";
     return false;
   }
@@ -548,9 +544,17 @@ bool LinkerDriver::link(llvm::ArrayRef<c
       return false;
     }
     Config->Entry = addUndefined(S);
+    if (Config->Verbose)
+      llvm::outs() << "Entry name inferred: " << S << "\n";
+  }
+
+  // Read as much files as we can.
+  if (auto EC = Symtab.run()) {
+    llvm::errs() << EC.message() << "\n";
+    return false;
   }
 
-  // Resolve auxiliary symbols until converge.
+  // Resolve auxiliary symbols until we get a convergence.
   // (Trying to resolve a symbol may trigger a Lazy symbol to load a new file.
   // A new file may contain a directive section to add new command line options.
   // That's why we have to repeat until converge.)

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=241236&r1=241235&r2=241236&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Wed Jul  1 22:15:15 2015
@@ -44,13 +44,20 @@ void SymbolTable::addFile(std::unique_pt
   }
 }
 
+std::error_code SymbolTable::step() {
+  if (queueEmpty())
+    return std::error_code();
+  if (auto EC = readObjects())
+    return EC;
+  if (auto EC = readArchives())
+    return EC;
+  return std::error_code();
+}
+
 std::error_code SymbolTable::run() {
-  while (!queueEmpty()) {
-    if (auto EC = readArchives())
+  while (!queueEmpty())
+    if (auto EC = step())
       return EC;
-    if (auto EC = readObjects())
-      return EC;
-  }
   return std::error_code();
 }
 

Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=241236&r1=241235&r2=241236&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Wed Jul  1 22:15:15 2015
@@ -43,9 +43,8 @@ class SymbolTable {
 public:
   SymbolTable();
   void addFile(std::unique_ptr<InputFile> File);
+  std::error_code step();
   std::error_code run();
-  std::error_code readArchives();
-  std::error_code readObjects();
   bool queueEmpty();
 
   // Print an error message on undefined symbols.
@@ -89,6 +88,9 @@ public:
   std::vector<Chunk *> LocalImportChunks;
 
 private:
+  std::error_code readArchives();
+  std::error_code readObjects();
+
   std::error_code addSymbol(SymbolBody *New);
   void addLazy(Lazy *New, std::vector<Symbol *> *Accum);
 

Added: lld/trunk/test/COFF/entry-inference2.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/entry-inference2.test?rev=241236&view=auto
==============================================================================
--- lld/trunk/test/COFF/entry-inference2.test (added)
+++ lld/trunk/test/COFF/entry-inference2.test Wed Jul  1 22:15:15 2015
@@ -0,0 +1,39 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: not lld -flavor link2 /out:%t.exe %t.obj /verbose > %t.log 2>&1
+# RUN: FileCheck %s < %t.log
+
+# CHECK: Entry name inferred: WinMainCRTStartup
+
+---
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     B82A000000C3
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       2147483648
+    SectionData:     2f616c7465726e6174656e616d653a6d61696e3d57696e4d61696e00  # /alternatename:main=WinMain
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          6
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            WinMain
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...





More information about the llvm-commits mailing list