Move File from SymbolBody to Symbol.

With this Symbol has the same size as before, but DefinedRegular goes
from 72 to 64 bytes.

I also find this a bit easier to read. There are fewer places
initializing File for example.

This has a small but measurable speed improvement on all tests (1%
max).

llvm-svn: 310142
This commit is contained in:
Rafael Espindola 2017-08-04 22:31:42 +00:00
parent e12d734be3
commit 6e93d0546a
10 changed files with 80 additions and 74 deletions

View File

@ -565,10 +565,10 @@ SymbolBody *ObjFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
StringRefZ Name = this->StringTable.data() + Sym->st_name; StringRefZ Name = this->StringTable.data() + Sym->st_name;
if (Sym->st_shndx == SHN_UNDEF) if (Sym->st_shndx == SHN_UNDEF)
return make<Undefined>(Name, /*IsLocal=*/true, StOther, Type, this); return make<Undefined>(Name, /*IsLocal=*/true, StOther, Type);
return make<DefinedRegular>(Name, /*IsLocal=*/true, StOther, Type, Value, return make<DefinedRegular>(Name, /*IsLocal=*/true, StOther, Type, Value,
Size, Sec, this); Size, Sec);
} }
StringRef Name = check(Sym->getName(this->StringTable), toString(this)); StringRef Name = check(Sym->getName(this->StringTable), toString(this));

View File

