[lld] r312386 - COFF: handle multiply defined symbols with different storage

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 1 15:12:10 PDT 2017


Author: compnerd
Date: Fri Sep  1 15:12:10 2017
New Revision: 312386

URL: http://llvm.org/viewvc/llvm-project?rev=312386&view=rev
Log:
COFF: handle multiply defined symbols with different storage

If a symbol is locally defined and is DLL imported in another
translation unit, and the object with the locally defined version is
loaded prior to the imported version, then the linker will fail to
resolve the definition of the thunk and return the locally defined
symbol.  This will then be attempted to be cast to an import thunk,
which will clearly fail.

Only return the thunk if the symbol is inserted or a thunk is created.
Otherwise, report a duplication error.

Added:
    lld/trunk/test/COFF/Inputs/alpha.ll
    lld/trunk/test/COFF/Inputs/beta.ll
    lld/trunk/test/COFF/Inputs/gamma.ll
    lld/trunk/test/COFF/duplicate.test
Modified:
    lld/trunk/COFF/InputFiles.cpp
    lld/trunk/COFF/SymbolTable.cpp

Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=312386&r1=312385&r2=312386&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Fri Sep  1 15:12:10 2017
@@ -355,19 +355,19 @@ void ImportFile::parse() {
   this->Hdr = Hdr;
   ExternalName = ExtName;
 
-  ImpSym = cast<DefinedImportData>(
-      Symtab->addImportData(ImpName, this)->body());
+  if (Symbol *S = Symtab->addImportData(ImpName, this))
+    ImpSym = cast<DefinedImportData>(S->body());
+
   if (Hdr->getType() == llvm::COFF::IMPORT_CONST)
-    ConstSym =
-        cast<DefinedImportData>(Symtab->addImportData(Name, this)->body());
+    if (Symbol *S = Symtab->addImportData(Name, this))
+      ConstSym = cast<DefinedImportData>(S->body());
 
   // If type is function, we need to create a thunk which jump to an
   // address pointed by the __imp_ symbol. (This allows you to call
   // DLL functions just like regular non-DLL functions.)
-  if (Hdr->getType() != llvm::COFF::IMPORT_CODE)
-    return;
-  ThunkSym = cast<DefinedImportThunk>(
-      Symtab->addImportThunk(Name, ImpSym, Hdr->Machine)->body());
+  if (Hdr->getType() == llvm::COFF::IMPORT_CODE)
+    if (Symbol *S = Symtab->addImportThunk(Name, ImpSym, Hdr->Machine))
+      ThunkSym = cast<DefinedImportThunk>(S->body());
 }
 
 void BitcodeFile::parse() {

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=312386&r1=312385&r2=312386&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Fri Sep  1 15:12:10 2017
@@ -274,11 +274,13 @@ Symbol *SymbolTable::addImportData(Strin
   bool WasInserted;
   std::tie(S, WasInserted) = insert(N);
   S->IsUsedInRegularObj = true;
-  if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+  if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) {
     replaceBody<DefinedImportData>(S, N, F);
-  else if (!isa<DefinedCOFF>(S->body()))
-    reportDuplicate(S, nullptr);
-  return S;
+    return S;
+  }
+
+  reportDuplicate(S, F);
+  return nullptr;
 }
 
 Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,
@@ -287,11 +289,13 @@ Symbol *SymbolTable::addImportThunk(Stri
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
   S->IsUsedInRegularObj = true;
-  if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+  if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) {
     replaceBody<DefinedImportThunk>(S, Name, ID, Machine);
-  else if (!isa<DefinedCOFF>(S->body()))
-    reportDuplicate(S, nullptr);
-  return S;
+    return S;
+  }
+
+  reportDuplicate(S, ID->File);
+  return nullptr;
 }
 
 std::vector<Chunk *> SymbolTable::getChunks() {

Added: lld/trunk/test/COFF/Inputs/alpha.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/alpha.ll?rev=312386&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/alpha.ll (added)
+++ lld/trunk/test/COFF/Inputs/alpha.ll Fri Sep  1 15:12:10 2017
@@ -0,0 +1,9 @@
+define void @_DllMainCRTStartup() {
+entry:
+  ret void
+}
+
+define dllexport void @f() local_unnamed_addr {
+entry:
+  ret void
+}

Added: lld/trunk/test/COFF/Inputs/beta.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/beta.ll?rev=312386&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/beta.ll (added)
+++ lld/trunk/test/COFF/Inputs/beta.ll Fri Sep  1 15:12:10 2017
@@ -0,0 +1,7 @@
+declare dllimport void @f() local_unnamed_addr
+
+define void @g() local_unnamed_addr {
+entry:
+  tail call void @f()
+  ret void
+}

Added: lld/trunk/test/COFF/Inputs/gamma.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/gamma.ll?rev=312386&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/gamma.ll (added)
+++ lld/trunk/test/COFF/Inputs/gamma.ll Fri Sep  1 15:12:10 2017
@@ -0,0 +1,14 @@
+
+declare void @f() local_unnamed_addr
+
+define void @__imp_f() local_unnamed_addr {
+entry:
+  ret void
+}
+
+define void @mainCRTStartup() local_unnamed_addr {
+entry:
+  tail call void @f()
+  ret void
+}
+

Added: lld/trunk/test/COFF/duplicate.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/duplicate.test?rev=312386&view=auto
==============================================================================
--- lld/trunk/test/COFF/duplicate.test (added)
+++ lld/trunk/test/COFF/duplicate.test Fri Sep  1 15:12:10 2017
@@ -0,0 +1,12 @@
+RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o alpha.obj %S/Inputs/alpha.ll
+RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o beta.obj %S/Inputs/beta.ll
+RUN: lld-link /out:alpha.dll /dll alpha.obj /implib:alpha.lib
+RUN: not lld-link /out:beta.dll /dll alpha.obj beta.obj alpha.lib 2>&1 | FileCheck %s -check-prefix CHECK-ALPHA
+
+CHECK-ALPHA: error: duplicate symbol: f in {{.*}}alpha.obj and in alpha.dll
+
+RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o gamma.obj %S/Inputs/gamma.ll
+RUN: not lld-link /out:gamma.exe /subsystem:console /entry:mainCRTStartup gamma.obj alpha.lib 2>&1 | FileCheck %s -check-prefix CHECK-GAMMA
+
+CHECK-GAMMA: error: duplicate symbol: __imp_f in {{.*}}gamma.obj and in alpha.dll
+




More information about the llvm-commits mailing list