[lld] r240620 - COFF: Handle undefined symbols starting with __imp_ in a special way.
Rui Ueyama
ruiu at google.com
Wed Jun 24 19:21:44 PDT 2015
Author: ruiu
Date: Wed Jun 24 21:21:44 2015
New Revision: 240620
URL: http://llvm.org/viewvc/llvm-project?rev=240620&view=rev
Log:
COFF: Handle undefined symbols starting with __imp_ in a special way.
MSVC linker is able to link an object file created from the following code.
Note that __imp_hello is not defined anywhere.
void hello() { printf("Hello\n"); }
extern void (*__imp_hello)();
int main() { __imp_hello(); }
Function symbols exported from DLLs are automatically mangled by appending
__imp_ prefix, so they have two names (original one and with the prefix).
This "feature" seems to simulate that behavior even for non-DLL symbols.
This is in my opnion very odd feature. Even MSVC linker warns if you use this.
I'm adding that anyway for the sake of compatibiltiy.
Added:
lld/trunk/test/COFF/locally-imported.test
Modified:
lld/trunk/COFF/SymbolTable.cpp
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=240620&r1=240619&r2=240620&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Wed Jun 24 21:21:44 2015
@@ -70,17 +70,26 @@ bool SymbolTable::reportRemainingUndefin
auto *Undef = dyn_cast<Undefined>(Sym->Body);
if (!Undef)
continue;
+ StringRef Name = Undef->getName();
if (SymbolBody *Alias = Undef->getWeakAlias()) {
Sym->Body = Alias->getReplacement();
if (!isa<Defined>(Sym->Body)) {
// Aliases are yet another symbols pointed by other symbols
// that could also remain undefined.
- llvm::errs() << "undefined symbol: " << Undef->getName() << "\n";
+ llvm::errs() << "undefined symbol: " << Name << "\n";
Ret = true;
}
continue;
}
- llvm::errs() << "undefined symbol: " << Undef->getName() << "\n";
+ // If we can resolve a symbol by removing __imp_ prefix, do that.
+ // This odd rule is for compatibility with MSVC linker.
+ if (Name.startswith("__imp_")) {
+ if (Defined *Imp = find(Name.substr(strlen("__imp_")))) {
+ Sym->Body = Imp;
+ continue;
+ }
+ }
+ llvm::errs() << "undefined symbol: " << Name << "\n";
Ret = true;
}
return Ret;
Added: lld/trunk/test/COFF/locally-imported.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/locally-imported.test?rev=240620&view=auto
==============================================================================
--- lld/trunk/test/COFF/locally-imported.test (added)
+++ lld/trunk/test/COFF/locally-imported.test Wed Jun 24 21:21:44 2015
@@ -0,0 +1,41 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: lld -flavor link2 /out:%t.exe %t.obj
+
+# The linker automatically removes __imp_ prefix if it helps to resolve all symbols.
+
+---
+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
+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
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: mainCRTStartup
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __imp_mainCRTStartup
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
More information about the llvm-commits
mailing list