forked from OSchip/llvm-project
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:
parent
e12d734be3
commit
6e93d0546a
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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()) ||
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue