forked from OSchip/llvm-project
Merge IAT and ILT.
Previously, LLD-produced executables had IAT (Import Address Table) and ILT (Import Lookup Table) as separate chunks of data, although their contents are identical. My interpretation of the COFF spec when I wrote the COFF linker is that they need to be separate tables even though they are the same. But Peter found that the Windows loader is fine with executables in which IAT and ILT are merged. This is a patch to merge IAT and ILT. I confirmed that an lld-link self-hosted with this patch works fine. Fixes https://bugs.llvm.org/show_bug.cgi?id=33064 Differential Revision: https://reviews.llvm.org/D33326 llvm-svn: 303374
This commit is contained in:
parent
f4f62003f4
commit
9fbfd76fe3
|
@ -100,13 +100,17 @@ public:
|
|||
|
||||
void writeTo(uint8_t *Buf) const override {
|
||||
auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
|
||||
E->ImportLookupTableRVA = LookupTab->getRVA();
|
||||
E->NameRVA = DLLName->getRVA();
|
||||
|
||||
// The import descriptor table contains two pointers to
|
||||
// the tables describing dllimported symbols. But the
|
||||
// Windows loader actually uses only one. So we create
|
||||
// only one table and set both fields to its address.
|
||||
E->ImportLookupTableRVA = AddressTab->getRVA();
|
||||
E->ImportAddressTableRVA = AddressTab->getRVA();
|
||||
}
|
||||
|
||||
Chunk *DLLName;
|
||||
Chunk *LookupTab;
|
||||
Chunk *AddressTab;
|
||||
};
|
||||
|
||||
|
@ -388,7 +392,6 @@ std::vector<Chunk *> IdataContents::getChunks() {
|
|||
// Add each type in the correct order.
|
||||
std::vector<Chunk *> V;
|
||||
V.insert(V.end(), Dirs.begin(), Dirs.end());
|
||||
V.insert(V.end(), Lookups.begin(), Lookups.end());
|
||||
V.insert(V.end(), Addresses.begin(), Addresses.end());
|
||||
V.insert(V.end(), Hints.begin(), Hints.end());
|
||||
V.insert(V.end(), DLLNames.begin(), DLLNames.end());
|
||||
|
@ -404,21 +407,18 @@ void IdataContents::create() {
|
|||
// we need to create HintName chunks to store the names.
|
||||
// If they don't (if they are import-by-ordinals), we store only
|
||||
// ordinal values to the table.
|
||||
size_t Base = Lookups.size();
|
||||
size_t Base = Addresses.size();
|
||||
for (DefinedImportData *S : Syms) {
|
||||
uint16_t Ord = S->getOrdinal();
|
||||
if (S->getExternalName().empty()) {
|
||||
Lookups.push_back(make<OrdinalOnlyChunk>(Ord));
|
||||
Addresses.push_back(make<OrdinalOnlyChunk>(Ord));
|
||||
continue;
|
||||
}
|
||||
auto *C = make<HintNameChunk>(S->getExternalName(), Ord);
|
||||
Lookups.push_back(make<LookupChunk>(C));
|
||||
Addresses.push_back(make<LookupChunk>(C));
|
||||
Hints.push_back(C);
|
||||
}
|
||||
// Terminate with null values.
|
||||
Lookups.push_back(make<NullChunk>(ptrSize()));
|
||||
Addresses.push_back(make<NullChunk>(ptrSize()));
|
||||
|
||||
for (int I = 0, E = Syms.size(); I < E; ++I)
|
||||
|
@ -427,7 +427,6 @@ void IdataContents::create() {
|
|||
// Create the import table header.
|
||||
DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
|
||||
auto *Dir = make<ImportDirectoryChunk>(DLLNames.back());
|
||||
Dir->LookupTab = Lookups[Base];
|
||||
Dir->AddressTab = Addresses[Base];
|
||||
Dirs.push_back(Dir);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ private:
|
|||
|
||||
std::vector<DefinedImportData *> Imports;
|
||||
std::vector<Chunk *> Dirs;
|
||||
std::vector<Chunk *> Lookups;
|
||||
std::vector<Chunk *> Addresses;
|
||||
std::vector<Chunk *> Hints;
|
||||
std::vector<Chunk *> DLLNames;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# CHECK: Import {
|
||||
# CHECK: Name: library.dll
|
||||
# CHECK: ImportLookupTableRVA: 0x2028
|
||||
# CHECK: ImportAddressTableRVA: 0x2030
|
||||
# CHECK: ImportAddressTableRVA: 0x2028
|
||||
# CHECK: Symbol: function (0)
|
||||
# CHECK: }
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ HEADER-NEXT: LoadConfigTableRVA: 0x0
|
|||
HEADER-NEXT: LoadConfigTableSize: 0x0
|
||||
HEADER-NEXT: BoundImportRVA: 0x0
|
||||
HEADER-NEXT: BoundImportSize: 0x0
|
||||
HEADER-NEXT: IATRVA: 0x3034
|
||||
HEADER-NEXT: IATRVA: 0x3028
|
||||
HEADER-NEXT: IATSize: 0xC
|
||||
HEADER-NEXT: DelayImportDescriptorRVA: 0x0
|
||||
HEADER-NEXT: DelayImportDescriptorSize: 0x0
|
||||
|
@ -113,7 +113,7 @@ IMPORTS: AddressSize: 32bit
|
|||
IMPORTS: Import {
|
||||
IMPORTS: Name: std32.dll
|
||||
IMPORTS: ImportLookupTableRVA: 0x3028
|
||||
IMPORTS: ImportAddressTableRVA: 0x3034
|
||||
IMPORTS: ImportAddressTableRVA: 0x3028
|
||||
IMPORTS: Symbol: ExitProcess (0)
|
||||
IMPORTS: Symbol: MessageBoxA (1)
|
||||
IMPORTS: }
|
||||
|
|
|
@ -21,14 +21,14 @@ TEXT-NEXT: callq 60
|
|||
TEXT-NEXT: movl $0, %ecx
|
||||
TEXT-NEXT: callq 18
|
||||
TEXT-NEXT: callq 29
|
||||
TEXT: jmpq *4098(%rip)
|
||||
TEXT: jmpq *4090(%rip)
|
||||
TEXT: jmpq *4082(%rip)
|
||||
TEXT: jmpq *4066(%rip)
|
||||
TEXT: jmpq *4058(%rip)
|
||||
TEXT: jmpq *4050(%rip)
|
||||
|
||||
IMPORT: Import {
|
||||
IMPORT-NEXT: Name: std64.dll
|
||||
IMPORT-NEXT: ImportLookupTableRVA: 0x3028
|
||||
IMPORT-NEXT: ImportAddressTableRVA: 0x3048
|
||||
IMPORT-NEXT: ImportAddressTableRVA: 0x3028
|
||||
IMPORT-NEXT: Symbol: ExitProcess (0)
|
||||
IMPORT-NEXT: Symbol: (50)
|
||||
IMPORT-NEXT: Symbol: MessageBoxA (1)
|
||||
|
|
Loading…
Reference in New Issue