@ -120,8 +120,8 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {
BitcodeCompiler::~BitcodeCompiler() = default; BitcodeCompiler::~BitcodeCompiler() = default;
static void undefine(Symbol *S) { static void undefine(Symbol *S) {
replaceBody<Undefined>(S, S->body()->getName(), /*IsLocal=*/false, replaceBody<Undefined>(S, nullptr, S->body()->getName(), /*IsLocal=*/false,
STV_DEFAULT, S->body()->Type, nullptr); STV_DEFAULT, S->body()->Type);
} }
void BitcodeCompiler::add(BitcodeFile &F) { void BitcodeCompiler::add(BitcodeFile &F) {
@ -142,7 +142,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
// flags an undefined in IR with a definition in ASM as prevailing. // flags an undefined in IR with a definition in ASM as prevailing.
// Once IRObjectFile is fixed to report only one symbol this hack can // Once IRObjectFile is fixed to report only one symbol this hack can
// be removed. // be removed.
R.Prevailing = !ObjSym.isUndefined() && B->File == &F; R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F;
R.VisibleToRegularObj = Sym->IsUsedInRegularObj || R.VisibleToRegularObj = Sym->IsUsedInRegularObj ||
(R.Prevailing && Sym->includeInDynsym()) || (R.Prevailing && Sym->includeInDynsym()) ||

View File

@ -79,8 +79,8 @@ static SymbolBody *addRegular(SymbolAssignment *Cmd) {
// as variables in linker scripts. Doing so allows us to write expressions // as variables in linker scripts. Doing so allows us to write expressions
// like this: `alignment = 16; . = ALIGN(., alignment)` // like this: `alignment = 16; . = ALIGN(., alignment)`
uint64_t SymValue = Value.isAbsolute() ? Value.getValue() : 0; uint64_t SymValue = Value.isAbsolute() ? Value.getValue() : 0;
replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility, replaceBody<DefinedRegular>(Sym, nullptr, Cmd->Name, /*IsLocal=*/false,
STT_NOTYPE, SymValue, 0, Sec, nullptr); Visibility, STT_NOTYPE, SymValue, 0, Sec);
return Sym->body(); return Sym->body();
} }

View File

@ -53,7 +53,7 @@ template <class ELFT> static std::vector<DefinedRegular *> getSymbols() {
for (ObjFile<ELFT> *File : ObjFile<ELFT>::Instances) for (ObjFile<ELFT> *File : ObjFile<ELFT>::Instances)
for (SymbolBody *B : File->getSymbols()) for (SymbolBody *B : File->getSymbols())
if (auto *DR = dyn_cast<DefinedRegular>(B)) if (auto *DR = dyn_cast<DefinedRegular>(B))
if (DR->File == File && !DR->isSection() && DR->Section && if (DR->getFile() == File && !DR->isSection() && DR->Section &&
DR->Section->Live) DR->Section->Live)
V.push_back(DR); V.push_back(DR);
return V; return V;

View File

@ -73,7 +73,7 @@ template <class ELFT>
static std::string getLocation(InputSectionBase &S, const SymbolBody &Sym, static std::string getLocation(InputSectionBase &S, const SymbolBody &Sym,
uint64_t Off) { uint64_t Off) {
std::string Msg = std::string Msg =
"\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by "; "\n>>> defined in " + toString(Sym.getFile()) + "\n>>> referenced by ";
std::string Src = S.getSrcMsg<ELFT>(Off); std::string Src = S.getSrcMsg<ELFT>(Off);
if (!Src.empty()) if (!Src.empty())
Msg += Src + "\n>>> "; Msg += Src + "\n>>> ";
@ -434,7 +434,7 @@ template <class ELFT> static bool isReadOnly(SharedSymbol *SS) {
uint64_t Value = SS->getValue<ELFT>(); uint64_t Value = SS->getValue<ELFT>();
// Determine if the symbol is read-only by scanning the DSO's program headers. // Determine if the symbol is read-only by scanning the DSO's program headers.
auto *File = cast<SharedFile<ELFT>>(SS->File); const SharedFile<ELFT> *File = SS->getFile<ELFT>();
for (const Elf_Phdr &Phdr : check(File->getObj().program_headers())) for (const Elf_Phdr &Phdr : check(File->getObj().program_headers()))
if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) && if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
!(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr && !(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr &&
@ -452,7 +452,7 @@ template <class ELFT>
static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) { static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) {
typedef typename ELFT::Sym Elf_Sym; typedef typename ELFT::Sym Elf_Sym;
auto *File = cast<SharedFile<ELFT>>(SS->File); SharedFile<ELFT> *File = SS->getFile<ELFT>();
uint64_t Shndx = SS->getShndx<ELFT>(); uint64_t Shndx = SS->getShndx<ELFT>();
uint64_t Value = SS->getValue<ELFT>(); uint64_t Value = SS->getValue<ELFT>();
@ -616,7 +616,7 @@ static RelExpr adjustExpr(SymbolBody &Body, RelExpr Expr, uint32_t Type,
} }
errorOrWarn("symbol '" + toString(Body) + "' defined in " + errorOrWarn("symbol '" + toString(Body) + "' defined in " +
toString(Body.File) + " has no type"); toString(Body.getFile()) + " has no type");
return Expr; return Expr;
} }

View File

@ -196,6 +196,7 @@ void SymbolTable::applySymbolRenames() {
Symbol *Dst = KV.first; Symbol *Dst = KV.first;
Symbol *Src = KV.second.Target; Symbol *Src = KV.second.Target;
Dst->body()->copy(Src->body()); Dst->body()->copy(Src->body());
Dst->File = Src->File;
Dst->Binding = KV.second.OriginalBinding; Dst->Binding = KV.second.OriginalBinding;
} }
} }
@ -266,8 +267,8 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
if (!WasInserted && S->body()->Type != SymbolBody::UnknownType && if (!WasInserted && S->body()->Type != SymbolBody::UnknownType &&
((Type == STT_TLS) != S->body()->isTls())) { ((Type == STT_TLS) != S->body()->isTls())) {
error("TLS attribute mismatch: " + toString(*S->body()) + error("TLS attribute mismatch: " + toString(*S->body()) +
"\n>>> defined in " + toString(S->body()->File) + "\n>>> defined in " + toString(S->File) + "\n>>> defined in " +
"\n>>> defined in " + toString(File)); toString(File));
} }
return {S, WasInserted}; return {S, WasInserted};
@ -295,7 +296,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
if (WasInserted || if (WasInserted ||
(isa<SharedSymbol>(S->body()) && Visibility != STV_DEFAULT)) { (isa<SharedSymbol>(S->body()) && Visibility != STV_DEFAULT)) {
S->Binding = Binding; S->Binding = Binding;
replaceBody<Undefined>(S, Name, IsLocal, StOther, Type, File); replaceBody<Undefined>(S, File, Name, IsLocal, StOther, Type);
return S; return S;
} }
if (Binding != STB_WEAK) { if (Binding != STB_WEAK) {
@ -303,7 +304,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
if (B->isShared() || B->isLazy() || B->isUndefined()) if (B->isShared() || B->isLazy() || B->isUndefined())
S->Binding = Binding; S->Binding = Binding;
if (auto *SS = dyn_cast<SharedSymbol>(B)) if (auto *SS = dyn_cast<SharedSymbol>(B))
cast<SharedFile<ELFT>>(SS->File)->IsUsed = true; SS->getFile<ELFT>()->IsUsed = true;
} }
if (auto *L = dyn_cast<Lazy>(S->body())) { if (auto *L = dyn_cast<Lazy>(S->body())) {
// An undefined weak will not fetch archive members, but we have to remember // An undefined weak will not fetch archive members, but we have to remember
@ -388,7 +389,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
int Cmp = compareDefined(S, WasInserted, Binding, N); int Cmp = compareDefined(S, WasInserted, Binding, N);
if (Cmp > 0) { if (Cmp > 0) {
S->Binding = Binding; S->Binding = Binding;
replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File); replaceBody<DefinedCommon>(S, File, N, Size, Alignment, StOther, Type);
} else if (Cmp == 0) { } else if (Cmp == 0) {
auto *C = dyn_cast<DefinedCommon>(S->body()); auto *C = dyn_cast<DefinedCommon>(S->body());
if (!C) { if (!C) {
@ -403,7 +404,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
Alignment = C->Alignment = std::max(C->Alignment, Alignment); Alignment = C->Alignment = std::max(C->Alignment, Alignment);
if (Size > C->Size) if (Size > C->Size)
replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File); replaceBody<DefinedCommon>(S, File, N, Size, Alignment, StOther, Type);
} }
return S; return S;
} }
@ -417,7 +418,8 @@ static void warnOrError(const Twine &Msg) {
static void reportDuplicate(SymbolBody *Sym, InputFile *NewFile) { static void reportDuplicate(SymbolBody *Sym, InputFile *NewFile) {
warnOrError("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " + warnOrError("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
toString(Sym->File) + "\n>>> defined in " + toString(NewFile)); toString(Sym->getFile()) + "\n>>> defined in " +
toString(NewFile));
} }
template <class ELFT> template <class ELFT>
@ -463,8 +465,8 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr, int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
Value, Name); Value, Name);
if (Cmp > 0) if (Cmp > 0)
replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type, replaceBody<DefinedRegular>(S, File, Name, /*IsLocal=*/false, StOther, Type,
Value, Size, Section, File); Value, Size, Section);
else if (Cmp == 0) else if (Cmp == 0)
reportDuplicate<ELFT>(S->body(), reportDuplicate<ELFT>(S->body(),
dyn_cast_or_null<InputSectionBase>(Section), Value); dyn_cast_or_null<InputSectionBase>(Section), Value);
@ -508,8 +510,8 @@ Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
/*IsAbs*/ false, /*Value*/ 0, Name); /*IsAbs*/ false, /*Value*/ 0, Name);
if (Cmp > 0) if (Cmp > 0)
replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type, 0, 0, replaceBody<DefinedRegular>(S, F, Name, /*IsLocal=*/false, StOther, Type, 0,
nullptr, F); 0, nullptr);
else if (Cmp == 0) else if (Cmp == 0)
reportDuplicate(S->body(), F); reportDuplicate(S->body(), F);
return S; return S;
@ -540,7 +542,7 @@ Symbol *SymbolTable::addLazyArchive(ArchiveFile *F,
StringRef Name = Sym.getName(); StringRef Name = Sym.getName();
std::tie(S, WasInserted) = insert(Name); std::tie(S, WasInserted) = insert(Name);
if (WasInserted) { if (WasInserted) {
replaceBody<LazyArchive>(S, *F, Sym, SymbolBody::UnknownType); replaceBody<LazyArchive>(S, F, Sym, SymbolBody::UnknownType);
return S; return S;
} }
if (!S->body()->isUndefined()) if (!S->body()->isUndefined())
@ -554,7 +556,7 @@ Symbol *SymbolTable::addLazyArchive(ArchiveFile *F,
// this symbol as used when we added it to the symbol table, but we also need // this symbol as used when we added it to the symbol table, but we also need
// to preserve its type. FIXME: Move the Type field to Symbol. // to preserve its type. FIXME: Move the Type field to Symbol.
if (S->isWeak()) { if (S->isWeak()) {
replaceBody<LazyArchive>(S, *F, Sym, S->body()->Type); replaceBody<LazyArchive>(S, F, Sym, S->body()->Type);
return S; return S;
} }
std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym); std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym);
@ -569,7 +571,7 @@ void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
bool WasInserted; bool WasInserted;
std::tie(S, WasInserted) = insert(Name); std::tie(S, WasInserted) = insert(Name);
if (WasInserted) { if (WasInserted) {
replaceBody<LazyObject>(S, Name, Obj, SymbolBody::UnknownType); replaceBody<LazyObject>(S, &Obj, Name, SymbolBody::UnknownType);
return; return;
} }
if (!S->body()->isUndefined()) if (!S->body()->isUndefined())
@ -577,7 +579,7 @@ void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
// See comment for addLazyArchive above. // See comment for addLazyArchive above.
if (S->isWeak()) if (S->isWeak())
replaceBody<LazyObject>(S, Name, Obj, S->body()->Type); replaceBody<LazyObject>(S, &Obj, Name, S->body()->Type);
else if (InputFile *F = Obj.fetch()) else if (InputFile *F = Obj.fetch())
addFile<ELFT>(F); addFile<ELFT>(F);
} }

