[lld] r343069 - [COFF] Allow automatic dllimport from gnu import libraries

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 25 23:13:40 PDT 2018


Author: mstorsjo
Date: Tue Sep 25 23:13:39 2018
New Revision: 343069

URL: http://llvm.org/viewvc/llvm-project?rev=343069&view=rev
Log:
[COFF] Allow automatic dllimport from gnu import libraries

Don't assume that the IAT chunk will be a DefinedImportData, it can
just as well be a DefinedRegular for gnu import libraries.

Differential Revision: https://reviews.llvm.org/D52381

Added:
    lld/trunk/test/COFF/Inputs/gnu-implib-data.s
    lld/trunk/test/COFF/autoimport-gnu-implib.s
Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/COFF/Symbols.h

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=343069&r1=343068&r2=343069&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Tue Sep 25 23:13:39 2018
@@ -529,8 +529,8 @@ static int getRuntimePseudoRelocSize(uin
 void SectionChunk::getRuntimePseudoRelocs(
     std::vector<RuntimePseudoReloc> &Res) {
   for (const coff_relocation &Rel : Relocs) {
-    auto *Target = dyn_cast_or_null<DefinedImportData>(
-        File->getSymbol(Rel.SymbolTableIndex));
+    auto *Target =
+        dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
     if (!Target || !Target->IsRuntimePseudoReloc)
       continue;
     int SizeInBits = getRuntimePseudoRelocSize(Rel.Type);

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=343069&r1=343068&r2=343069&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Tue Sep 25 23:13:39 2018
@@ -152,21 +152,33 @@ void SymbolTable::loadMinGWAutomaticImpo
 bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) {
   if (Name.startswith("__imp_"))
     return false;
-  DefinedImportData *Imp =
-      dyn_cast_or_null<DefinedImportData>(find(("__imp_" + Name).str()));
+  Defined *Imp = dyn_cast_or_null<Defined>(find(("__imp_" + Name).str()));
   if (!Imp)
     return false;
 
-  log("Automatically importing " + Name + " from " + Imp->getDLLName());
-
   // Replace the reference directly to a variable with a reference
   // to the import address table instead. This obviously isn't right,
   // but we mark the symbol as IsRuntimePseudoReloc, and a later pass
   // will add runtime pseudo relocations for every relocation against
   // this Symbol. The runtime pseudo relocation framework expects the
   // reference itself to point at the IAT entry.
-  Sym->replaceKeepingName(Imp, sizeof(DefinedImportData));
-  cast<DefinedImportData>(Sym)->IsRuntimePseudoReloc = true;
+  size_t ImpSize = 0;
+  if (isa<DefinedImportData>(Imp)) {
+    log("Automatically importing " + Name + " from " +
+        cast<DefinedImportData>(Imp)->getDLLName());
+    ImpSize = sizeof(DefinedImportData);
+  } else if (isa<DefinedRegular>(Imp)) {
+    log("Automatically importing " + Name + " from " +
+        toString(cast<DefinedRegular>(Imp)->File));
+    ImpSize = sizeof(DefinedRegular);
+  } else {
+    warn("unable to automatically import " + Name + " from " + Imp->getName() +
+         " from " + toString(cast<DefinedRegular>(Imp)->File) +
+         "; unexpected symbol type");
+    return false;
+  }
+  Sym->replaceKeepingName(Imp, ImpSize);
+  Sym->IsRuntimePseudoReloc = true;
 
   // There may exist symbols named .refptr.<name> which only consist
   // of a single pointer to <name>. If it turns out <name> is
@@ -181,7 +193,7 @@ bool SymbolTable::handleMinGWAutomaticIm
     if (SC && SC->Relocs.size() == 1 && *SC->symbols().begin() == Sym) {
       log("Replacing .refptr." + Name + " with " + Imp->getName());
       Refptr->getChunk()->Live = false;
-      Refptr->replaceKeepingName(Imp, sizeof(DefinedImportData));
+      Refptr->replaceKeepingName(Imp, ImpSize);
     }
   }
   return true;

Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=343069&r1=343068&r2=343069&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Tue Sep 25 23:13:39 2018
@@ -80,7 +80,7 @@ protected:
   explicit Symbol(Kind K, StringRef N = "")
       : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
         WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
-        Name(N) {}
+        IsRuntimePseudoReloc(false), Name(N) {}
 
   const unsigned SymbolKind : 8;
   unsigned IsExternal : 1;
@@ -104,6 +104,8 @@ public:
   /// True if we've already added this symbol to the list of GC roots.
   unsigned IsGCRoot : 1;
 
+  unsigned IsRuntimePseudoReloc : 1;
+
 protected:
   StringRef Name;
 };
@@ -309,8 +311,6 @@ public:
   uint16_t getOrdinal() { return File->Hdr->OrdinalHint; }
 
   ImportFile *File;
-
-  bool IsRuntimePseudoReloc = false;
 };
 
 // This class represents a symbol for a jump table entry which jumps

Added: lld/trunk/test/COFF/Inputs/gnu-implib-data.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/gnu-implib-data.s?rev=343069&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/gnu-implib-data.s (added)
+++ lld/trunk/test/COFF/Inputs/gnu-implib-data.s Tue Sep 25 23:13:39 2018
@@ -0,0 +1,23 @@
+        .global         __imp_data
+
+        # The data that is emitted into .idata$7 here is isn't needed for
+        # the import data structures, but we need to emit something which
+        # produces a relocation against _head_test_lib, to pull in the
+        # header and trailer objects.
+
+        .section        .idata$7
+        .rva            _head_test_lib
+
+        .section        .idata$5
+__imp_data:
+        .rva            .Lhint_name
+        .long           0
+
+        .section        .idata$4
+        .rva            .Lhint_name
+        .long           0
+
+        .section        .idata$6
+.Lhint_name:
+        .short          0
+        .asciz          "data"

Added: lld/trunk/test/COFF/autoimport-gnu-implib.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/autoimport-gnu-implib.s?rev=343069&view=auto
==============================================================================
--- lld/trunk/test/COFF/autoimport-gnu-implib.s (added)
+++ lld/trunk/test/COFF/autoimport-gnu-implib.s Tue Sep 25 23:13:39 2018
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-head.s -filetype=obj -o %t-dabcdh.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-data.s -filetype=obj -o %t-dabcds00000.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %p/Inputs/gnu-implib-tail.s -filetype=obj -o %t-dabcdt.o
+# RUN: rm -f %t-implib.a
+# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-implib.a -verbose
+
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
+
+# IMPORTS: Import {
+# IMPORTS-NEXT: Name: foo.dll
+# IMPORTS-NEXT: ImportLookupTableRVA:
+# IMPORTS-NEXT: ImportAddressTableRVA:
+# IMPORTS-NEXT: Symbol: data (0)
+# IMPORTS-NEXT: }
+
+    .global main
+    .text
+main:
+    movl data(%rip), %eax
+    ret
+    .data




More information about the llvm-commits mailing list