[lld] r360838 - Simplify SymbolTable::add{Defined, Undefined, ...} functions.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Wed May 15 19:14:00 PDT 2019
Author: ruiu
Date: Wed May 15 19:14:00 2019
New Revision: 360838
URL: http://llvm.org/viewvc/llvm-project?rev=360838&view=rev
Log:
Simplify SymbolTable::add{Defined,Undefined,...} functions.
SymbolTable's add-family functions have lots of parameters because
when they have to create a new symbol, they forward given arguments
to Symbol's constructors. Therefore, the functions take at least as
many arguments as their corresponding constructors.
This patch simplifies the add-family functions. Now, the functions
take a symbol instead of arguments to construct a symbol. If there's
no existing symbol, a given symbol is memcpy'ed to the symbol table.
Otherwise, the functions attempt to merge the existing and a given
new symbol.
I also eliminated `CanOmitFromDynSym` parameter, so that the functions
take really one argument.
Symbol classes are trivially constructible, so looks like constructing
them to pass to add-family functions is as cheap as passing a lot of
arguments to the functions. A quick benchmark showed that this patch
seems performance-neutral.
This is a preparation for
http://lists.llvm.org/pipermail/llvm-dev/2019-April/131902.html
Differential Revision: https://reviews.llvm.org/D61855
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/LTO.cpp
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed May 15 19:14:00 2019
@@ -1329,14 +1329,14 @@ template <class ELFT> static void handle
// that point to a non-existent DSO.
static void demoteSharedSymbols() {
for (Symbol *Sym : Symtab->getSymbols()) {
- if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
- if (!S->getFile().IsNeeded) {
- bool Used = S->Used;
- replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
- S->Type);
- S->Used = Used;
- }
- }
+ auto *S = dyn_cast<SharedSymbol>(Sym);
+ if (!S || S->getFile().IsNeeded)
+ continue;
+
+ bool Used = S->Used;
+ Undefined New(nullptr, S->getName(), STB_WEAK, S->StOther, S->Type);
+ replaceSymbol(S, &New);
+ S->Used = Used;
}
}
@@ -1405,8 +1405,8 @@ static void findKeepUniqueSections(opt::
}
template <class ELFT> static Symbol *addUndefined(StringRef Name) {
- return Symtab->addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, 0, false,
- nullptr);
+ return Symtab->addUndefined<ELFT>(
+ Undefined{nullptr, Name, STB_GLOBAL, STV_DEFAULT, 0});
}
// The --wrap option is a feature to rename symbols so that you can write
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed May 15 19:14:00 2019
@@ -864,13 +864,12 @@ template <class ELFT> void ObjFile<ELFT>
}
template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
- int Binding = Sym->getBinding();
-
uint32_t SecIdx = getSectionIndex(*Sym);
if (SecIdx >= this->Sections.size())
fatal(toString(this) + ": invalid section index: " + Twine(SecIdx));
InputSectionBase *Sec = this->Sections[SecIdx];
+ uint8_t Binding = Sym->getBinding();
uint8_t StOther = Sym->st_other;
uint8_t Type = Sym->getType();
uint64_t Value = Sym->st_value;
@@ -886,7 +885,6 @@ template <class ELFT> Symbol *ObjFile<EL
StringRefZ Name = this->StringTable.data() + Sym->st_name;
if (Sym->st_shndx == SHN_UNDEF)
return make<Undefined>(this, Name, Binding, StOther, Type);
-
return make<Defined>(this, Name, Binding, StOther, Type, Value, Size, Sec);
}
@@ -894,26 +892,27 @@ template <class ELFT> Symbol *ObjFile<EL
switch (Sym->st_shndx) {
case SHN_UNDEF:
- return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
- /*CanOmitFromDynSym=*/false, this);
+ return Symtab->addUndefined<ELFT>(
+ 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(Name, Size, Value, Binding, StOther, Type, *this);
+ return Symtab->addCommon(
+ Defined{this, Name, Binding, StOther, Type, Value, Size, nullptr});
}
switch (Binding) {
default:
- fatal(toString(this) + ": unexpected binding: " + Twine(Binding));
+ fatal(toString(this) + ": unexpected binding: " + Twine((int)Binding));
case STB_GLOBAL:
case STB_WEAK:
case STB_GNU_UNIQUE:
if (Sec == &InputSection::Discarded)
- return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
- /*CanOmitFromDynSym=*/false, this);
- return Symtab->addDefined(Name, StOther, Type, Value, Size, Binding, Sec,
- this);
+ return Symtab->addUndefined<ELFT>(
+ Undefined{this, Name, Binding, StOther, Type});
+ return Symtab->addDefined(
+ Defined{this, Name, Binding, StOther, Type, Value, Size, Sec});
}
}
@@ -923,7 +922,7 @@ ArchiveFile::ArchiveFile(std::unique_ptr
template <class ELFT> void ArchiveFile::parse() {
for (const Archive::Symbol &Sym : File->symbols())
- Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym);
+ Symtab->addLazyArchive<ELFT>(LazyArchive{*this, Sym});
}
// Returns a buffer pointing to a member file containing a given symbol.
@@ -1124,9 +1123,8 @@ template <class ELFT> void SharedFile::p
}
if (Sym.isUndefined()) {
- Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(),
- Sym.st_other, Sym.getType(),
- /*CanOmitFromDynSym=*/false, this);
+ Symbol *S = Symtab->addUndefined<ELFT>(
+ Undefined{this, Name, Sym.getBinding(), Sym.st_other, Sym.getType()});
S->ExportDynamic = true;
continue;
}
@@ -1139,10 +1137,12 @@ template <class ELFT> void SharedFile::p
Name == "_gp_disp")
continue;
- uint64_t Alignment = getAlignment<ELFT>(Sections, Sym);
- if (!(Versyms[I] & VERSYM_HIDDEN))
- Symtab->addShared(Name, Sym.getBinding(), Sym.st_other, Sym.getType(),
- Sym.st_value, Sym.st_size, Alignment, Idx, this);
+ uint32_t Alignment = getAlignment<ELFT>(Sections, Sym);
+ if (!(Versyms[I] & VERSYM_HIDDEN)) {
+ Symtab->addShared(SharedSymbol{*this, Name, Sym.getBinding(),
+ Sym.st_other, Sym.getType(), Sym.st_value,
+ Sym.st_size, Alignment, Idx});
+ }
// Also add the symbol with the versioned name to handle undefined symbols
// with explicit versions.
@@ -1161,9 +1161,9 @@ template <class ELFT> void SharedFile::p
reinterpret_cast<const Elf_Verdef *>(Verdefs[Idx])->getAux()->vda_name;
VersionedNameBuffer.clear();
Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
- Symtab->addShared(Saver.save(Name), Sym.getBinding(), Sym.st_other,
- Sym.getType(), Sym.st_value, Sym.st_size, Alignment, Idx,
- this);
+ Symtab->addShared(SharedSymbol{*this, Saver.save(Name), Sym.getBinding(),
+ Sym.st_other, Sym.getType(), Sym.st_value,
+ Sym.st_size, Alignment, Idx});
}
}
@@ -1252,28 +1252,28 @@ static Symbol *createBitcodeSymbol(const
const lto::InputFile::Symbol &ObjSym,
BitcodeFile &F) {
StringRef Name = Saver.save(ObjSym.getName());
- uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
-
+ uint8_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE;
uint8_t Visibility = mapVisibility(ObjSym.getVisibility());
bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable();
int C = ObjSym.getComdatIndex();
- if (C != -1 && !KeptComdats[C])
- return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
- CanOmitFromDynSym, &F);
-
- if (ObjSym.isUndefined())
- return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
- CanOmitFromDynSym, &F);
+ if (ObjSym.isUndefined() || (C != -1 && !KeptComdats[C])) {
+ Undefined New(&F, Name, Binding, Visibility, Type);
+ if (CanOmitFromDynSym)
+ New.ExportDynamic = false;
+ return Symtab->addUndefined<ELFT>(New);
+ }
if (ObjSym.isCommon())
- return Symtab->addCommon(Name, ObjSym.getCommonSize(),
- ObjSym.getCommonAlignment(), Binding, Visibility,
- STT_OBJECT, F);
-
- return Symtab->addBitcode(Name, Binding, Visibility, Type, CanOmitFromDynSym,
- F);
+ return Symtab->addCommon(Defined{&F, Name, Binding, Visibility, STT_OBJECT,
+ ObjSym.getCommonAlignment(),
+ ObjSym.getCommonSize(), nullptr});
+
+ Defined New(&F, Name, Binding, Visibility, Type, 0, 0, nullptr);
+ if (CanOmitFromDynSym)
+ New.ExportDynamic = false;
+ return Symtab->addBitcode(New);
}
template <class ELFT>
@@ -1331,12 +1331,12 @@ void BinaryFile::parse() {
if (!isAlnum(S[I]))
S[I] = '_';
- Symtab->addDefined(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0,
- STB_GLOBAL, Section, nullptr);
- Symtab->addDefined(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
- Data.size(), 0, STB_GLOBAL, Section, nullptr);
- Symtab->addDefined(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
- Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
+ 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});
}
InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
@@ -1401,9 +1401,11 @@ template <class ELFT> void LazyObjFile::
if (isBitcode(this->MB)) {
std::unique_ptr<lto::InputFile> Obj =
CHECK(lto::InputFile::create(this->MB), this);
- for (const lto::InputFile::Symbol &Sym : Obj->symbols())
- if (!Sym.isUndefined())
- Symtab->addLazyObject<ELFT>(Saver.save(Sym.getName()), *this);
+ for (const lto::InputFile::Symbol &Sym : Obj->symbols()) {
+ if (Sym.isUndefined())
+ continue;
+ Symtab->addLazyObject<ELFT>(LazyObject{*this, Saver.save(Sym.getName())});
+ }
return;
}
@@ -1424,10 +1426,12 @@ template <class ELFT> void LazyObjFile::
StringRef StringTable =
CHECK(Obj.getStringTableForSymtab(Sec, Sections), this);
- for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal))
- if (Sym.st_shndx != SHN_UNDEF)
- Symtab->addLazyObject<ELFT>(CHECK(Sym.getName(StringTable), this),
- *this);
+ for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal)) {
+ if (Sym.st_shndx == SHN_UNDEF)
+ continue;
+ Symtab->addLazyObject<ELFT>(
+ LazyObject{*this, CHECK(Sym.getName(StringTable), this)});
+ }
return;
}
}
Modified: lld/trunk/ELF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.cpp (original)
+++ lld/trunk/ELF/LTO.cpp Wed May 15 19:14:00 2019
@@ -153,8 +153,8 @@ BitcodeCompiler::BitcodeCompiler() {
BitcodeCompiler::~BitcodeCompiler() = default;
static void undefine(Symbol *S) {
- replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT,
- S->Type);
+ Undefined New(nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT, S->Type);
+ replaceSymbol(S, &New);
}
void BitcodeCompiler::add(BitcodeFile &F) {
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed May 15 19:14:00 2019
@@ -166,13 +166,9 @@ void LinkerScript::addSymbol(SymbolAssig
return;
// Define a symbol.
- Symbol *Sym;
- uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
- std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
- /*CanOmitFromDynSym*/ false,
- /*File*/ nullptr);
ExprValue Value = Cmd->Expression();
SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
+ uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
// When this function is called, section addresses have not been
// fixed yet. So, we may or may not know the value of the RHS
@@ -187,8 +183,12 @@ void LinkerScript::addSymbol(SymbolAssig
// write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
uint64_t SymValue = Value.Sec ? 0 : Value.getValue();
- replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
- STT_NOTYPE, SymValue, 0, Sec);
+ Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, SymValue,
+ 0, Sec);
+
+ Symbol *Sym;
+ std::tie(Sym, std::ignore) = Symtab->insert(New);
+ replaceSymbol(Sym, &New);
Cmd->Sym = cast<Defined>(Sym);
}
@@ -198,14 +198,15 @@ static void declareSymbol(SymbolAssignme
if (!shouldDefineSym(Cmd))
return;
+ uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
+ Defined New(nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, 0, 0,
+ nullptr);
+
// We can't calculate final value right now.
Symbol *Sym;
- uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
- std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
- /*CanOmitFromDynSym*/ false,
- /*File*/ nullptr);
- replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
- STT_NOTYPE, 0, 0, nullptr);
+ std::tie(Sym, std::ignore) = Symtab->insert(New);
+ replaceSymbol(Sym, &New);
+
Cmd->Sym = cast<Defined>(Sym);
Cmd->Provide = false;
Sym->ScriptDefined = true;
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed May 15 19:14:00 2019
@@ -529,8 +529,11 @@ static SmallSet<SharedSymbol *, 4> getSy
static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
uint64_t Size) {
Symbol Old = Sym;
- replaceSymbol<Defined>(&Sym, Sym.File, Sym.getName(), Sym.Binding,
- Sym.StOther, Sym.Type, Value, Size, Sec);
+
+ Defined New(Sym.File, Sym.getName(), Sym.Binding, Sym.StOther, Sym.Type,
+ Value, Size, Sec);
+ replaceSymbol(&Sym, &New);
+
Sym.PltIndex = Old.PltIndex;
Sym.GotIndex = Old.GotIndex;
Sym.VerdefIndex = Old.VerdefIndex;
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed May 15 19:14:00 2019
@@ -86,14 +86,18 @@ static uint8_t getMinVisibility(uint8_t
return std::min(VA, VB);
}
-// Find an existing symbol or create and insert a new one.
-std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
+// Find an existing symbol or create and insert a new one, then apply the given
+// attributes.
+std::pair<Symbol *, bool> SymbolTable::insert(const Symbol &New) {
+ // Find an existing symbol or create and insert a new one.
+
// <name>@@<version> means the symbol is the default version. In that
// case <name>@@<version> will be used to resolve references to <name>.
//
// Since this is a hot path, the following string search code is
// optimized for speed. StringRef::find(char) is much faster than
// StringRef::find(StringRef).
+ StringRef Name = New.getName();
size_t Pos = Name.find('@');
if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@')
Name = Name.take_front(Pos);
@@ -109,70 +113,57 @@ std::pair<Symbol *, bool> SymbolTable::i
Traced = true;
}
- if (!IsNew)
- return {SymVector[SymIndex], false};
-
- auto *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
- Sym->SymbolKind = Symbol::PlaceholderKind;
- Sym->Visibility = STV_DEFAULT;
- Sym->IsUsedInRegularObj = false;
- Sym->ExportDynamic = false;
- Sym->CanInline = true;
- Sym->Traced = Traced;
- Sym->VersionId = Config->DefaultSymbolVersion;
- SymVector.push_back(Sym);
- return {Sym, true};
-}
-
-// Find an existing symbol or create and insert a new one, then apply the given
-// attributes.
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
- uint8_t Visibility,
- bool CanOmitFromDynSym,
- InputFile *File) {
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insertName(Name);
-
- // Merge in the new symbol's visibility.
- S->Visibility = getMinVisibility(S->Visibility, Visibility);
-
- if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
- S->ExportDynamic = true;
-
- if (!File || File->kind() == InputFile::ObjKind)
- S->IsUsedInRegularObj = true;
+ Symbol *Old;
+ if (IsNew) {
+ Old = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+ SymVector.push_back(Old);
+
+ Old->SymbolKind = Symbol::PlaceholderKind;
+ Old->VersionId = Config->DefaultSymbolVersion;
+ Old->Visibility = STV_DEFAULT;
+ Old->IsUsedInRegularObj = false;
+ Old->ExportDynamic = false;
+ Old->CanInline = true;
+ Old->Traced = Traced;
+ Old->ScriptDefined = false;
+ } else {
+ Old = SymVector[SymIndex];
+ }
+
+ // Merge symbol properties.
+ Old->ExportDynamic = Old->ExportDynamic || New.ExportDynamic;
+ Old->IsUsedInRegularObj = Old->IsUsedInRegularObj || New.IsUsedInRegularObj;
+
+ // DSO symbols do not affect visibility in the output.
+ if (!isa<SharedSymbol>(&New))
+ Old->Visibility = getMinVisibility(Old->Visibility, New.Visibility);
- return {S, WasInserted};
+ return {Old, IsNew};
}
-static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
-
-template <class ELFT>
-Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type,
- bool CanOmitFromDynSym, InputFile *File) {
- Symbol *S;
+template <class ELFT> Symbol *SymbolTable::addUndefined(const Undefined &New) {
+ Symbol *Old;
bool WasInserted;
- uint8_t Visibility = getVisibility(StOther);
- std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File);
+ std::tie(Old, WasInserted) = insert(New);
// An undefined symbol with non default visibility must be satisfied
// in the same DSO.
- if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) {
- replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
- return S;
+ if (WasInserted ||
+ (isa<SharedSymbol>(Old) && New.Visibility != STV_DEFAULT)) {
+ replaceSymbol(Old, &New);
+ return Old;
}
- if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
- S->Binding = Binding;
+ if (Old->isShared() || Old->isLazy() ||
+ (Old->isUndefined() && New.Binding != STB_WEAK))
+ Old->Binding = New.Binding;
- if (S->isLazy()) {
+ if (Old->isLazy()) {
// An undefined weak will not fetch archive members. See comment on Lazy in
// Symbols.h for the details.
- if (Binding == STB_WEAK) {
- S->Type = Type;
- return S;
+ if (New.Binding == STB_WEAK) {
+ Old->Type = New.Type;
+ return Old;
}
// Do extra check for --warn-backrefs.
@@ -225,17 +216,17 @@ Symbol *SymbolTable::addUndefined(String
// A forms group 0. B form group 1. C and D (including their member object
// files) form group 2. E forms group 3. I think that you can see how this
// group assignment rule simulates the traditional linker's semantics.
- bool Backref =
- Config->WarnBackrefs && File && S->File->GroupId < File->GroupId;
- fetchLazy<ELFT>(S);
+ bool Backref = Config->WarnBackrefs && New.File &&
+ Old->File->GroupId < New.File->GroupId;
+ fetchLazy<ELFT>(Old);
// We don't report backward references to weak symbols as they can be
// overridden later.
- if (Backref && !S->isWeak())
- warn("backward reference detected: " + Name + " in " + toString(File) +
- " refers to " + toString(S->File));
+ if (Backref && !Old->isWeak())
+ warn("backward reference detected: " + New.getName() + " in " +
+ toString(New.File) + " refers to " + toString(Old->File));
}
- return S;
+ return Old;
}
// Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
@@ -244,12 +235,12 @@ Symbol *SymbolTable::addUndefined(String
// FIXME: If users can transition to using
// .symver foo,foo@@@VER
// we can delete this hack.
-static int compareVersion(Symbol *S, StringRef Name) {
- bool A = Name.contains("@@");
- bool B = S->getName().contains("@@");
- if (A && !B)
- return 1;
+static int compareVersion(StringRef OldName, StringRef NewName) {
+ bool A = OldName.contains("@@");
+ bool B = NewName.contains("@@");
if (!A && B)
+ return 1;
+ if (A && !B)
return -1;
return 0;
}
@@ -257,17 +248,14 @@ static int compareVersion(Symbol *S, Str
// We have a new defined symbol with the specified binding. Return 1 if the new
// symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
// strong defined symbols.
-static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding,
- StringRef Name) {
- if (WasInserted)
- return 1;
- if (!S->isDefined())
+static int compareDefined(const Symbol *Old, const Symbol *New) {
+ if (!Old->isDefined())
return 1;
- if (int R = compareVersion(S, Name))
- return R;
- if (Binding == STB_WEAK)
+ if (int Cmp = compareVersion(Old->getName(), New->getName()))
+ return Cmp;
+ if (New->Binding == STB_WEAK)
return -1;
- if (S->isWeak())
+ if (Old->isWeak())
return 1;
return 0;
}
@@ -275,65 +263,77 @@ static int compareDefined(Symbol *S, boo
// We have a new non-common defined symbol with the specified binding. Return 1
// if the new symbol should win, -1 if the new symbol should lose, or 0 if there
// is a conflict. If the new symbol wins, also update the binding.
-static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
- bool IsAbsolute, uint64_t Value,
- StringRef Name) {
- if (int Cmp = compareDefined(S, WasInserted, Binding, Name))
+static int compareDefinedNonCommon(const Symbol *OldSym, const Defined *New) {
+ if (int Cmp = compareDefined(OldSym, New))
return Cmp;
- if (auto *R = dyn_cast<Defined>(S)) {
- if (R->Section && isa<BssSection>(R->Section)) {
+
+ if (auto *Old = dyn_cast<Defined>(OldSym)) {
+ if (Old->Section && isa<BssSection>(Old->Section)) {
// Non-common symbols take precedence over common symbols.
if (Config->WarnCommon)
- warn("common " + S->getName() + " is overridden");
+ warn("common " + Old->getName() + " is overridden");
return 1;
}
- if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute &&
- R->Value == Value)
+
+ if (New->File && isa<BitcodeFile>(New->File))
+ return 0;
+
+ if (Old->Section == nullptr && New->Section == nullptr &&
+ Old->Value == New->Value && New->Binding == STB_GLOBAL)
return -1;
}
return 0;
}
-Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
- uint8_t Binding, uint8_t StOther, uint8_t Type,
- InputFile &File) {
- Symbol *S;
+Symbol *SymbolTable::addCommon(const Defined &New) {
+ Symbol *Old;
bool WasInserted;
- std::tie(S, WasInserted) = insert(N, getVisibility(StOther),
- /*CanOmitFromDynSym*/ false, &File);
-
- int Cmp = compareDefined(S, WasInserted, Binding, N);
- if (Cmp < 0)
- return S;
+ std::tie(Old, WasInserted) = insert(New);
- if (Cmp > 0) {
- auto *Bss = make<BssSection>("COMMON", Size, Alignment);
- Bss->File = &File;
+ auto Replace = [&] {
+ auto *Bss = make<BssSection>("COMMON", New.Size, New.Value);
+ Bss->File = New.File;
Bss->Live = !Config->GcSections;
InputSections.push_back(Bss);
- replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss);
- return S;
+ Defined Sym = New;
+ Sym.Value = 0;
+ Sym.Section = Bss;
+ replaceSymbol(Old, &Sym);
+ };
+
+ if (WasInserted) {
+ Replace();
+ return Old;
+ }
+
+ int Cmp = compareDefined(Old, &New);
+ if (Cmp < 0)
+ return Old;
+
+ if (Cmp > 0) {
+ Replace();
+ return Old;
}
- auto *D = cast<Defined>(S);
+ auto *D = cast<Defined>(Old);
auto *Bss = dyn_cast_or_null<BssSection>(D->Section);
if (!Bss) {
// Non-common symbols take precedence over common symbols.
if (Config->WarnCommon)
- warn("common " + S->getName() + " is overridden");
- return S;
+ warn("common " + Old->getName() + " is overridden");
+ return Old;
}
if (Config->WarnCommon)
warn("multiple common of " + D->getName());
- Bss->Alignment = std::max(Bss->Alignment, Alignment);
- if (Size > Bss->Size) {
- D->File = Bss->File = &File;
- D->Size = Bss->Size = Size;
+ Bss->Alignment = std::max<uint32_t>(Bss->Alignment, New.Value);
+ if (New.Size > Bss->Size) {
+ D->File = Bss->File = New.File;
+ D->Size = Bss->Size = New.Size;
}
- return S;
+ return Old;
}
static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
@@ -371,66 +371,62 @@ static void reportDuplicate(Symbol *Sym,
error(Msg);
}
-Defined *SymbolTable::addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
- uint64_t Value, uint64_t Size, uint8_t Binding,
- SectionBase *Section, InputFile *File) {
- Symbol *S;
+Defined *SymbolTable::addDefined(const Defined &New) {
+ Symbol *Old;
bool WasInserted;
- std::tie(S, WasInserted) = insert(Name, getVisibility(StOther),
- /*CanOmitFromDynSym*/ false, File);
- int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
- Value, Name);
+ std::tie(Old, WasInserted) = insert(New);
+
+ if (WasInserted) {
+ replaceSymbol(Old, &New);
+ return cast<Defined>(Old);
+ }
+
+ int Cmp = compareDefinedNonCommon(Old, &New);
if (Cmp > 0)
- replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size,
- Section);
+ replaceSymbol(Old, &New);
else if (Cmp == 0)
- reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),
- Value);
- return cast<Defined>(S);
+ reportDuplicate(Old, New.File,
+ dyn_cast_or_null<InputSectionBase>(New.Section), New.Value);
+ return cast<Defined>(Old);
}
-void SymbolTable::addShared(StringRef Name, uint8_t Binding, uint8_t StOther,
- uint8_t Type, uint64_t Value, uint64_t Size,
- uint32_t Alignment, uint32_t VerdefIndex,
- InputFile *File) {
- // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
- // as the visibility, which will leave the visibility in the symbol table
- // unchanged.
- Symbol *S;
+void SymbolTable::addShared(const SharedSymbol &New) {
+ Symbol *Old;
bool WasInserted;
- std::tie(S, WasInserted) = insert(Name, STV_DEFAULT,
- /*CanOmitFromDynSym*/ true, File);
- // Make sure we preempt DSO symbols with default visibility.
- if (getVisibility(StOther) == STV_DEFAULT)
- S->ExportDynamic = true;
+ std::tie(Old, WasInserted) = insert(New);
- // An undefined symbol with non default visibility must be satisfied
- // in the same DSO.
- auto Replace = [&](uint8_t Binding) {
- replaceSymbol<SharedSymbol>(S, *File, Name, Binding, StOther, Type, Value,
- Size, Alignment, VerdefIndex);
- };
+ // Make sure we preempt DSO symbols with default visibility.
+ if (New.Visibility == STV_DEFAULT)
+ Old->ExportDynamic = true;
- if (WasInserted)
- Replace(Binding);
- else if (S->Visibility == STV_DEFAULT && (S->isUndefined() || S->isLazy()))
- Replace(S->Binding);
+ if (WasInserted) {
+ replaceSymbol(Old, &New);
+ } else if (Old->Visibility == STV_DEFAULT &&
+ (Old->isUndefined() || Old->isLazy())) {
+ // An undefined symbol with non default visibility must be satisfied
+ // in the same DSO.
+ uint8_t Binding = Old->Binding;
+ replaceSymbol(Old, &New);
+ Old->Binding = Binding;
+ }
}
-Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
- uint8_t StOther, uint8_t Type,
- bool CanOmitFromDynSym, BitcodeFile &F) {
- Symbol *S;
+Symbol *SymbolTable::addBitcode(const Defined &New) {
+ Symbol *Old;
bool WasInserted;
- std::tie(S, WasInserted) =
- insert(Name, getVisibility(StOther), CanOmitFromDynSym, &F);
- int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
- /*IsAbs*/ false, /*Value*/ 0, Name);
+ std::tie(Old, WasInserted) = insert(New);
+
+ if (WasInserted) {
+ replaceSymbol(Old, &New);
+ return Old;
+ }
+
+ int Cmp = compareDefinedNonCommon(Old, &New);
if (Cmp > 0)
- replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
+ replaceSymbol(Old, &New);
else if (Cmp == 0)
- reportDuplicate(S, &F, nullptr, 0);
- return S;
+ reportDuplicate(Old, New.File, nullptr, 0);
+ return Old;
}
Symbol *SymbolTable::find(StringRef Name) {
@@ -442,53 +438,39 @@ Symbol *SymbolTable::find(StringRef Name
return SymVector[It->second];
}
-template <class ELFT>
-void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &File,
- const object::Archive::Symbol Sym) {
- Symbol *S;
+template <class ELFT, class LazyT> void SymbolTable::addLazy(const LazyT &New) {
+ Symbol *Old;
bool WasInserted;
- std::tie(S, WasInserted) = insertName(Name);
+ std::tie(Old, WasInserted) = insert(New);
+
if (WasInserted) {
- replaceSymbol<LazyArchive>(S, File, STT_NOTYPE, Sym);
+ replaceSymbol(Old, &New);
return;
}
- if (!S->isUndefined())
+
+ if (!Old->isUndefined())
return;
// An undefined weak will not fetch archive members. See comment on Lazy in
// Symbols.h for the details.
- if (S->isWeak()) {
- replaceSymbol<LazyArchive>(S, File, S->Type, Sym);
- S->Binding = STB_WEAK;
+ if (Old->isWeak()) {
+ uint8_t Type = Old->Type;
+ replaceSymbol(Old, &New);
+ Old->Type = Type;
+ Old->Binding = STB_WEAK;
return;
}
- if (InputFile *F = File.fetch(Sym))
+ if (InputFile *F = New.fetch())
parseFile<ELFT>(F);
}
-template <class ELFT>
-void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &File) {
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insertName(Name);
- if (WasInserted) {
- replaceSymbol<LazyObject>(S, File, STT_NOTYPE, Name);
- return;
- }
- if (!S->isUndefined())
- return;
-
- // An undefined weak will not fetch archive members. See comment on Lazy in
- // Symbols.h for the details.
- if (S->isWeak()) {
- replaceSymbol<LazyObject>(S, File, S->Type, Name);
- S->Binding = STB_WEAK;
- return;
- }
+template <class ELFT> void SymbolTable::addLazyArchive(const LazyArchive &New) {
+ addLazy<ELFT>(New);
+}
- if (InputFile *F = File.fetch())
- parseFile<ELFT>(F);
+template <class ELFT> void SymbolTable::addLazyObject(const LazyObject &New) {
+ addLazy<ELFT>(New);
}
template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
@@ -664,37 +646,25 @@ void SymbolTable::scanVersionScript() {
Sym->parseSymbolVersion();
}
-template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,
- uint8_t, bool, InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,
- uint8_t, bool, InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, uint8_t, uint8_t,
- uint8_t, bool, InputFile *);
-template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, uint8_t, uint8_t,
- uint8_t, bool, InputFile *);
+template Symbol *SymbolTable::addUndefined<ELF32LE>(const Undefined &);
+template Symbol *SymbolTable::addUndefined<ELF32BE>(const Undefined &);
+template Symbol *SymbolTable::addUndefined<ELF64LE>(const Undefined &);
+template Symbol *SymbolTable::addUndefined<ELF64BE>(const Undefined &);
template void SymbolTable::addCombinedLTOObject<ELF32LE>();
template void SymbolTable::addCombinedLTOObject<ELF32BE>();
template void SymbolTable::addCombinedLTOObject<ELF64LE>();
template void SymbolTable::addCombinedLTOObject<ELF64BE>();
-template void
-SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &,
- const object::Archive::Symbol);
-template void
-SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &,
- const object::Archive::Symbol);
-template void
-SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &,
- const object::Archive::Symbol);
-template void
-SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &,
- const object::Archive::Symbol);
-
-template void SymbolTable::addLazyObject<ELF32LE>(StringRef, LazyObjFile &);
-template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &);
-template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &);
-template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &);
+template void SymbolTable::addLazyArchive<ELF32LE>(const LazyArchive &);
+template void SymbolTable::addLazyArchive<ELF32BE>(const LazyArchive &);
+template void SymbolTable::addLazyArchive<ELF64LE>(const LazyArchive &);
+template void SymbolTable::addLazyArchive<ELF64BE>(const LazyArchive &);
+
+template void SymbolTable::addLazyObject<ELF32LE>(const LazyObject &);
+template void SymbolTable::addLazyObject<ELF32BE>(const LazyObject &);
+template void SymbolTable::addLazyObject<ELF64LE>(const LazyObject &);
+template void SymbolTable::addLazyObject<ELF64BE>(const LazyObject &);
template void SymbolTable::fetchLazy<ELF32LE>(Symbol *);
template void SymbolTable::fetchLazy<ELF32BE>(Symbol *);
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed May 15 19:14:00 2019
@@ -17,8 +17,13 @@
namespace lld {
namespace elf {
+
class Defined;
+class LazyArchive;
+class LazyObject;
class SectionBase;
+class SharedSymbol;
+class Undefined;
// SymbolTable is a bucket of all known symbols, including defined,
// undefined, or lazy symbols (the last one is symbols in archive
@@ -39,33 +44,19 @@ public:
ArrayRef<Symbol *> getSymbols() const { return SymVector; }
- template <class ELFT>
- Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,
- uint8_t Type, bool CanOmitFromDynSym, InputFile *File);
-
- Defined *addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
- uint64_t Value, uint64_t Size, uint8_t Binding,
- SectionBase *Section, InputFile *File);
-
- void addShared(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type,
- uint64_t Value, uint64_t Size, uint32_t Alignment,
- uint32_t VerdefIndex, InputFile *File);
+ template <class ELFT> Symbol *addUndefined(const Undefined &New);
- template <class ELFT>
- void addLazyArchive(StringRef Name, ArchiveFile &F,
- const llvm::object::Archive::Symbol S);
+ Defined *addDefined(const Defined &New);
- template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj);
+ void addShared(const SharedSymbol &New);
- Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
- uint8_t Type, bool CanOmitFromDynSym, BitcodeFile &File);
+ template <class ELFT> void addLazyArchive(const LazyArchive &New);
+ template <class ELFT> void addLazyObject(const LazyObject &New);
- Symbol *addCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
- uint8_t Binding, uint8_t StOther, uint8_t Type,
- InputFile &File);
+ Symbol *addBitcode(const Defined &New);
+ Symbol *addCommon(const Defined &New);
- std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Visibility,
- bool CanOmitFromDynSym, InputFile *File);
+ std::pair<Symbol *, bool> insert(const Symbol &New);
template <class ELFT> void fetchLazy(Symbol *Sym);
@@ -81,7 +72,7 @@ public:
llvm::DenseMap<StringRef, SharedFile *> SoNames;
private:
- std::pair<Symbol *, bool> insertName(StringRef Name);
+ template <class ELFT, class LazyT> void addLazy(const LazyT &New);
std::vector<Symbol *> findByVersion(SymbolVersion Ver);
std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed May 15 19:14:00 2019
@@ -239,7 +239,9 @@ void Symbol::parseSymbolVersion() {
Verstr);
}
-InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); }
+InputFile *LazyArchive::fetch() const {
+ return cast<ArchiveFile>(File)->fetch(Sym);
+}
MemoryBufferRef LazyArchive::getMemberBuffer() {
Archive::Child C = CHECK(
@@ -250,6 +252,10 @@ MemoryBufferRef LazyArchive::getMemberBu
Sym.getName());
}
+InputFile *LazyObject::fetch() const {
+ return cast<LazyObjFile>(File)->fetch();
+}
+
uint8_t Symbol::computeBinding() const {
if (Config->Relocatable)
return Binding;
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Wed May 15 19:14:00 2019
@@ -172,10 +172,13 @@ protected:
Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
uint8_t StOther, uint8_t Type)
: File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
- Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
- IsInIplt(false), GotInIgot(false), IsPreemptible(false),
- Used(!Config->GcSections), NeedsTocRestore(false),
- ScriptDefined(false) {}
+ Type(Type), StOther(StOther), SymbolKind(K), Visibility(StOther & 3),
+ IsUsedInRegularObj(!File || File->kind() == InputFile::ObjKind),
+ ExportDynamic(K != SharedKind &&
+ (Config->Shared || Config->ExportDynamic)),
+ CanInline(false), Traced(false), NeedsPltAddr(false), IsInIplt(false),
+ GotInIgot(false), IsPreemptible(false), Used(!Config->GcSections),
+ NeedsTocRestore(false), ScriptDefined(false) {}
public:
// True the symbol should point to its PLT entry.
@@ -289,15 +292,14 @@ public:
// symbol.
class LazyArchive : public Symbol {
public:
- LazyArchive(InputFile &File, uint8_t Type,
- const llvm::object::Archive::Symbol S)
+ LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S)
: Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL,
- llvm::ELF::STV_DEFAULT, Type),
+ llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE),
Sym(S) {}
static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
- InputFile *fetch();
+ InputFile *fetch() const;
MemoryBufferRef getMemberBuffer();
private:
@@ -308,11 +310,13 @@ private:
// --start-lib and --end-lib options.
class LazyObject : public Symbol {
public:
- LazyObject(InputFile &File, uint8_t Type, StringRef Name)
+ LazyObject(InputFile &File, StringRef Name)
: Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
- llvm::ELF::STV_DEFAULT, Type) {}
+ llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE) {}
static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
+
+ InputFile *fetch() const;
};
// Some linker-generated symbols need to be created as
@@ -361,8 +365,7 @@ union SymbolUnion {
void printTraceSymbol(Symbol *Sym);
-template <typename T, typename... ArgT>
-void replaceSymbol(Symbol *S, ArgT &&... Arg) {
+template <typename T> void replaceSymbol(Symbol *Sym, const T *New) {
using llvm::ELF::STT_TLS;
static_assert(std::is_trivially_destructible<T>(),
@@ -373,34 +376,35 @@ void replaceSymbol(Symbol *S, ArgT &&...
assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
"Not a Symbol");
- Symbol Sym = *S;
-
- new (S) T(std::forward<ArgT>(Arg)...);
-
- S->VersionId = Sym.VersionId;
- S->Visibility = Sym.Visibility;
- S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
- S->ExportDynamic = Sym.ExportDynamic;
- S->CanInline = Sym.CanInline;
- S->Traced = Sym.Traced;
- S->ScriptDefined = Sym.ScriptDefined;
-
// Symbols representing thread-local variables must be referenced by
// TLS-aware relocations, and non-TLS symbols must be reference by
// non-TLS relocations, so there's a clear distinction between TLS
// and non-TLS symbols. It is an error if the same symbol is defined
// as a TLS symbol in one file and as a non-TLS symbol in other file.
- bool TlsMismatch = (Sym.Type == STT_TLS && S->Type != STT_TLS) ||
- (Sym.Type != STT_TLS && S->Type == STT_TLS);
+ if (Sym->SymbolKind != Symbol::PlaceholderKind && !Sym->isLazy() &&
+ !New->isLazy()) {
+ bool TlsMismatch = (Sym->Type == STT_TLS && New->Type != STT_TLS) ||
+ (Sym->Type != STT_TLS && New->Type == STT_TLS);
+ if (TlsMismatch)
+ error("TLS attribute mismatch: " + toString(*Sym) + "\n>>> defined in " +
+ toString(New->File) + "\n>>> defined in " + toString(Sym->File));
+ }
+
+ Symbol Old = *Sym;
+ memcpy(Sym, New, sizeof(T));
- if (Sym.SymbolKind != Symbol::PlaceholderKind && TlsMismatch && !Sym.isLazy())
- error("TLS attribute mismatch: " + toString(Sym) + "\n>>> defined in " +
- toString(Sym.File) + "\n>>> defined in " + toString(S->File));
+ Sym->VersionId = Old.VersionId;
+ Sym->Visibility = Old.Visibility;
+ Sym->IsUsedInRegularObj = Old.IsUsedInRegularObj;
+ Sym->ExportDynamic = Old.ExportDynamic;
+ Sym->CanInline = Old.CanInline;
+ Sym->Traced = Old.Traced;
+ Sym->ScriptDefined = Old.ScriptDefined;
// Print out a log message if --trace-symbol was specified.
// This is for debugging.
- if (S->Traced)
- printTraceSymbol(S);
+ if (Sym->Traced)
+ printTraceSymbol(Sym);
}
void maybeWarnUnorderableSymbol(const Symbol *Sym);
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=360838&r1=360837&r2=360838&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed May 15 19:14:00 2019
@@ -179,14 +179,15 @@ static Defined *addOptionalRegular(Strin
Symbol *S = Symtab->find(Name);
if (!S || S->isDefined())
return nullptr;
- return Symtab->addDefined(Name, StOther, STT_NOTYPE, Val,
- /*Size=*/0, Binding, Sec,
- /*File=*/nullptr);
+
+ return Symtab->addDefined(Defined{/*File=*/nullptr, Name, Binding, StOther,
+ STT_NOTYPE, Val,
+ /*Size=*/0, Sec});
}
static Defined *addAbsolute(StringRef Name) {
- return Symtab->addDefined(Name, STV_HIDDEN, STT_NOTYPE, 0, 0, STB_GLOBAL,
- nullptr, nullptr);
+ return Symtab->addDefined(Defined{nullptr, Name, STB_GLOBAL, STV_HIDDEN,
+ STT_NOTYPE, 0, 0, nullptr});
}
// The linker is expected to define some symbols depending on
@@ -236,9 +237,9 @@ void elf::addReservedSymbols() {
GotOff = 0x8000;
ElfSym::GlobalOffsetTable =
- Symtab->addDefined(GotSymName, STV_HIDDEN, STT_NOTYPE, GotOff,
- /*Size=*/0, STB_GLOBAL, Out::ElfHeader,
- /*File=*/nullptr);
+ Symtab->addDefined(Defined{/*File=*/nullptr, GotSymName, STB_GLOBAL,
+ STV_HIDDEN, STT_NOTYPE, GotOff,
+ /*Size=*/0, Out::ElfHeader});
}
// __ehdr_start is the location of ELF file headers. Note that we define
@@ -1588,9 +1589,9 @@ template <class ELFT> void Writer<ELFT>:
// Even the author of gold doesn't remember why gold behaves that way.
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
if (In.Dynamic->Parent)
- Symtab->addDefined("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
- /*Size=*/0, STB_WEAK, In.Dynamic,
- /*File=*/nullptr);
+ Symtab->addDefined(Defined{/*File=*/nullptr, "_DYNAMIC", STB_WEAK,
+ STV_HIDDEN, STT_NOTYPE,
+ /*Value=*/0, /*Size=*/0, In.Dynamic});
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();
More information about the llvm-commits
mailing list