Skip to content

Commit

Permalink
Merge IAT and ILT.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rui314 committed May 18, 2017
1 parent f4f6200 commit 9fbfd76
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 16 deletions.
15 changes: 7 additions & 8 deletions lld/COFF/DLL.cpp
Expand Up @@ -100,13 +100,17 @@ class ImportDirectoryChunk : public Chunk {

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;
};

Expand Down Expand Up @@ -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());
Expand All @@ -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)
Expand All @@ -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);
}
Expand Down
1 change: 0 additions & 1 deletion lld/COFF/DLL.h
Expand Up @@ -36,7 +36,6 @@ class IdataContents {

std::vector<DefinedImportData *> Imports;
std::vector<Chunk *> Dirs;
std::vector<Chunk *> Lookups;
std::vector<Chunk *> Addresses;
std::vector<Chunk *> Hints;
std::vector<Chunk *> DLLNames;
Expand Down
2 changes: 1 addition & 1 deletion lld/test/COFF/armnt-imports.test
Expand Up @@ -6,7 +6,7 @@
# CHECK: Import {
# CHECK: Name: library.dll
# CHECK: ImportLookupTableRVA: 0x2028
# CHECK: ImportAddressTableRVA: 0x2030
# CHECK: ImportAddressTableRVA: 0x2028
# CHECK: Symbol: function (0)
# CHECK: }

Expand Down
4 changes: 2 additions & 2 deletions lld/test/COFF/hello32.test
Expand Up @@ -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
Expand Down Expand Up @@ -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: }
Expand Down
8 changes: 4 additions & 4 deletions lld/test/COFF/imports.test
Expand Up @@ -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)
Expand Down

0 comments on commit 9fbfd76

Please sign in to comment.