summaryrefslogtreecommitdiff
path: root/COFF/DLL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'COFF/DLL.cpp')
-rw-r--r--COFF/DLL.cpp160
1 files changed, 68 insertions, 92 deletions
diff --git a/COFF/DLL.cpp b/COFF/DLL.cpp
index f93dc5cde44ca..3ac14e4ea2b0b 100644
--- a/COFF/DLL.cpp
+++ b/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;
};
@@ -136,9 +140,9 @@ binImports(const std::vector<DefinedImportData *> &Imports) {
M[Sym->getDLLName().lower()].push_back(Sym);
std::vector<std::vector<DefinedImportData *>> V;
- for (auto &P : M) {
+ for (auto &KV : M) {
// Sort symbols by name for each group.
- std::vector<DefinedImportData *> &Syms = P.second;
+ std::vector<DefinedImportData *> &Syms = KV.second;
std::sort(Syms.begin(), Syms.end(),
[](DefinedImportData *A, DefinedImportData *B) {
return A->getName() < B->getName();
@@ -383,21 +387,14 @@ uint64_t IdataContents::getIATSize() {
// See Microsoft PE/COFF spec 5.4 for details.
std::vector<Chunk *> IdataContents::getChunks() {
create();
- std::vector<Chunk *> V;
+
// The loader assumes a specific order of data.
// Add each type in the correct order.
- for (std::unique_ptr<Chunk> &C : Dirs)
- V.push_back(C.get());
- for (std::unique_ptr<Chunk> &C : Lookups)
- V.push_back(C.get());
- for (std::unique_ptr<Chunk> &C : Addresses)
- V.push_back(C.get());
- for (std::unique_ptr<Chunk> &C : Hints)
- V.push_back(C.get());
- for (auto &P : DLLNames) {
- std::unique_ptr<Chunk> &C = P.second;
- V.push_back(C.get());
- }
+ std::vector<Chunk *> V;
+ V.insert(V.end(), Dirs.begin(), Dirs.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());
return V;
}
@@ -406,65 +403,50 @@ void IdataContents::create() {
// Create .idata contents for each DLL.
for (std::vector<DefinedImportData *> &Syms : V) {
- StringRef Name = Syms[0]->getDLLName();
-
// Create lookup and address tables. If they have external names,
// 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_unique<OrdinalOnlyChunk>(Ord));
- Addresses.push_back(make_unique<OrdinalOnlyChunk>(Ord));
+ Addresses.push_back(make<OrdinalOnlyChunk>(Ord));
continue;
}
- auto C = make_unique<HintNameChunk>(S->getExternalName(), Ord);
- Lookups.push_back(make_unique<LookupChunk>(C.get()));
- Addresses.push_back(make_unique<LookupChunk>(C.get()));
- Hints.push_back(std::move(C));
+ auto *C = make<HintNameChunk>(S->getExternalName(), Ord);
+ Addresses.push_back(make<LookupChunk>(C));
+ Hints.push_back(C);
}
// Terminate with null values.
- Lookups.push_back(make_unique<NullChunk>(ptrSize()));
- Addresses.push_back(make_unique<NullChunk>(ptrSize()));
+ Addresses.push_back(make<NullChunk>(ptrSize()));
for (int I = 0, E = Syms.size(); I < E; ++I)
- Syms[I]->setLocation(Addresses[Base + I].get());
+ Syms[I]->setLocation(Addresses[Base + I]);
// Create the import table header.
- if (!DLLNames.count(Name))
- DLLNames[Name] = make_unique<StringChunk>(Name);
- auto Dir = make_unique<ImportDirectoryChunk>(DLLNames[Name].get());
- Dir->LookupTab = Lookups[Base].get();
- Dir->AddressTab = Addresses[Base].get();
- Dirs.push_back(std::move(Dir));
+ DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
+ auto *Dir = make<ImportDirectoryChunk>(DLLNames.back());
+ Dir->AddressTab = Addresses[Base];
+ Dirs.push_back(Dir);
}
// Add null terminator.
- Dirs.push_back(make_unique<NullChunk>(sizeof(ImportDirectoryTableEntry)));
+ Dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry)));
}
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 : Names)
- V.push_back(C.get());
- for (std::unique_ptr<Chunk> &C : HintNames)
- V.push_back(C.get());
- for (auto &P : DLLNames) {
- std::unique_ptr<Chunk> &C = P.second;
- V.push_back(C.get());
- }
+ V.insert(V.end(), Dirs.begin(), Dirs.end());
+ V.insert(V.end(), Names.begin(), Names.end());
+ V.insert(V.end(), HintNames.begin(), HintNames.end());
+ V.insert(V.end(), DLLNames.begin(), DLLNames.end());
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());
+ V.insert(V.end(), ModuleHandles.begin(), ModuleHandles.end());
+ V.insert(V.end(), Addresses.begin(), Addresses.end());
return V;
}
@@ -478,55 +460,51 @@ void DelayLoadContents::create(Defined *H) {
// Create .didat contents for each DLL.
for (std::vector<DefinedImportData *> &Syms : V) {
- StringRef Name = Syms[0]->getDLLName();
-
// Create the delay import table header.
- if (!DLLNames.count(Name))
- DLLNames[Name] = make_unique<StringChunk>(Name);
- auto Dir = make_unique<DelayDirectoryChunk>(DLLNames[Name].get());
+ DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
+ auto *Dir = make<DelayDirectoryChunk>(DLLNames.back());
size_t Base = Addresses.size();
for (DefinedImportData *S : Syms) {
- Chunk *T = newThunkChunk(S, Dir.get());
- auto A = make_unique<DelayAddressChunk>(T);
- Addresses.push_back(std::move(A));
- Thunks.push_back(std::unique_ptr<Chunk>(T));
+ Chunk *T = newThunkChunk(S, Dir);
+ auto *A = make<DelayAddressChunk>(T);
+ Addresses.push_back(A);
+ Thunks.push_back(T);
StringRef ExtName = S->getExternalName();
if (ExtName.empty()) {
- Names.push_back(make_unique<OrdinalOnlyChunk>(S->getOrdinal()));
+ Names.push_back(make<OrdinalOnlyChunk>(S->getOrdinal()));
} else {
- auto C = make_unique<HintNameChunk>(ExtName, 0);
- Names.push_back(make_unique<LookupChunk>(C.get()));
- HintNames.push_back(std::move(C));
+ auto *C = make<HintNameChunk>(ExtName, 0);
+ Names.push_back(make<LookupChunk>(C));
+ HintNames.push_back(C);
}
}
// Terminate with null values.
- Addresses.push_back(make_unique<NullChunk>(8));
- Names.push_back(make_unique<NullChunk>(8));
+ Addresses.push_back(make<NullChunk>(8));
+ Names.push_back(make<NullChunk>(8));
for (int I = 0, E = Syms.size(); I < E; ++I)
- Syms[I]->setLocation(Addresses[Base + I].get());
- auto *MH = new NullChunk(8);
+ Syms[I]->setLocation(Addresses[Base + I]);
+ auto *MH = make<NullChunk>(8);
MH->setAlign(8);
- ModuleHandles.push_back(std::unique_ptr<Chunk>(MH));
+ ModuleHandles.push_back(MH);
// Fill the delay import table header fields.
Dir->ModuleHandle = MH;
- Dir->AddressTab = Addresses[Base].get();
- Dir->NameTab = Names[Base].get();
- Dirs.push_back(std::move(Dir));
+ Dir->AddressTab = Addresses[Base];
+ Dir->NameTab = Names[Base];
+ Dirs.push_back(Dir);
}
// Add null terminator.
- Dirs.push_back(
- make_unique<NullChunk>(sizeof(delay_import_directory_table_entry)));
+ Dirs.push_back(make<NullChunk>(sizeof(delay_import_directory_table_entry)));
}
Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {
switch (Config->Machine) {
case AMD64:
- return new ThunkChunkX64(S, Dir, Helper);
+ return make<ThunkChunkX64>(S, Dir, Helper);
case I386:
- return new ThunkChunkX86(S, Dir, Helper);
+ return make<ThunkChunkX86>(S, Dir, Helper);
default:
llvm_unreachable("unsupported machine type");
}
@@ -537,34 +515,32 @@ EdataContents::EdataContents() {
for (Export &E : Config->Exports)
MaxOrdinal = std::max(MaxOrdinal, E.Ordinal);
- auto *DLLName = new StringChunk(sys::path::filename(Config->OutputFile));
- auto *AddressTab = new AddressTableChunk(MaxOrdinal);
+ auto *DLLName = make<StringChunk>(sys::path::filename(Config->OutputFile));
+ auto *AddressTab = make<AddressTableChunk>(MaxOrdinal);
std::vector<Chunk *> Names;
for (Export &E : Config->Exports)
if (!E.Noname)
- Names.push_back(new StringChunk(E.ExportName));
+ Names.push_back(make<StringChunk>(E.ExportName));
std::vector<Chunk *> Forwards;
for (Export &E : Config->Exports) {
if (E.ForwardTo.empty())
continue;
- E.ForwardChunk = new StringChunk(E.ForwardTo);
+ E.ForwardChunk = make<StringChunk>(E.ForwardTo);
Forwards.push_back(E.ForwardChunk);
}
- auto *NameTab = new NamePointersChunk(Names);
- auto *OrdinalTab = new ExportOrdinalChunk(Names.size());
- auto *Dir = new ExportDirectoryChunk(MaxOrdinal, Names.size(), DLLName,
- AddressTab, NameTab, OrdinalTab);
- Chunks.push_back(std::unique_ptr<Chunk>(Dir));
- Chunks.push_back(std::unique_ptr<Chunk>(DLLName));
- Chunks.push_back(std::unique_ptr<Chunk>(AddressTab));
- Chunks.push_back(std::unique_ptr<Chunk>(NameTab));
- Chunks.push_back(std::unique_ptr<Chunk>(OrdinalTab));
- for (Chunk *C : Names)
- Chunks.push_back(std::unique_ptr<Chunk>(C));
- for (Chunk *C : Forwards)
- Chunks.push_back(std::unique_ptr<Chunk>(C));
+ auto *NameTab = make<NamePointersChunk>(Names);
+ auto *OrdinalTab = make<ExportOrdinalChunk>(Names.size());
+ auto *Dir = make<ExportDirectoryChunk>(MaxOrdinal, Names.size(), DLLName,
+ AddressTab, NameTab, OrdinalTab);
+ Chunks.push_back(Dir);
+ Chunks.push_back(DLLName);
+ Chunks.push_back(AddressTab);
+ Chunks.push_back(NameTab);
+ Chunks.push_back(OrdinalTab);
+ Chunks.insert(Chunks.end(), Names.begin(), Names.end());
+ Chunks.insert(Chunks.end(), Forwards.begin(), Forwards.end());
}
} // namespace coff