Skip to content

Commit

Permalink
Move symbol resolution code out of SymbolTable class.
Browse files Browse the repository at this point in the history
This is the last patch of the series of patches to make it possible to
resolve symbols without asking SymbolTable to do so.

The main point of this patch is the introduction of
`elf::resolveSymbol(Symbol *Old, Symbol *New)`. That function resolves
or merges given symbols by examining symbol types and call
replaceSymbol (which memcpy's New to Old) if necessary.

With the new function, we have now separated symbol resolution from
symbol lookup. If you already have a Symbol pointer, you can directly
resolve the symbol without asking SymbolTable to do that.

Now that the nice abstraction become available, I can start working on
performance improvement of the linker. As a starter, I'm thinking of
making --{start,end}-lib faster.

--{start,end}-lib is currently unnecessarily slow because it looks up
the symbol table twice for each symbol.

 - The first hash table lookup/insertion occurs when we instantiate a
   LazyObject file to insert LazyObject symbols.

 - The second hash table lookup/insertion occurs when we create an
   ObjFile from LazyObject file. That overwrites LazyObject symbols
   with Defined symbols.

I think it is not too hard to see how we can now eliminate the second
hash table lookup. We can keep LazyObject symbols in Step 1, and then
call elf::resolveSymbol() to do Step 2.

Differential Revision: https://reviews.llvm.org/D61898

llvm-svn: 360975
  • Loading branch information
rui314 authored and MrSidims committed May 24, 2019
1 parent e28cc8a commit 4280b42
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 182 deletions.
13 changes: 6 additions & 7 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1337,10 +1337,9 @@ static void replaceCommonSymbols() {
Bss->File = S->File;
Bss->Live = !Config->GcSections;
InputSections.push_back(Bss);

Defined New(S->File, S->getName(), S->Binding, S->StOther, S->Type,
/*Value=*/0, S->Size, Bss);
replaceSymbol(S, &New);
replaceSymbol(S, Defined{S->File, S->getName(), S->Binding, S->StOther,
S->Type,
/*Value=*/0, S->Size, Bss});
}
}

Expand All @@ -1355,8 +1354,8 @@ static void demoteSharedSymbols() {
continue;

bool Used = S->Used;
Undefined New(nullptr, S->getName(), STB_WEAK, S->StOther, S->Type);
replaceSymbol(S, &New);
replaceSymbol(
S, Undefined{nullptr, S->getName(), STB_WEAK, S->StOther, S->Type});
S->Used = Used;
}
}
Expand Down Expand Up @@ -1426,7 +1425,7 @@ static void findKeepUniqueSections(opt::InputArgList &Args) {
}