View File

@ -93,7 +93,7 @@ static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) {
if (D.isTls() && !Config->Relocatable) { if (D.isTls() && !Config->Relocatable) {
if (!Out::TlsPhdr) if (!Out::TlsPhdr)
fatal(toString(D.File) + fatal(toString(D.getFile()) +
" has an STT_TLS symbol but doesn't have an SHF_TLS section"); " has an STT_TLS symbol but doesn't have an SHF_TLS section");
return VA - Out::TlsPhdr->p_vaddr; return VA - Out::TlsPhdr->p_vaddr;
} }
@ -129,6 +129,12 @@ SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {} IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
InputFile *SymbolBody::getFile() const {
if (isLocal())
return cast<InputSectionBase>(cast<DefinedRegular>(this)->Section)->File;
return symbol()->File;
}
// Returns true if a symbol can be replaced at load-time by a symbol // Returns true if a symbol can be replaced at load-time by a symbol
// with the same name defined in other ELF executable or DSO. // with the same name defined in other ELF executable or DSO.
bool SymbolBody::isPreemptible() const { bool SymbolBody::isPreemptible() const {
@ -274,7 +280,7 @@ void SymbolBody::parseSymbolVersion() {
// but we may still want to override a versioned symbol from DSO, // but we may still want to override a versioned symbol from DSO,
// so we do not report error in this case. // so we do not report error in this case.
if (Config->Shared) if (Config->Shared)
error(toString(File) + ": symbol " + S + " has undefined version " + error(toString(getFile()) + ": symbol " + S + " has undefined version " +
Verstr); Verstr);
} }
@ -294,24 +300,20 @@ template <class ELFT> bool DefinedRegular::isMipsPIC() const {
} }
Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther,
uint8_t Type, InputFile *File) uint8_t Type)
: SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) { : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) {}
this->File = File;
}
DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint32_t Alignment, DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
uint8_t StOther, uint8_t Type, InputFile *File) uint8_t StOther, uint8_t Type)
: Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther, : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
Type), Type),
Alignment(Alignment), Size(Size) { Alignment(Alignment), Size(Size) {}
this->File = File;
}
// If a shared symbol is referred via a copy relocation, its alignment // If a shared symbol is referred via a copy relocation, its alignment
// becomes part of the ABI. This function returns a symbol alignment. // becomes part of the ABI. This function returns a symbol alignment.
// Because symbols don't have alignment attributes, we need to infer that. // Because symbols don't have alignment attributes, we need to infer that.
template <class ELFT> uint32_t SharedSymbol::getAlignment() const { template <class ELFT> uint32_t SharedSymbol::getAlignment() const {
auto *File = cast<SharedFile<ELFT>>(this->File); SharedFile<ELFT> *File = getFile<ELFT>();
uint32_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign; uint32_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign;
uint64_t SymValue = getSym<ELFT>().st_value; uint64_t SymValue = getSym<ELFT>().st_value;
uint32_t SymAlign = uint32_t(1) << countTrailingZeros(SymValue); uint32_t SymAlign = uint32_t(1) << countTrailingZeros(SymValue);
@ -324,28 +326,31 @@ InputFile *Lazy::fetch() {
return cast<LazyObject>(this)->fetch(); return cast<LazyObject>(this)->fetch();
} }
LazyArchive::LazyArchive(ArchiveFile &File, LazyArchive::LazyArchive(const llvm::object::Archive::Symbol S, uint8_t Type)
const llvm::object::Archive::Symbol S, uint8_t Type) : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) {}
: Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) {
this->File = &File;
}
LazyObject::LazyObject(StringRef Name, LazyObjFile &File, uint8_t Type) LazyObject::LazyObject(StringRef Name, uint8_t Type)
: Lazy(LazyObjectKind, Name, Type) { : Lazy(LazyObjectKind, Name, Type) {}
this->File = &File;
ArchiveFile *LazyArchive::getFile() {
return cast<ArchiveFile>(SymbolBody::getFile());
} }
InputFile *LazyArchive::fetch() { InputFile *LazyArchive::fetch() {
std::pair<MemoryBufferRef, uint64_t> MBInfo = file()->getMember(&Sym); std::pair<MemoryBufferRef, uint64_t> MBInfo = getFile()->getMember(&Sym);
// getMember returns an empty buffer if the member was already // getMember returns an empty buffer if the member was already
// read from the library. // read from the library.
if (MBInfo.first.getBuffer().empty()) if (MBInfo.first.getBuffer().empty())
return nullptr; return nullptr;
return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second); return createObjectFile(MBInfo.first, getFile()->getName(), MBInfo.second);
} }
InputFile *LazyObject::fetch() { return file()->fetch(); } LazyObjFile *LazyObject::getFile() {
return cast<LazyObjFile>(SymbolBody::getFile());
}
InputFile *LazyObject::fetch() { return getFile()->fetch(); }
uint8_t Symbol::computeBinding() const { uint8_t Symbol::computeBinding() const {
if (Config->Relocatable) if (Config->Relocatable)
@ -378,7 +383,7 @@ void elf::printTraceSymbol(Symbol *Sym) {
else else
S = ": definition of "; S = ": definition of ";
message(toString(B->File) + S + B->getName()); message(toString(Sym->File) + S + B->getName());
} }
// Returns a symbol for an error message. // Returns a symbol for an error message.

View File

@ -69,6 +69,7 @@ public:
return !isUndefined() && !isShared() && !isLazy(); return !isUndefined() && !isShared() && !isLazy();
} }
bool isLocal() const { return IsLocal; } bool isLocal() const { return IsLocal; }
InputFile *getFile() const;
bool isPreemptible() const; bool isPreemptible() const;
StringRef getName() const { return Name; } StringRef getName() const { return Name; }
uint8_t getVisibility() const { return StOther & 0x3; } uint8_t getVisibility() const { return StOther & 0x3; }
@ -88,9 +89,6 @@ public:
template <class ELFT> typename ELFT::uint getSize() const; template <class ELFT> typename ELFT::uint getSize() const;
OutputSection *getOutputSection() const; OutputSection *getOutputSection() const;
// The file from which this symbol was created.
InputFile *File = nullptr;
uint32_t DynsymIndex = 0; uint32_t DynsymIndex = 0;
uint32_t GotIndex = -1; uint32_t GotIndex = -1;
uint32_t GotPltIndex = -1; uint32_t GotPltIndex = -1;
@ -155,7 +153,7 @@ public:
class DefinedCommon : public Defined { class DefinedCommon : public Defined {
public: public:
DefinedCommon(StringRef N, uint64_t Size, uint32_t Alignment, uint8_t StOther, DefinedCommon(StringRef N, uint64_t Size, uint32_t Alignment, uint8_t StOther,
uint8_t Type, InputFile *File); uint8_t Type);
static bool classof(const SymbolBody *S) { static bool classof(const SymbolBody *S) {
return S->kind() == SymbolBody::DefinedCommonKind; return S->kind() == SymbolBody::DefinedCommonKind;
@ -175,12 +173,9 @@ public:
class DefinedRegular : public Defined { class DefinedRegular : public Defined {
public: public:
DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type, DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type,
uint64_t Value, uint64_t Size, SectionBase *Section, uint64_t Value, uint64_t Size, SectionBase *Section)
InputFile *File)
: Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type), : Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type),
Value(Value), Size(Size), Section(Section) { Value(Value), Size(Size), Section(Section) {}
this->File = File;
}
// Return true if the symbol is a PIC function. // Return true if the symbol is a PIC function.
template <class ELFT> bool isMipsPIC() const; template <class ELFT> bool isMipsPIC() const;
@ -196,8 +191,7 @@ public:
class Undefined : public SymbolBody { class Undefined : public SymbolBody {
public: public:
Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type, Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type);
InputFile *F);
static bool classof(const SymbolBody *S) { static bool classof(const SymbolBody *S) {
return S->kind() == UndefinedKind; return S->kind() == UndefinedKind;
@ -210,14 +204,17 @@ public:
return S->kind() == SymbolBody::SharedKind; return S->kind() == SymbolBody::SharedKind;
} }
SharedSymbol(InputFile *File, StringRef Name, uint8_t StOther, uint8_t Type, SharedSymbol(StringRef Name, uint8_t StOther, uint8_t Type,
const void *ElfSym, const void *Verdef) const void *ElfSym, const void *Verdef)
: Defined(SymbolBody::SharedKind, Name, /*IsLocal=*/false, StOther, Type), : Defined(SymbolBody::SharedKind, Name, /*IsLocal=*/false, StOther, Type),
Verdef(Verdef), ElfSym(ElfSym) { Verdef(Verdef), ElfSym(ElfSym) {
// IFuncs defined in DSOs are treated as functions by the static linker. // IFuncs defined in DSOs are treated as functions by the static linker.
if (isGnuIFunc()) if (isGnuIFunc())
this->Type = llvm::ELF::STT_FUNC; this->Type = llvm::ELF::STT_FUNC;
this->File = File; }
template <class ELFT> SharedFile<ELFT> *getFile() const {
return cast<SharedFile<ELFT>>(SymbolBody::getFile());
} }
template <class ELFT> uint64_t getShndx() const { template <class ELFT> uint64_t getShndx() const {
@ -270,14 +267,13 @@ protected:
// LazyArchive symbols represents symbols in archive files. // LazyArchive symbols represents symbols in archive files.
class LazyArchive : public Lazy { class LazyArchive : public Lazy {
public: public:
LazyArchive(ArchiveFile &File, const llvm::object::Archive::Symbol S, LazyArchive(const llvm::object::Archive::Symbol S, uint8_t Type);
uint8_t Type);
static bool classof(const SymbolBody *S) { static bool classof(const SymbolBody *S) {
return S->kind() == LazyArchiveKind; return S->kind() == LazyArchiveKind;
} }
ArchiveFile *file() { return (ArchiveFile *)this->File; } ArchiveFile *getFile();
InputFile *fetch(); InputFile *fetch();
private: private:
@ -288,13 +284,13 @@ private:
// --start-lib and --end-lib options. // --start-lib and --end-lib options.
class LazyObject : public Lazy { class LazyObject : public Lazy {
public: public:
LazyObject(StringRef Name, LazyObjFile &File, uint8_t Type); LazyObject(StringRef Name, uint8_t Type);
static bool classof(const SymbolBody *S) { static bool classof(const SymbolBody *S) {
return S->kind() == LazyObjectKind; return S->kind() == LazyObjectKind;
} }
LazyObjFile *file() { return (LazyObjFile *)this->File; } LazyObjFile *getFile();
InputFile *fetch(); InputFile *fetch();
}; };
@ -364,6 +360,9 @@ struct Symbol {
// This symbol version was found in a version script. // This symbol version was found in a version script.
unsigned InVersionScript : 1; unsigned InVersionScript : 1;
// The file from which this symbol was created.
InputFile *File = nullptr;
bool includeInDynsym() const; bool includeInDynsym() const;
uint8_t computeBinding() const; uint8_t computeBinding() const;
bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
@ -382,13 +381,13 @@ struct Symbol {
void printTraceSymbol(Symbol *Sym); void printTraceSymbol(Symbol *Sym);
template <typename T, typename... ArgT> template <typename T, typename... ArgT>
void replaceBody(Symbol *S, ArgT &&... Arg) { void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
static_assert(sizeof(T) <= sizeof(S->Body), "Body too small"); static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
static_assert(alignof(T) <= alignof(decltype(S->Body)), static_assert(alignof(T) <= alignof(decltype(S->Body)),
"Body not aligned enough"); "Body not aligned enough");
assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr && assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
"Not a SymbolBody"); "Not a SymbolBody");
S->File = File;
new (S->Body.buffer) T(std::forward<ArgT>(Arg)...); new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
// Print out a log message if --trace-symbol was specified. // Print out a log message if --trace-symbol was specified.

View File

@ -297,7 +297,7 @@ InputSection *elf::createInterpSection() {
SymbolBody *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, SymbolBody *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
uint64_t Size, InputSectionBase *Section) { uint64_t Size, InputSectionBase *Section) {
auto *S = make<DefinedRegular>(Name, /*IsLocal*/ true, STV_DEFAULT, Type, auto *S = make<DefinedRegular>(Name, /*IsLocal*/ true, STV_DEFAULT, Type,
Value, Size, Section, nullptr); Value, Size, Section);
if (InX::SymTab) if (InX::SymTab)
InX::SymTab->addSymbol(S); InX::SymTab->addSymbol(S);
return S; return S;
@ -2082,7 +2082,7 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) {
return; return;
} }
auto *File = cast<SharedFile<ELFT>>(SS->File); SharedFile<ELFT> *File = SS->getFile<ELFT>();
// If we don't already know that we need an Elf_Verneed for this DSO, prepare // If we don't already know that we need an Elf_Verneed for this DSO, prepare
// to create one by adding it to our needed list and creating a dynstr entry // to create one by adding it to our needed list and creating a dynstr entry

View File

@ -502,7 +502,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
auto *Sym = auto *Sym =
make<DefinedRegular>("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION, make<DefinedRegular>("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION,
/*Value=*/0, /*Size=*/0, IS, nullptr); /*Value=*/0, /*Size=*/0, IS);
InX::SymTab->addSymbol(Sym); InX::SymTab->addSymbol(Sym);
} }
} }
@ -1204,7 +1204,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (InX::DynSymTab && S->includeInDynsym()) { if (InX::DynSymTab && S->includeInDynsym()) {
InX::DynSymTab->addSymbol(Body); InX::DynSymTab->addSymbol(Body);
if (auto *SS = dyn_cast<SharedSymbol>(Body)) if (auto *SS = dyn_cast<SharedSymbol>(Body))
if (cast<SharedFile<ELFT>>(SS->File)->isNeeded()) if (cast<SharedFile<ELFT>>(S->File)->isNeeded())
In<ELFT>::VerNeed->addSymbol(SS); In<ELFT>::VerNeed->addSymbol(SS);
} }
} }