Use make<> everywhere in COFF to make it consistent with ELF.

We've been using make<> to allocate new objects in ELF. We have
the same function in COFF, but we didn't use it widely due to
negligence. This patch uses the function in COFF to close the gap
between ELF and COFF.

llvm-svn: 303357
This commit is contained in:
Rui Ueyama 2017-05-18 17:03:49 +00:00
parent 06e3c74d83
commit 01f93335a0
9 changed files with 112 additions and 143 deletions

View File

@ -136,9 +136,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 +383,16 @@ 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(), Lookups.begin(), Lookups.end());
V.insert(V.end(), Addresses.begin(), Addresses.end());
V.insert(V.end(), Hints.begin(), Hints.end());
for (auto &KV : DLLNames)
V.push_back(KV.second);
return V;
}
@ -416,55 +411,48 @@ void IdataContents::create() {
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));
Lookups.push_back(make<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);
Lookups.push_back(make<LookupChunk>(C));
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()));
Lookups.push_back(make<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[Name] = make<StringChunk>(Name);
auto *Dir = make<ImportDirectoryChunk>(DLLNames[Name]);
Dir->LookupTab = Lookups[Base];
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());
for (auto &KV : DLLNames)
V.push_back(KV.second);
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;
}
@ -482,51 +470,50 @@ void DelayLoadContents::create(Defined *H) {
// 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[Name] = make<StringChunk>(Name);
auto *Dir = make<DelayDirectoryChunk>(DLLNames[Name]);
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 +524,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

View File

@ -35,11 +35,11 @@ private:
void create();
std::vector<DefinedImportData *> Imports;
std::vector<std::unique_ptr<Chunk>> Dirs;
std::vector<std::unique_ptr<Chunk>> Lookups;
std::vector<std::unique_ptr<Chunk>> Addresses;
std::vector<std::unique_ptr<Chunk>> Hints;
std::map<StringRef, std::unique_ptr<Chunk>> DLLNames;
std::vector<Chunk *> Dirs;
std::vector<Chunk *> Lookups;
std::vector<Chunk *> Addresses;
std::vector<Chunk *> Hints;
std::map<StringRef, Chunk *> DLLNames;
};
// Windows-specific.
@ -51,7 +51,7 @@ public:
void create(Defined *Helper);
std::vector<Chunk *> getChunks();
std::vector<Chunk *> getDataChunks();
std::vector<std::unique_ptr<Chunk>> &getCodeChunks() { return Thunks; }
ArrayRef<Chunk *> getCodeChunks() { return Thunks; }
uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
uint64_t getDirSize();
@ -61,13 +61,13 @@ private:
Defined *Helper;
std::vector<DefinedImportData *> Imports;
std::vector<std::unique_ptr<Chunk>> Dirs;
std::vector<std::unique_ptr<Chunk>> ModuleHandles;
std::vector<std::unique_ptr<Chunk>> Addresses;
std::vector<std::unique_ptr<Chunk>> Names;
std::vector<std::unique_ptr<Chunk>> HintNames;
std::vector<std::unique_ptr<Chunk>> Thunks;
std::map<StringRef, std::unique_ptr<Chunk>> DLLNames;
std::vector<Chunk *> Dirs;
std::vector<Chunk *> ModuleHandles;
std::vector<Chunk *> Addresses;
std::vector<Chunk *> Names;
std::vector<Chunk *> HintNames;
std::vector<Chunk *> Thunks;
std::map<StringRef, Chunk *> DLLNames;
};
// Windows-specific.
@ -75,7 +75,7 @@ private:
class EdataContents {
public:
EdataContents();
std::vector<std::unique_ptr<Chunk>> Chunks;
std::vector<Chunk *> Chunks;
};
} // namespace coff

View File

@ -97,12 +97,11 @@ static std::future<MBErrPair> createFutureForFile(std::string Path) {
MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) {
MemoryBufferRef MBRef = *MB;
OwningMBs.push_back(std::move(MB));
make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take ownership
if (Driver->Tar)
Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()),
MBRef.getBuffer());
return MBRef;
}

View File

