Skip to content

Commit

Permalink
COFF: New symbol table design.
Browse files Browse the repository at this point in the history
This ports the ELF linker's symbol table design, introduced in r268178,
to the COFF linker.

Differential Revision: http://reviews.llvm.org/D21166

llvm-svn: 289280
  • Loading branch information
pcc committed Dec 9, 2016
1 parent 8dc97a4 commit 79a5e6b
Show file tree
Hide file tree
Showing 19 changed files with 465 additions and 542 deletions.
4 changes: 2 additions & 2 deletions lld/COFF/Chunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
// Apply relocations.
for (const coff_relocation &Rel : Relocs) {
uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex)->repl();
SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
Defined *Sym = cast<Defined>(Body);
uint64_t P = RVA + Rel.VirtualAddress;
switch (Config->Machine) {
Expand Down Expand Up @@ -203,7 +203,7 @@ void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
uint8_t Ty = getBaserelType(Rel);
if (Ty == IMAGE_REL_BASED_ABSOLUTE)
continue;
SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex)->repl();
SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
if (isa<DefinedAbsolute>(Body))
continue;
Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
Expand Down
1 change: 0 additions & 1 deletion lld/COFF/Chunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ using llvm::object::COFFSymbolRef;
using llvm::object::SectionRef;
using llvm::object::coff_relocation;
using llvm::object::coff_section;
using llvm::sys::fs::file_magic;

class Baserel;
class Defined;
Expand Down
15 changes: 8 additions & 7 deletions lld/COFF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ using llvm::StringRef;
class DefinedAbsolute;
class DefinedRelative;
class StringChunk;
class Undefined;
struct Symbol;
class SymbolBody;

// Short aliases.
static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
Expand All @@ -37,7 +38,7 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
struct Export {
StringRef Name; // N in /export:N or /export:E=N
StringRef ExtName; // E in /export:E=N
Undefined *Sym = nullptr;
SymbolBody *Sym = nullptr;
uint16_t Ordinal = 0;
bool Noname = false;
bool Data = false;
Expand Down Expand Up @@ -76,7 +77,7 @@ struct Configuration {
llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
bool Verbose = false;
WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
Undefined *Entry = nullptr;
SymbolBody *Entry = nullptr;
bool NoEntry = false;
std::string OutputFile;
bool DoGC = true;
Expand All @@ -89,7 +90,7 @@ struct Configuration {
StringRef PDBPath;

// Symbols in this set are considered as live by the garbage collector.
std::set<Undefined *> GCRoot;
std::set<SymbolBody *> GCRoot;

std::set<StringRef> NoDefaultLibs;
bool NoDefaultLibAll = false;
Expand All @@ -100,11 +101,11 @@ struct Configuration {
std::vector<Export> Exports;
std::set<std::string> DelayLoads;
std::map<std::string, int> DLLOrder;
Undefined *DelayLoadHelper = nullptr;
SymbolBody *DelayLoadHelper = nullptr;

// Used for SafeSEH.
DefinedRelative *SEHTable = nullptr;
DefinedAbsolute *SEHCount = nullptr;
Symbol *SEHTable = nullptr;
Symbol *SEHCount = nullptr;

// Used for /opt:lldlto=N
unsigned LTOOptLevel = 2;
Expand Down
2 changes: 1 addition & 1 deletion lld/COFF/DLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ class AddressTableChunk : public Chunk {
if (E.ForwardChunk) {
write32le(P, E.ForwardChunk->getRVA());
} else {
write32le(P, cast<Defined>(E.Sym->repl())->getRVA());
write32le(P, cast<Defined>(E.Sym)->getRVA());
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions lld/COFF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,10 @@ void LinkerDriver::addLibSearchPaths() {
}
}

Undefined *LinkerDriver::addUndefined(StringRef Name) {
Undefined *U = Symtab.addUndefined(Name);
Config->GCRoot.insert(U);
return U;
SymbolBody *LinkerDriver::addUndefined(StringRef Name) {
SymbolBody *B = Symtab.addUndefined(Name);
Config->GCRoot.insert(B);
return B;
}

// Symbol names are mangled by appending "_" prefix on x86.
Expand All @@ -232,7 +232,7 @@ StringRef LinkerDriver::findDefaultEntry() {
};
for (auto E : Entries) {
StringRef Entry = Symtab.findMangle(mangle(E[0]));
if (!Entry.empty() && !isa<Undefined>(Symtab.find(Entry)->Body))
if (!Entry.empty() && !isa<Undefined>(Symtab.find(Entry)->body()))
return mangle(E[1]);
}
return "";
Expand Down Expand Up @@ -715,7 +715,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Symbol *Sym = Symtab.find(From);
if (!Sym)
continue;
if (auto *U = dyn_cast<Undefined>(Sym->Body))
if (auto *U = dyn_cast<Undefined>(Sym->body()))
if (!U->WeakAlias)
U->WeakAlias = Symtab.addUndefined(To);
}
Expand All @@ -734,7 +734,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Symtab.addCombinedLTOObjects();

// Make sure we have resolved all symbols.
Symtab.reportRemainingUndefines(/*Resolve=*/true);
Symtab.reportRemainingUndefines();

// Windows specific -- if no /subsystem is given, we need to infer
// that from entry point name.
Expand Down
3 changes: 2 additions & 1 deletion lld/COFF/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class ArgParser {

class LinkerDriver {
public:
LinkerDriver() { coff::Symtab = &Symtab; }
void link(llvm::ArrayRef<const char *> Args);

// Used by the resolver to parse .drectve section contents.
Expand Down Expand Up @@ -86,7 +87,7 @@ class LinkerDriver {
std::vector<StringRef> SearchPaths;
std::set<std::string> VisitedFiles;

Undefined *addUndefined(StringRef Sym);
SymbolBody *addUndefined(StringRef Sym);
StringRef mangle(StringRef Sym);

// Windows specific -- "main" is not the only main function in Windows.
Expand Down
10 changes: 5 additions & 5 deletions lld/COFF/DriverUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,13 +510,13 @@ void fixupExports() {
}

for (Export &E : Config->Exports) {
SymbolBody *Sym = E.Sym;
if (!E.ForwardTo.empty()) {
E.SymbolName = E.Name;
} else if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) {
E.SymbolName = U->getName();
} else {
E.SymbolName = E.Sym->getName();
}
} else if (auto *U = dyn_cast<Undefined>(Sym))
if (U->WeakAlias)
Sym = U->WeakAlias;
E.SymbolName = Sym->getName();
}

for (Export &E : Config->Exports) {
Expand Down
8 changes: 4 additions & 4 deletions lld/COFF/ICF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) {
R1.VirtualAddress != R2.VirtualAddress) {
return false;
}
SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex)->repl();
SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex)->repl();
SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex);
SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex);
if (B1 == B2)
return true;
if (auto *D1 = dyn_cast<DefinedRegular>(B1))
Expand All @@ -141,8 +141,8 @@ bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) {
bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) {
// Compare relocations.
auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {
SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex)->repl();
SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex)->repl();
SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex);
SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex);
if (B1 == B2)
return true;
if (auto *D1 = dyn_cast<DefinedRegular>(B1))
Expand Down
Loading

0 comments on commit 79a5e6b

Please sign in to comment.