forked from OSchip/llvm-project
COFF: Fix export symbol names for x86.
I don't fully understand the rationale behind the name mangling scheme used for the DLL export table and the import library. Why only leading "_" is dropped for the import library while both "_" and "@" are dropped from DLL symbol table? But this seems to be what MSVC linker does. llvm-svn: 243490
This commit is contained in:
parent
7651dd8359
commit
9420dee328
|
@ -34,8 +34,10 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
|
|||
|
||||
// Represents an /export option.
|
||||
struct Export {
|
||||
StringRef Name;
|
||||
StringRef ExtName;
|
||||
StringRef Name; // N in /export:N or /export:E=N
|
||||
StringRef ExtName; // E in /export:E=N
|
||||
StringRef ExtDLLName; // Symbol name written to a DLL export table
|
||||
StringRef ExtLibName; // Symbol name written to a import library
|
||||
Undefined *Sym = nullptr;
|
||||
uint16_t Ordinal = 0;
|
||||
bool Noname = false;
|
||||
|
|
|
@ -535,7 +535,7 @@ EdataContents::EdataContents() {
|
|||
std::vector<Chunk *> Names;
|
||||
for (Export &E : Config->Exports)
|
||||
if (!E.Noname)
|
||||
Names.push_back(new StringChunk(E.ExtName));
|
||||
Names.push_back(new StringChunk(E.ExtDLLName));
|
||||
auto *NameTab = new NamePointersChunk(Names);
|
||||
auto *OrdinalTab = new ExportOrdinalChunk(Names.size());
|
||||
auto *Dir = new ExportDirectoryChunk(MaxOrdinal, Names.size(), DLLName,
|
||||
|
|
|
@ -425,12 +425,19 @@ std::error_code fixupExports() {
|
|||
}
|
||||
|
||||
for (Export &E : Config->Exports) {
|
||||
if (!E.ExtName.empty())
|
||||
if (!E.ExtName.empty()) {
|
||||
E.ExtDLLName = E.ExtName;
|
||||
E.ExtLibName = E.ExtName;
|
||||
continue;
|
||||
}
|
||||
StringRef S = E.Sym->repl()->getName();
|
||||
if (Config->Machine == I386 && S.startswith("_"))
|
||||
S = S.substr(1);
|
||||
E.ExtName = S;
|
||||
if (Config->Machine == I386 && S.startswith("_")) {
|
||||
E.ExtDLLName = S.substr(1).split('@').first;
|
||||
E.ExtLibName = S.substr(1);
|
||||
continue;
|
||||
}
|
||||
E.ExtDLLName = S;
|
||||
E.ExtLibName = S;
|
||||
}
|
||||
|
||||
// Uniquefy by name.
|
||||
|
@ -452,9 +459,10 @@ std::error_code fixupExports() {
|
|||
Config->Exports = std::move(V);
|
||||
|
||||
// Sort by name.
|
||||
std::sort(
|
||||
Config->Exports.begin(), Config->Exports.end(),
|
||||
[](const Export &A, const Export &B) { return A.ExtName < B.ExtName; });
|
||||
std::sort(Config->Exports.begin(), Config->Exports.end(),
|
||||
[](const Export &A, const Export &B) {
|
||||
return A.ExtDLLName < B.ExtDLLName;
|
||||
});
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
|
@ -528,7 +536,7 @@ static std::string createModuleDefinitionFile() {
|
|||
OS << "LIBRARY \"" << llvm::sys::path::filename(Config->OutputFile) << "\"\n"
|
||||
<< "EXPORTS\n";
|
||||
for (Export &E : Config->Exports) {
|
||||
OS << " " << E.ExtName;
|
||||
OS << " " << E.ExtLibName;
|
||||
if (E.Ordinal > 0)
|
||||
OS << " @" << E.Ordinal;
|
||||
if (E.Noname)
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
---
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_I386
|
||||
Characteristics: []
|
||||
sections:
|
||||
- Name: .text
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: B800000000506800000000680000000050E80000000050E800000000
|
||||
- Name: .drectve
|
||||
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
|
||||
Alignment: 2147483648
|
||||
SectionData: 2f6578706f72743a5f6578706f7274666e3300 # /export:_exportfn3
|
||||
symbols:
|
||||
- Name: .text
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 28
|
||||
NumberOfRelocations: 4
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: __DllMainCRTStartup@12
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: _exportfn1
|
||||
Value: 8
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: _exportfn2
|
||||
Value: 16
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: _exportfn3
|
||||
Value: 16
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: '?mangled@@YAHXZ'
|
||||
Value: 16
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
|
@ -1,74 +1,132 @@
|
|||
# RUN: yaml2obj < %p/Inputs/export32.yaml > %t.obj
|
||||
# RUN: yaml2obj < %s > %t.obj
|
||||
#
|
||||
# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2
|
||||
# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
|
||||
|
||||
CHECK1: Export Table:
|
||||
CHECK1: DLL name: export32.test.tmp.dll
|
||||
CHECK1: Ordinal RVA Name
|
||||
CHECK1-NEXT: 0 0
|
||||
CHECK1-NEXT: 1 0x1008 exportfn1
|
||||
CHECK1-NEXT: 2 0x1010 exportfn2
|
||||
# CHECK1: Export Table:
|
||||
# CHECK1: DLL name: export32.test.tmp.dll
|
||||
# CHECK1: Ordinal RVA Name
|
||||
# CHECK1-NEXT: 0 0
|
||||
# CHECK1-NEXT: 1 0x1008 exportfn1
|
||||
# CHECK1-NEXT: 2 0x1010 exportfn2
|
||||
|
||||
# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5 \
|
||||
# RUN: /export:exportfn2 /export:mangled
|
||||
# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s
|
||||
|
||||
CHECK2: Export Table:
|
||||
CHECK2: DLL name: export32.test.tmp.dll
|
||||
CHECK2: Ordinal RVA Name
|
||||
CHECK2-NEXT: 0 0
|
||||
CHECK2-NEXT: 1 0
|
||||
CHECK2-NEXT: 2 0
|
||||
CHECK2-NEXT: 3 0
|
||||
CHECK2-NEXT: 4 0
|
||||
CHECK2-NEXT: 5 0x1008 exportfn1
|
||||
CHECK2-NEXT: 6 0x1010 ?mangled@@YAHXZ
|
||||
CHECK2-NEXT: 7 0x1010 exportfn2
|
||||
CHECK2-NEXT: 8 0x1010 exportfn3
|
||||
# CHECK2: Export Table:
|
||||
# CHECK2: DLL name: export32.test.tmp.dll
|
||||
# CHECK2: Ordinal RVA Name
|
||||
# CHECK2-NEXT: 0 0
|
||||
# CHECK2-NEXT: 1 0
|
||||
# CHECK2-NEXT: 2 0
|
||||
# CHECK2-NEXT: 3 0
|
||||
# CHECK2-NEXT: 4 0
|
||||
# CHECK2-NEXT: 5 0x1008 exportfn1
|
||||
# CHECK2-NEXT: 6 0x1010 ?mangled@@YAHXZ
|
||||
# CHECK2-NEXT: 7 0x1010 exportfn2
|
||||
# CHECK2-NEXT: 8 0x1010 exportfn3
|
||||
|
||||
# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2
|
||||
# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK3 %s
|
||||
|
||||
CHECK3: Export Table:
|
||||
CHECK3: DLL name: export32.test.tmp.dll
|
||||
CHECK3: Ordinal RVA Name
|
||||
CHECK3-NEXT: 0 0
|
||||
CHECK3-NEXT: 1 0
|
||||
CHECK3-NEXT: 2 0
|
||||
CHECK3-NEXT: 3 0
|
||||
CHECK3-NEXT: 4 0
|
||||
CHECK3-NEXT: 5 0x1008
|
||||
CHECK3-NEXT: 6 0x1010 exportfn2
|
||||
# CHECK3: Export Table:
|
||||
# CHECK3: DLL name: export32.test.tmp.dll
|
||||
# CHECK3: Ordinal RVA Name
|
||||
# CHECK3-NEXT: 0 0
|
||||
# CHECK3-NEXT: 1 0
|
||||
# CHECK3-NEXT: 2 0
|
||||
# CHECK3-NEXT: 3 0
|
||||
# CHECK3-NEXT: 4 0
|
||||
# CHECK3-NEXT: 5 0x1008
|
||||
# CHECK3-NEXT: 6 0x1010 exportfn2
|
||||
|
||||
# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2
|
||||
# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK4 %s
|
||||
|
||||
CHECK4: Export Table:
|
||||
CHECK4: DLL name: export32.test.tmp.dll
|
||||
CHECK4: Ordinal RVA Name
|
||||
CHECK4-NEXT: 0 0
|
||||
CHECK4-NEXT: 1 0x1010 exportfn3
|
||||
CHECK4-NEXT: 2 0x1008 f1
|
||||
CHECK4-NEXT: 3 0x1010 f2
|
||||
# CHECK4: Export Table:
|
||||
# CHECK4: DLL name: export32.test.tmp.dll
|
||||
# CHECK4: Ordinal RVA Name
|
||||
# CHECK4-NEXT: 0 0
|
||||
# CHECK4-NEXT: 1 0x1010 exportfn3
|
||||
# CHECK4-NEXT: 2 0x1008 f1
|
||||
# CHECK4-NEXT: 3 0x1010 f2
|
||||
|
||||
# RUN: echo "EXPORTS exportfn1 @3" > %t.def
|
||||
# RUN: echo "fn2=exportfn2 @2" >> %t.def
|
||||
# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /def:%t.def
|
||||
# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s
|
||||
|
||||
CHECK5: Export Table:
|
||||
CHECK5: DLL name: export32.test.tmp.dll
|
||||
CHECK5: Ordinal RVA Name
|
||||
CHECK5-NEXT: 0 0
|
||||
CHECK5-NEXT: 1 0
|
||||
CHECK5-NEXT: 2 0x1010 fn2
|
||||
CHECK5-NEXT: 3 0x1008 exportfn1
|
||||
CHECK5-NEXT: 4 0x1010 exportfn3
|
||||
# CHECK5: Export Table:
|
||||
# CHECK5: DLL name: export32.test.tmp.dll
|
||||
# CHECK5: Ordinal RVA Name
|
||||
# CHECK5-NEXT: 0 0
|
||||
# CHECK5-NEXT: 1 0
|
||||
# CHECK5-NEXT: 2 0x1010 fn2
|
||||
# CHECK5-NEXT: 3 0x1008 exportfn1
|
||||
# CHECK5-NEXT: 4 0x1010 exportfn3
|
||||
|
||||
# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
|
||||
# RUN: /export:exportfn1 /export:exportfn2,@5 >& %t.log
|
||||
# RUN: FileCheck -check-prefix=CHECK6 %s < %t.log
|
||||
|
||||
CHECK6: duplicate /export option: _exportfn2
|
||||
CHECK6-NOT: duplicate /export option: _exportfn1
|
||||
# CHECK6: duplicate /export option: _exportfn2
|
||||
# CHECK6-NOT: duplicate /export option: _exportfn1
|
||||
|
||||
---
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_I386
|
||||
Characteristics: []
|
||||
sections:
|
||||
- Name: .text
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: B800000000506800000000680000000050E80000000050E800000000
|
||||
- Name: .drectve
|
||||
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
|
||||
Alignment: 2147483648
|
||||
SectionData: 2f6578706f72743a5f6578706f7274666e3300 # /export:_exportfn3
|
||||
symbols:
|
||||
- Name: .text
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 28
|
||||
NumberOfRelocations: 4
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: __DllMainCRTStartup@12
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: _exportfn1
|
||||
Value: 8
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: _exportfn2@4
|
||||
Value: 16
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: _exportfn3
|
||||
Value: 16
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: '?mangled@@YAHXZ'
|
||||
Value: 16
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue