summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-05-18 19:59:22 +0000
committerRui Ueyama <ruiu@google.com>2017-05-18 19:59:22 +0000
commit9fbfd76fe3061d9e02aaed704b439dcff750af1d (patch)
treea304dc0633da0acbac8caa0186d35cc48d44822e
parentf4f62003f452ff49894fc9fa44b93d7a1b1a8b19 (diff)
downloadbcm5719-llvm-9fbfd76fe3061d9e02aaed704b439dcff750af1d.tar.gz
bcm5719-llvm-9fbfd76fe3061d9e02aaed704b439dcff750af1d.zip
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
-rw-r--r--lld/COFF/DLL.cpp15
-rw-r--r--lld/COFF/DLL.h1
-rw-r--r--lld/test/COFF/armnt-imports.test2
-rw-r--r--lld/test/COFF/hello32.test4
-rw-r--r--lld/test/COFF/imports.test8
5 files changed, 14 insertions, 16 deletions
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index d76410b6747..3ac14e4ea2b 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -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);
}
diff --git a/lld/COFF/DLL.h b/lld/COFF/DLL.h
index ad312789edf..939771b3290 100644
--- a/lld/COFF/DLL.h
+++ b/lld/COFF/DLL.h
@@ -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;
diff --git a/lld/test/COFF/armnt-imports.test b/lld/test/COFF/armnt-imports.test
index 519886eb0c0..f0aaebd3f29 100644
--- a/lld/test/COFF/armnt-imports.test
+++ b/lld/test/COFF/armnt-imports.test
@@ -6,7 +6,7 @@
# CHECK: Import {
# CHECK: Name: library.dll
# CHECK: ImportLookupTableRVA: 0x2028
-# CHECK: ImportAddressTableRVA: 0x2030
+# CHECK: ImportAddressTableRVA: 0x2028
# CHECK: Symbol: function (0)
# CHECK: }
diff --git a/lld/test/COFF/hello32.test b/lld/test/COFF/hello32.test
index b7bc887d46e..e6117b990da 100644
--- a/lld/test/COFF/hello32.test
+++ b/lld/test/COFF/hello32.test
@@ -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: }
diff --git a/lld/test/COFF/imports.test b/lld/test/COFF/imports.test
index 584c24eb1b7..4df6d492ff2 100644
--- a/lld/test/COFF/imports.test
+++ b/lld/test/COFF/imports.test
@@ -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)
OpenPOWER on IntegriCloud