Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lld/COFF
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-06-27 00:40:15 +0300
committerRui Ueyama <ruiu@google.com>2015-06-27 00:40:15 +0300
commit382dc96e29d989cb30407230c70cb3eeac8b11d2 (patch)
tree67c5681d7bddb0b34c2d5226b3e76191ac50d2e8 /lld/COFF
parenta3c6f0048cbb703da2c1ee3a7f40d134c68f861c (diff)
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. llvm-svn: 240837
Diffstat (limited to 'lld/COFF')
-rw-r--r--lld/COFF/DLL.cpp60
-rw-r--r--lld/COFF/DLL.h6
-rw-r--r--lld/COFF/Writer.cpp9
3 files changed, 48 insertions, 27 deletions
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index 188674874df0..9d5eb817220a 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -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::getChunks(Defined *H) {
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();
diff --git a/lld/COFF/DLL.h b/lld/COFF/DLL.h
index ac55366c5a59..f0f596974789 100644
--- a/lld/COFF/DLL.h
+++ b/lld/COFF/DLL.h
@@ -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;
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index fb8005b25607..81a9b2425527 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -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());
}
}