template <class ELFT> static Symbol *addUndefined(StringRef Name) {
return Symtab->addUndefined(
return Symtab->addSymbol(
Undefined{nullptr, Name, STB_GLOBAL, STV_DEFAULT, 0});
}

Expand Down
39 changes: 19 additions & 20 deletions lld/ELF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -911,12 +911,12 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {

switch (Sym->st_shndx) {
case SHN_UNDEF:
return Symtab->addUndefined(Undefined{this, Name, Binding, StOther, Type});
return Symtab->addSymbol(Undefined{this, Name, Binding, StOther, Type});
case SHN_COMMON:
if (Value == 0 || Value >= UINT32_MAX)
fatal(toString(this) + ": common symbol '" + Name +
"' has invalid alignment: " + Twine(Value));
return Symtab->addCommon(
return Symtab->addSymbol(
CommonSymbol{this, Name, Binding, StOther, Type, Value, Size});
}

Expand All @@ -927,9 +927,8 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
case STB_WEAK:
case STB_GNU_UNIQUE:
if (Sec == &InputSection::Discarded)
return Symtab->addUndefined(
Undefined{this, Name, Binding, StOther, Type});
return Symtab->addDefined(
return Symtab->addSymbol(Undefined{this, Name, Binding, StOther, Type});
return Symtab->addSymbol(
Defined{this, Name, Binding, StOther, Type, Value, Size, Sec});
}
}
Expand All @@ -940,7 +939,7 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)

void ArchiveFile::parse() {
for (const Archive::Symbol &Sym : File->symbols())
Symtab->addLazyArchive(LazyArchive{*this, Sym});
Symtab->addSymbol(LazyArchive{*this, Sym});
}

// Returns a buffer pointing to a member file containing a given symbol.
Expand Down Expand Up @@ -1141,7 +1140,7 @@ template <class ELFT> void SharedFile::parse() {
}

if (Sym.isUndefined()) {
Symbol *S = Symtab->addUndefined(
Symbol *S = Symtab->addSymbol(
Undefined{this, Name, Sym.getBinding(), Sym.st_other, Sym.getType()});
S->ExportDynamic = true;
continue;
Expand All @@ -1157,7 +1156,7 @@ template <class ELFT> void SharedFile::parse() {

uint32_t Alignment = getAlignment<ELFT>(Sections, Sym);
if (!(Versyms[I] & VERSYM_HIDDEN)) {
Symtab->addShared(SharedSymbol{*this, Name, Sym.getBinding(),
Symtab->addSymbol(SharedSymbol{*this, Name, Sym.getBinding(),
Sym.st_other, Sym.getType(), Sym.st_value,
Sym.st_size, Alignment, Idx});
}
Expand All @@ -1179,7 +1178,7 @@ template <class ELFT> void SharedFile::parse() {
reinterpret_cast<const Elf_Verdef *>(Verdefs[Idx])->getAux()->vda_name;
VersionedNameBuffer.clear();
Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
Symtab->addShared(SharedSymbol{*this, Saver.save(Name), Sym.getBinding(),
Symtab->addSymbol(SharedSymbol{*this, Saver.save(Name), Sym.getBinding(),
Sym.st_other, Sym.getType(), Sym.st_value,
Sym.st_size, Alignment, Idx});
}
Expand Down Expand Up @@ -1281,18 +1280,18 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
Undefined New(&F, Name, Binding, Visibility, Type);
if (CanOmitFromDynSym)
New.ExportDynamic = false;
return Symtab->addUndefined(New);
return Symtab->addSymbol(New);
}

if (ObjSym.isCommon())
return Symtab->addCommon(
return Symtab->addSymbol(
CommonSymbol{&F, Name, Binding, Visibility, STT_OBJECT,
ObjSym.getCommonAlignment(), ObjSym.getCommonSize()});

Defined New(&F, Name, Binding, Visibility, Type, 0, 0, nullptr);
if (CanOmitFromDynSym)
New.ExportDynamic = false;
return Symtab->addDefined(New);
return Symtab->addSymbol(New);
}

template <class ELFT>
Expand Down Expand Up @@ -1350,12 +1349,12 @@ void BinaryFile::parse() {
if (!isAlnum(S[I]))
S[I] = '_';

Symtab->addDefined(Defined{nullptr, Saver.save(S + "_start"), STB_GLOBAL,
STV_DEFAULT, STT_OBJECT, 0, 0, Section});
Symtab->addDefined(Defined{nullptr, Saver.save(S + "_end"), STB_GLOBAL,
STV_DEFAULT, STT_OBJECT, Data.size(), 0, Section});
Symtab->addDefined(Defined{nullptr, Saver.save(S + "_size"), STB_GLOBAL,
STV_DEFAULT, STT_OBJECT, Data.size(), 0, nullptr});
Symtab->addSymbol(Defined{nullptr, Saver.save(S + "_start"), STB_GLOBAL,
STV_DEFAULT, STT_OBJECT, 0, 0, Section});
Symtab->addSymbol(Defined{nullptr, Saver.save(S + "_end"), STB_GLOBAL,
STV_DEFAULT, STT_OBJECT, Data.size(), 0, Section});
Symtab->addSymbol(Defined{nullptr, Saver.save(S + "_size"), STB_GLOBAL,
STV_DEFAULT, STT_OBJECT, Data.size(), 0, nullptr});
}

InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
Expand Down Expand Up @@ -1423,7 +1422,7 @@ template <class ELFT> void LazyObjFile::parse() {
for (const lto::InputFile::Symbol &Sym : Obj->symbols()) {
if (Sym.isUndefined())
continue;
Symtab->addLazyObject(LazyObject{*this, Saver.save(Sym.getName())});
Symtab->addSymbol(LazyObject{*this, Saver.save(Sym.getName())});
}
return;
}
Expand All @@ -1448,7 +1447,7 @@ template <class ELFT> void LazyObjFile::parse() {
for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal)) {
if (Sym.st_shndx == SHN_UNDEF)
continue;
Symtab->addLazyObject(
Symtab->addSymbol(
LazyObject{*this, CHECK(Sym.getName(StringTable), this)});
}
return;
Expand Down
8 changes: 2 additions & 6 deletions lld/ELF/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,6 @@ BitcodeCompiler::BitcodeCompiler() {

BitcodeCompiler::~BitcodeCompiler() = default;

static void undefine(Symbol *S) {
Undefined New(nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT, S->Type);
replaceSymbol(S, &New);
}

void BitcodeCompiler::add(BitcodeFile &F) {
lto::InputFile &Obj = *F.Obj;
bool IsExec = !Config->Shared && !Config->Relocatable;
Expand Down Expand Up @@ -201,7 +196,8 @@ void BitcodeCompiler::add(BitcodeFile &F) {
!(DR->Section == nullptr && (!Sym->File || Sym->File->isElf()));

if (R.Prevailing)
undefine(Sym);
replaceSymbol(Sym, Undefined{nullptr, Sym->getName(), STB_GLOBAL,
STV_DEFAULT, Sym->Type});

// We tell LTO to not apply interprocedural optimization for wrapped
// (with --wrap) symbols because otherwise LTO would inline them while
Expand Down
12 changes: 6 additions & 6 deletions lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, SymValue,
0, Sec);

Symbol *Sym = Symtab->insert(New);
Symtab->mergeProperties(Sym, New);
replaceSymbol(Sym, &New);
Symbol *Sym = Symtab->insert(Cmd->Name);
mergeSymbolProperties(Sym, New);
replaceSymbol(Sym, New);
Cmd->Sym = cast<Defined>(Sym);
}

Expand All @@ -203,9 +203,9 @@ static void declareSymbol(SymbolAssignment *Cmd) {
nullptr);

// We can't calculate final value right now.
Symbol *Sym = Symtab->insert(New);
Symtab->mergeProperties(Sym, New);
replaceSymbol(Sym, &New);
Symbol *Sym = Symtab->insert(Cmd->Name);
mergeSymbolProperties(Sym, New);
replaceSymbol(Sym, New);

Cmd->Sym = cast<Defined>(Sym);
Cmd->Provide = false;
Expand Down
5 changes: 2 additions & 3 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,9 +530,8 @@ static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
uint64_t Size) {
Symbol Old = Sym;

Defined New(Sym.File, Sym.getName(), Sym.Binding, Sym.StOther, Sym.Type,
Value, Size, Sec);
replaceSymbol(&Sym, &New);
replaceSymbol(&Sym, Defined{Sym.File, Sym.getName(), Sym.Binding, Sym.StOther,
Sym.Type, Value, Size, Sec});

Sym.PltIndex = Old.PltIndex;
Sym.GotIndex = Old.GotIndex;
Expand Down

0 comments on commit 4280b42

Please sign in to comment.