@ -119,10 +119,6 @@ private:
void enqueueTask(std::function<void()> Task);
bool run();
// Driver is the owner of all opened files.
// InputFiles have MemoryBufferRefs to them.
std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs;
std::list<std::function<void()>> TaskQueue;
std::vector<StringRef> FilePaths;
std::vector<MemoryBufferRef> Resources;

View File

@ -43,7 +43,7 @@ namespace {
class Executor {
public:
explicit Executor(StringRef S) : Saver(Alloc), Prog(Saver.save(S)) {}
explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
void add(StringRef S) { Args.push_back(Saver.save(S)); }
void add(std::string &S) { Args.push_back(Saver.save(S)); }
void add(Twine S) { Args.push_back(Saver.save(S)); }
@ -67,8 +67,6 @@ public:
}
private:
BumpPtrAllocator Alloc;
StringSaver Saver;
StringRef Prog;
std::vector<StringRef> Args;
};

View File

@ -137,13 +137,13 @@ void ObjectFile::initializeChunks() {
// CodeView sections are stored to a different vector because they are
// not linked in the regular manner.
if (Name == ".debug" || Name.startswith(".debug$")) {
DebugChunks.push_back(new (Alloc) SectionChunk(this, Sec));
DebugChunks.push_back(make<SectionChunk>(this, Sec));
continue;
}
if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
continue;
auto *C = new (Alloc) SectionChunk(this, Sec);
auto *C = make<SectionChunk>(this, Sec);
Chunks.push_back(C);
SparseChunks[I] = C;
}
@ -200,7 +200,7 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
bool IsFirst) {
StringRef Name;
if (Sym.isCommon()) {
auto *C = new (Alloc) CommonChunk(Sym);
auto *C = make<CommonChunk>(Sym);
Chunks.push_back(C);
COFFObj->getSymbolName(Sym, Name);
Symbol *S =
@ -221,7 +221,7 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
if (Sym.isExternal())
return Symtab->addAbsolute(Name, Sym)->body();
else
return new (Alloc) DefinedAbsolute(Name, Sym);
return make<DefinedAbsolute>(Name, Sym);
}
int32_t SectionNumber = Sym.getSectionNumber();
if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
@ -258,8 +258,8 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
Symtab->addRegular(this, Name, SC->isCOMDAT(), Sym.getGeneric(), SC);
B = cast<DefinedRegular>(S->body());
} else
B = new (Alloc) DefinedRegular(this, /*Name*/ "", SC->isCOMDAT(),
/*IsExternal*/ false, Sym.getGeneric(), SC);
B = make<DefinedRegular>(this, /*Name*/ "", SC->isCOMDAT(),
/*IsExternal*/ false, Sym.getGeneric(), SC);
if (SC->isCOMDAT() && Sym.getValue() == 0 && !AuxP)
SC->setSymbol(B);
@ -301,8 +301,8 @@ void ImportFile::parse() {
fatal("broken import library");
// Read names and create an __imp_ symbol.
StringRef Name = StringAlloc.save(StringRef(Buf + sizeof(*Hdr)));
StringRef ImpName = StringAlloc.save("__imp_" + Name);
StringRef Name = Saver.save(StringRef(Buf + sizeof(*Hdr)));
StringRef ImpName = Saver.save("__imp_" + Name);
const char *NameStart = Buf + sizeof(coff_import_header) + Name.size() + 1;
DLLName = StringRef(NameStart);
StringRef ExtName;

View File

@ -130,7 +130,6 @@ private:
SymbolBody *createUndefined(COFFSymbolRef Sym);
std::unique_ptr<COFFObjectFile> COFFObj;
llvm::BumpPtrAllocator Alloc;
const coff_section *SXData = nullptr;
// List of all chunks defined by this file. This includes both section
@ -162,8 +161,7 @@ private:
// for details about the format.
class ImportFile : public InputFile {
public:
explicit ImportFile(MemoryBufferRef M)
: InputFile(ImportKind, M), StringAlloc(StringAllocAux) {}
explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind, M) {}
static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
DefinedImportData *ImpSym = nullptr;
@ -174,9 +172,6 @@ public:
private:
void parse() override;
llvm::BumpPtrAllocator StringAllocAux;
llvm::StringSaver StringAlloc;
public:
StringRef ExternalName;
const coff_import_header *Hdr;

View File

@ -15,7 +15,6 @@
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {

View File

@ -48,8 +48,7 @@ namespace {
class DebugDirectoryChunk : public Chunk {
public:
DebugDirectoryChunk(const std::vector<std::unique_ptr<Chunk>> &R)
: Records(R) {}
DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {}
size_t getSize() const override {
return Records.size() * sizeof(debug_directory);
@ -58,7 +57,7 @@ public:
void writeTo(uint8_t *B) const override {
auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
for (const std::unique_ptr<Chunk> &Record : Records) {
for (const Chunk *Record : Records) {
D->Characteristics = 0;
D->TimeDateStamp = 0;
D->MajorVersion = 0;
@ -74,7 +73,7 @@ public:
}
private:
const std::vector<std::unique_ptr<Chunk>> &Records;
const std::vector<Chunk *> &Records;
};
class CVDebugRecordChunk : public Chunk {
@ -142,10 +141,10 @@ private:
IdataContents Idata;
DelayLoadContents DelayIdata;
EdataContents Edata;
std::unique_ptr<SEHTableChunk> SEHTable;
SEHTableChunk *SEHTable = nullptr;
std::unique_ptr<Chunk> DebugDirectory;
std::vector<std::unique_ptr<Chunk>> DebugRecords;
Chunk *DebugDirectory = nullptr;
std::vector<Chunk *> DebugRecords;
CVDebugRecordChunk *BuildId = nullptr;
ArrayRef<uint8_t> SectionTable;
@ -153,8 +152,6 @@ private:
uint32_t PointerToSymbolTable = 0;
uint64_t SizeOfImage;
uint64_t SizeOfHeaders;
std::vector<std::unique_ptr<Chunk>> Chunks;
};
} // anonymous namespace
@ -324,19 +321,19 @@ void Writer::createMiscChunks() {
// Create Debug Information Chunks
if (Config->Debug) {
DebugDirectory = llvm::make_unique<DebugDirectoryChunk>(DebugRecords);
DebugDirectory = make<DebugDirectoryChunk>(DebugRecords);
// TODO(compnerd) create a coffgrp entry if DebugType::CV is not enabled
if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) {
auto Chunk = llvm::make_unique<CVDebugRecordChunk>();
auto *Chunk = make<CVDebugRecordChunk>();
BuildId = Chunk.get();
DebugRecords.push_back(std::move(Chunk));
BuildId = Chunk;
DebugRecords.push_back(Chunk);
}
RData->addChunk(DebugDirectory.get());
for (const std::unique_ptr<Chunk> &C : DebugRecords)
RData->addChunk(C.get());
RData->addChunk(DebugDirectory);
for (Chunk *C : DebugRecords)
RData->addChunk(C);
}
// Create SEH table. x86-only.
@ -352,8 +349,8 @@ void Writer::createMiscChunks() {
Handlers.insert(cast<Defined>(B));
}
SEHTable.reset(new SEHTableChunk(Handlers));
RData->addChunk(SEHTable.get());
SEHTable = make<SEHTableChunk>(Handlers);
RData->addChunk(SEHTable);
}
// Create .idata section for the DLL-imported symbol table.
@ -404,8 +401,8 @@ void Writer::createImportTables() {
for (Chunk *C : DelayIdata.getDataChunks())
Sec->addChunk(C);
Sec = createSection(".text");
for (std::unique_ptr<Chunk> &C : DelayIdata.getCodeChunks())
Sec->addChunk(C.get());
for (Chunk *C : DelayIdata.getCodeChunks())
Sec->addChunk(C);
}
}
@ -413,8 +410,8 @@ void Writer::createExportTable() {
if (Config->Exports.empty())
return;
OutputSection *Sec = createSection(".edata");
for (std::unique_ptr<Chunk> &C : Edata.Chunks)
Sec->addChunk(C.get());
for (Chunk *C : Edata.Chunks)
Sec->addChunk(C);
}
// The Windows loader doesn't seem to like empty sections,