mirror of
https://github.com/intel/llvm.git
synced 2026-01-25 01:07:04 +08:00
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.
llvm-svn: 240620
This commit is contained in:
@@ -70,17 +70,26 @@ bool SymbolTable::reportRemainingUndefines() {
|
||||
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;
|
||||
|
||||
41
lld/test/COFF/locally-imported.test
Normal file
41
lld/test/COFF/locally-imported.test
Normal file
@@ -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
|
||||
...
|
||||
Reference in New Issue
Block a user