[lld] r240837 - COFF: Fix delay-import tables.
Rui Ueyama
ruiu at google.com
Fri Jun 26 14:40:16 PDT 2015
Author: ruiu
Date: Fri Jun 26 16:40:15 2015
New Revision: 240837
URL: http://llvm.org/viewvc/llvm-project?rev=240837&view=rev
Log:
COFF: Fix delay-import tables.
There were a few issues with the previous delay-import tables.
- "Attribute" field should have been 1 instead of 0.
(I don't know the meaning of this field, though.)
- LEA and CALL operands had wrong addresses.
- Address tables are in .didat (which is read-only).
They should have been in .data.
Modified:
lld/trunk/COFF/DLL.cpp
lld/trunk/COFF/DLL.h
lld/trunk/COFF/Writer.cpp
lld/trunk/test/COFF/delayimports.test
Modified: lld/trunk/COFF/DLL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DLL.cpp?rev=240837&r1=240836&r2=240837&view=diff
==============================================================================
--- lld/trunk/COFF/DLL.cpp (original)
+++ lld/trunk/COFF/DLL.cpp Fri Jun 26 16:40:15 2015
@@ -228,6 +228,7 @@ public:
void writeTo(uint8_t *Buf) override {
auto *E = (delay_import_directory_table_entry *)(Buf + FileOff);
+ E->Attributes = 1;
E->Name = DLLName->getRVA();
E->ModuleHandle = ModuleHandle->getRVA();
E->DelayImportAddressTable = AddressTab->getRVA();
@@ -272,15 +273,14 @@ static const uint8_t Thunk[] = {
// A chunk for the delay import thunk.
class ThunkChunk : public Chunk {
public:
- ThunkChunk(Defined *I, Defined *H) : Imp(I), Helper(H) {}
-
+ ThunkChunk(Defined *I, Chunk *D, Defined *H) : Imp(I), Desc(D), Helper(H) {}
size_t getSize() const override { return sizeof(Thunk); }
void writeTo(uint8_t *Buf) override {
memcpy(Buf + FileOff, Thunk, sizeof(Thunk));
- write32le(Buf + FileOff + 36, Imp->getRVA());
- write32le(Buf + FileOff + 43, Desc->getRVA());
- write32le(Buf + FileOff + 48, Helper->getRVA());
+ write32le(Buf + FileOff + 36, Imp->getRVA() - RVA - 40);
+ write32le(Buf + FileOff + 43, Desc->getRVA() - RVA - 47);
+ write32le(Buf + FileOff + 48, Helper->getRVA() - RVA - 52);
}
Defined *Imp = nullptr;
@@ -288,14 +288,10 @@ public:
Defined *Helper = nullptr;
};
-std::vector<Chunk *> DelayLoadContents::getChunks(Defined *H) {
- Helper = H;
- create();
+std::vector<Chunk *> DelayLoadContents::getChunks() {
std::vector<Chunk *> V;
for (std::unique_ptr<Chunk> &C : Dirs)
V.push_back(C.get());
- for (std::unique_ptr<Chunk> &C : Addresses)
- V.push_back(C.get());
for (std::unique_ptr<Chunk> &C : Names)
V.push_back(C.get());
for (std::unique_ptr<Chunk> &C : HintNames)
@@ -307,11 +303,34 @@ std::vector<Chunk *> DelayLoadContents::
return V;
}
+std::vector<Chunk *> DelayLoadContents::getDataChunks() {
+ std::vector<Chunk *> V;
+ for (std::unique_ptr<Chunk> &C : ModuleHandles)
+ V.push_back(C.get());
+ for (std::unique_ptr<Chunk> &C : Addresses)
+ V.push_back(C.get());
+ return V;
+}
+
uint64_t DelayLoadContents::getDirSize() {
return Dirs.size() * sizeof(delay_import_directory_table_entry);
}
-void DelayLoadContents::create() {
+// A chunk for the import descriptor table.
+class DelayAddressChunk : public Chunk {
+public:
+ explicit DelayAddressChunk(Chunk *C) : Thunk(C) {}
+ size_t getSize() const override { return 8; }
+
+ void writeTo(uint8_t *Buf) override {
+ write64le(Buf + FileOff, Thunk->getRVA() + Config->ImageBase);
+ }
+
+ Chunk *Thunk;
+};
+
+void DelayLoadContents::create(Defined *H) {
+ Helper = H;
std::map<StringRef, std::vector<DefinedImportData *>> Map =
binImports(Imports);
@@ -320,11 +339,15 @@ void DelayLoadContents::create() {
StringRef Name = P.first;
std::vector<DefinedImportData *> &Syms = P.second;
+ // Create the delay import table header.
+ if (!DLLNames.count(Name))
+ DLLNames[Name] = make_unique<StringChunk>(Name);
+ auto Dir = make_unique<DelayDirectoryChunk>(DLLNames[Name].get());
+
size_t Base = Addresses.size();
for (DefinedImportData *S : Syms) {
- auto T = make_unique<ThunkChunk>(S, Helper);
- auto A = make_unique<LookupChunk>(T.get());
- T->Desc = A.get();
+ auto T = make_unique<ThunkChunk>(S, Dir.get(), Helper);
+ auto A = make_unique<DelayAddressChunk>(T.get());
Addresses.push_back(std::move(A));
Thunks.push_back(std::move(T));
auto C =
@@ -333,8 +356,8 @@ void DelayLoadContents::create() {
HintNames.push_back(std::move(C));
}
// Terminate with null values.
- Addresses.push_back(make_unique<NullChunk>(LookupChunkSize));
- Names.push_back(make_unique<NullChunk>(LookupChunkSize));
+ Addresses.push_back(make_unique<NullChunk>(8));
+ Names.push_back(make_unique<NullChunk>(8));
for (int I = 0, E = Syms.size(); I < E; ++I)
Syms[I]->setLocation(Addresses[Base + I].get());
@@ -342,10 +365,7 @@ void DelayLoadContents::create() {
MH->setAlign(8);
ModuleHandles.push_back(std::unique_ptr<Chunk>(MH));
- // Create the delay import table header.
- if (!DLLNames.count(Name))
- DLLNames[Name] = make_unique<StringChunk>(Name);
- auto Dir = make_unique<DelayDirectoryChunk>(DLLNames[Name].get());
+ // Fill the delay import table header fields.
Dir->ModuleHandle = MH;
Dir->AddressTab = Addresses[Base].get();
Dir->NameTab = Names[Base].get();
Modified: lld/trunk/COFF/DLL.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DLL.h?rev=240837&r1=240836&r2=240837&view=diff
==============================================================================
--- lld/trunk/COFF/DLL.h (original)
+++ lld/trunk/COFF/DLL.h Fri Jun 26 16:40:15 2015
@@ -48,15 +48,15 @@ class DelayLoadContents {
public:
void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
bool empty() { return Imports.empty(); }
- std::vector<Chunk *> getChunks(Defined *Helper);
- std::vector<std::unique_ptr<Chunk>> &getDataChunks() { return ModuleHandles; }
+ void create(Defined *Helper);
+ std::vector<Chunk *> getChunks();
+ std::vector<Chunk *> getDataChunks();
std::vector<std::unique_ptr<Chunk>> &getCodeChunks() { return Thunks; }
uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
uint64_t getDirSize();
private:
- void create();
Defined *Helper;
std::vector<DefinedImportData *> Imports;
std::vector<std::unique_ptr<Chunk>> Dirs;
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=240837&r1=240836&r2=240837&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Fri Jun 26 16:40:15 2015
@@ -203,15 +203,16 @@ void Writer::createImportTables() {
Sec->addChunk(C);
}
if (!DelayIdata.empty()) {
+ DelayIdata.create(Symtab->find("__delayLoadHelper2"));
OutputSection *Sec = createSection(".didat");
- for (Chunk *C : DelayIdata.getChunks(Symtab->find("__delayLoadHelper2")))
+ for (Chunk *C : DelayIdata.getChunks())
+ Sec->addChunk(C);
+ Sec = createSection(".data");
+ for (Chunk *C : DelayIdata.getDataChunks())
Sec->addChunk(C);
Sec = createSection(".text");
for (std::unique_ptr<Chunk> &C : DelayIdata.getCodeChunks())
Sec->addChunk(C.get());
- Sec = createSection(".data");
- for (std::unique_ptr<Chunk> &C : DelayIdata.getDataChunks())
- Sec->addChunk(C.get());
}
}
Modified: lld/trunk/test/COFF/delayimports.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/delayimports.test?rev=240837&r1=240836&r2=240837&view=diff
==============================================================================
--- lld/trunk/test/COFF/delayimports.test (original)
+++ lld/trunk/test/COFF/delayimports.test Fri Jun 26 16:40:15 2015
@@ -5,22 +5,22 @@
CHECK: DelayImport {
CHECK-NEXT: Name: std64.dll
-CHECK-NEXT: Attributes: 0x0
+CHECK-NEXT: Attributes: 0x1
CHECK-NEXT: ModuleHandle: 0x1018
-CHECK-NEXT: ImportAddressTable: 0x3040
-CHECK-NEXT: ImportNameTable: 0x3060
+CHECK-NEXT: ImportAddressTable: 0x1020
+CHECK-NEXT: ImportNameTable: 0x3040
CHECK-NEXT: BoundDelayImportTable: 0x0
CHECK-NEXT: UnloadDelayImportTable: 0x0
CHECK-NEXT: Import {
CHECK-NEXT: Symbol: ExitProcess (0)
-CHECK-NEXT: Address: 0x2066
+CHECK-NEXT: Address: 0x140002066
CHECK-NEXT: }
CHECK-NEXT: Import {
CHECK-NEXT: Symbol: (50)
-CHECK-NEXT: Address: 0x20BD
+CHECK-NEXT: Address: 0x1400020BD
CHECK-NEXT: }
CHECK-NEXT: Import {
CHECK-NEXT: Symbol: MessageBoxA (1)
-CHECK-NEXT: Address: 0x2114
+CHECK-NEXT: Address: 0x140002114
CHECK-NEXT: }
CHECK-NEXT: }
More information about the llvm-commits
mailing list