Index: lld/trunk/COFF/Chunks.cpp =================================================================== --- lld/trunk/COFF/Chunks.cpp +++ lld/trunk/COFF/Chunks.cpp @@ -529,8 +529,8 @@ void SectionChunk::getRuntimePseudoRelocs( std::vector &Res) { for (const coff_relocation &Rel : Relocs) { - auto *Target = dyn_cast_or_null( - File->getSymbol(Rel.SymbolTableIndex)); + auto *Target = + dyn_cast_or_null(File->getSymbol(Rel.SymbolTableIndex)); if (!Target || !Target->IsRuntimePseudoReloc) continue; int SizeInBits = getRuntimePseudoRelocSize(Rel.Type); Index: lld/trunk/COFF/SymbolTable.cpp =================================================================== --- lld/trunk/COFF/SymbolTable.cpp +++ lld/trunk/COFF/SymbolTable.cpp @@ -152,21 +152,33 @@ bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) { if (Name.startswith("__imp_")) return false; - DefinedImportData *Imp = - dyn_cast_or_null(find(("__imp_" + Name).str())); + Defined *Imp = dyn_cast_or_null(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(Sym)->IsRuntimePseudoReloc = true; + size_t ImpSize = 0; + if (isa(Imp)) { + log("Automatically importing " + Name + " from " + + cast(Imp)->getDLLName()); + ImpSize = sizeof(DefinedImportData); + } else if (isa(Imp)) { + log("Automatically importing " + Name + " from " + + toString(cast(Imp)->File)); + ImpSize = sizeof(DefinedRegular); + } else { + warn("unable to automatically import " + Name + " from " + Imp->getName() + + " from " + toString(cast(Imp)->File) + + "; unexpected symbol type"); + return false; + } + Sym->replaceKeepingName(Imp, ImpSize); + Sym->IsRuntimePseudoReloc = true; // There may exist symbols named .refptr. which only consist // of a single pointer to . If it turns out is @@ -181,7 +193,7 @@ 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; Index: lld/trunk/COFF/Symbols.h =================================================================== --- lld/trunk/COFF/Symbols.h +++ lld/trunk/COFF/Symbols.h @@ -80,7 +80,7 @@ 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 @@ /// 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 @@ uint16_t getOrdinal() { return File->Hdr->OrdinalHint; } ImportFile *File; - - bool IsRuntimePseudoReloc = false; }; // This class represents a symbol for a jump table entry which jumps Index: lld/trunk/test/COFF/Inputs/gnu-implib-data.s =================================================================== --- lld/trunk/test/COFF/Inputs/gnu-implib-data.s +++ lld/trunk/test/COFF/Inputs/gnu-implib-data.s @@ -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" Index: lld/trunk/test/COFF/autoimport-gnu-implib.s =================================================================== --- lld/trunk/test/COFF/autoimport-gnu-implib.s +++ lld/trunk/test/COFF/autoimport-gnu-implib.s @@ -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