Index: ELF/ICF.cpp =================================================================== --- ELF/ICF.cpp +++ ELF/ICF.cpp @@ -93,7 +93,7 @@ static uint64_t getHash(InputSection *S); static bool isEligible(InputSectionBase *Sec); static std::vector *> getSections(SymbolTable *S); - static SymbolBody *getSymbol(const InputSection *Sec, + static SymbolBody &getSymbol(const InputSection *Sec, const Elf_Rel *Rel); void segregate(InputSection **Begin, InputSection **End, @@ -161,10 +161,10 @@ } template -SymbolBody *ICF::getSymbol(const InputSection *Sec, +SymbolBody &ICF::getSymbol(const InputSection *Sec, const Elf_Rel *Rel) { uint32_t SymIdx = Rel->getSymbol(Config->Mips64EL); - return Sec->File->getSymbolBody(SymIdx); + return Sec->File->getSymbolBody(SymIdx).repl(); } // All sections between Begin and End must have the same group ID before @@ -259,26 +259,15 @@ const RelTy *EA = RelsA.end(); const RelTy *IB = RelsB.begin(); for (; IA != EA; ++IA, ++IB) { - // If both IA and IB are pointing to the same local symbol, - // this "if" condition must be true. - if (A->File == B->File && - IA->getSymbol(Config->Mips64EL) == IB->getSymbol(Config->Mips64EL)) - continue; - - // Otherwise, IA and IB must be pointing to the global symbols. - SymbolBody *SA = getSymbol(A, (const Elf_Rel *)IA); - SymbolBody *SB = getSymbol(B, (const Elf_Rel *)IB); - if (!SA || !SB) - return false; - - // The global symbols should be simply the same. - if (SA->repl() == SB->repl()) + SymbolBody &SA = getSymbol(A, (const Elf_Rel *)IA); + SymbolBody &SB = getSymbol(B, (const Elf_Rel *)IB); + if (&SA == &SB) continue; // Or, the symbols should be pointing to the same section // in terms of the group ID. - auto *DA = dyn_cast>(SA->repl()); - auto *DB = dyn_cast>(SB->repl()); + auto *DA = dyn_cast>(&SA); + auto *DB = dyn_cast>(&SB); if (!DA || !DB) return false; if (DA->Sym.st_value != DB->Sym.st_value) Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -84,8 +84,7 @@ ArrayRef SymtabSHNDX; StringRef StringTable; void initStringTable(); - Elf_Sym_Range getNonLocalSymbols(); - Elf_Sym_Range getSymbolsHelper(bool); + Elf_Sym_Range getElfSymbols(bool OnlyGlobals); }; // .o file. @@ -110,7 +109,9 @@ return F->kind() == Base::ObjectKind; } - ArrayRef getSymbols() { return SymbolBodies; } + ArrayRef getSymbols(); + ArrayRef getLocalSymbolBodies(); + ArrayRef getNonLocalSymbolBodies(); explicit ObjectFile(MemoryBufferRef M); void parse(llvm::DenseSet &ComdatGroups); @@ -118,16 +119,10 @@ ArrayRef *> getSections() const { return Sections; } InputSectionBase *getSection(const Elf_Sym &Sym) const; - SymbolBody *getSymbolBody(uint32_t SymbolIndex) const { - uint32_t FirstNonLocal = this->Symtab->sh_info; - if (SymbolIndex < FirstNonLocal) - return nullptr; - return SymbolBodies[SymbolIndex - FirstNonLocal]; + SymbolBody &getSymbolBody(uint32_t SymbolIndex) const { + return *SymbolBodies[SymbolIndex]; } - Elf_Sym_Range getLocalSymbols(); - const Elf_Sym *getLocalSymbol(uintX_t SymIndex); - const Elf_Shdr *getSymbolTable() const { return this->Symtab; }; // Get MIPS GP0 value defined by this file. This value represents the gp value Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -46,7 +46,7 @@ template typename ELFFileBase::Elf_Sym_Range -ELFFileBase::getSymbolsHelper(bool Local) { +ELFFileBase::getElfSymbols(bool OnlyGlobals) { if (!Symtab) return Elf_Sym_Range(nullptr, nullptr); Elf_Sym_Range Syms = ELFObj.symbols(Symtab); @@ -54,10 +54,10 @@ uint32_t FirstNonLocal = Symtab->sh_info; if (FirstNonLocal > NumSymbols) fatal("Invalid sh_info in symbol table"); - if (!Local) + + if (OnlyGlobals) return make_range(Syms.begin() + FirstNonLocal, Syms.end()); - // +1 to skip over dummy symbol. - return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal); + return make_range(Syms.begin(), Syms.end()); } template @@ -77,19 +77,30 @@ } template -typename ELFFileBase::Elf_Sym_Range -ELFFileBase::getNonLocalSymbols() { - return getSymbolsHelper(false); +elf::ObjectFile::ObjectFile(MemoryBufferRef M) + : ELFFileBase(Base::ObjectKind, M) {} + +template +ArrayRef elf::ObjectFile::getNonLocalSymbolBodies() { + if (!this->Symtab) + return this->SymbolBodies; + uint32_t FirstNonLocal = this->Symtab->sh_info; + return makeArrayRef(this->SymbolBodies).slice(FirstNonLocal); } template -elf::ObjectFile::ObjectFile(MemoryBufferRef M) - : ELFFileBase(Base::ObjectKind, M) {} +ArrayRef elf::ObjectFile::getLocalSymbolBodies() { + if (!this->Symtab) + return this->SymbolBodies; + uint32_t FirstNonLocal = this->Symtab->sh_info; + return makeArrayRef(this->SymbolBodies).slice(1, FirstNonLocal - 1); +} template -typename elf::ObjectFile::Elf_Sym_Range -elf::ObjectFile::getLocalSymbols() { - return this->getSymbolsHelper(true); +ArrayRef elf::ObjectFile::getSymbols() { + if (!this->Symtab) + return this->SymbolBodies; + return makeArrayRef(this->SymbolBodies).slice(1); } template uint32_t elf::ObjectFile::getMipsGp0() const { @@ -99,16 +110,6 @@ } template -const typename elf::ObjectFile::Elf_Sym * -elf::ObjectFile::getLocalSymbol(uintX_t SymIndex) { - uint32_t FirstNonLocal = this->Symtab->sh_info; - if (SymIndex >= FirstNonLocal) - return nullptr; - Elf_Sym_Range Syms = this->ELFObj.symbols(this->Symtab); - return Syms.begin() + SymIndex; -} - -template void elf::ObjectFile::parse(DenseSet &ComdatGroups) { // Read section and symbol tables. initializeSections(ComdatGroups); @@ -266,7 +267,7 @@ template void elf::ObjectFile::initializeSymbols() { this->initStringTable(); - Elf_Sym_Range Syms = this->getNonLocalSymbols(); + Elf_Sym_Range Syms = this->getElfSymbols(false); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); SymbolBodies.reserve(NumSymbols); for (const Elf_Sym &Sym : Syms) @@ -289,6 +290,10 @@ template SymbolBody *elf::ObjectFile::createSymbolBody(const Elf_Sym *Sym) { + unsigned char Binding = Sym->getBinding(); + if (Binding == STB_LOCAL) + return new (Alloc) LocalSymbol(*Sym); + StringRef Name = check(Sym->getName(this->StringTable)); switch (Sym->st_shndx) { @@ -300,7 +305,7 @@ Sym->getVisibility()); } - switch (Sym->getBinding()) { + switch (Binding) { default: fatal("Unexpected binding"); case STB_GLOBAL: @@ -399,7 +404,7 @@ // Fully parse the shared object file. This must be called after parseSoName(). template void SharedFile::parseRest() { - Elf_Sym_Range Syms = this->getNonLocalSymbols(); + Elf_Sym_Range Syms = this->getElfSymbols(true); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); SymbolBodies.reserve(NumSymbols); for (const Elf_Sym &Sym : Syms) { Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -77,12 +77,11 @@ InputSectionBase::getRelocTarget(const Elf_Rel &Rel) const { // Global symbol uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL); - if (SymbolBody *B = File->getSymbolBody(SymIndex)) - if (auto *D = dyn_cast>(B->repl())) - return D->Section->Repl; - // Local symbol - if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex)) - if (InputSectionBase *Sec = File->getSection(*Sym)) + SymbolBody &B = File->getSymbolBody(SymIndex).repl(); + if (auto *D = dyn_cast>(&B)) + return D->Section->Repl; + if (auto *L = dyn_cast>(&B)) + if (InputSectionBase *Sec = File->getSection(L->Sym)) return Sec; return nullptr; } @@ -122,24 +121,13 @@ for (const RelType &Rel : Rels) { uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL); uint32_t Type = Rel.getType(Config->Mips64EL); - const Elf_Shdr *SymTab = this->File->getSymbolTable(); + SymbolBody &Body = this->File->getSymbolBody(SymIndex).repl(); RelType *P = reinterpret_cast(Buf); Buf += sizeof(RelType); - // Relocation against local symbol here means that it is probably - // rel[a].eh_frame section which has references to sections in r_info field. - if (SymIndex < SymTab->sh_info) { - const Elf_Sym *Sym = this->File->getLocalSymbol(SymIndex); - uint32_t Idx = Out::SymTab->Locals[Sym]; - P->r_offset = RelocatedSection->getOffset(Rel.r_offset); - P->setSymbolAndType(Idx, Type, Config->Mips64EL); - continue; - } - - SymbolBody *Body = this->File->getSymbolBody(SymIndex)->repl(); P->r_offset = RelocatedSection->getOffset(Rel.r_offset); - P->setSymbolAndType(Body->DynsymIndex, Type, Config->Mips64EL); + P->setSymbolAndType(Body.DynsymIndex, Type, Config->Mips64EL); } } @@ -251,19 +239,16 @@ continue; } - const Elf_Shdr *SymTab = File->getSymbolTable(); - SymbolBody *Body = nullptr; - if (SymIndex >= SymTab->sh_info) - Body = File->getSymbolBody(SymIndex)->repl(); + SymbolBody &Body = File->getSymbolBody(SymIndex).repl(); - if (Target->canRelaxTls(Type, Body)) { + if (Target->canRelaxTls(Type, &Body)) { uintX_t SymVA; - if (!Body) + if (Body.isLocal()) SymVA = getLocalRelTarget(*File, RI, 0); - else if (Target->needsGot(Type, *Body)) - SymVA = Body->getGotVA(); + else if (Target->needsGot(Type, Body)) + SymVA = Body.getGotVA(); else - SymVA = Body->getVA(); + SymVA = Body.getVA(); // By optimizing TLS relocations, it is sometimes needed to skip // relocations that immediately follow TLS relocations. This function // knows how many slots we need to skip. @@ -274,7 +259,7 @@ // Handle relocations for local symbols -- they never get // resolved so we don't allocate a SymbolBody. uintX_t A = getAddend(RI); - if (!Body) { + if (Body.isLocal()) { uintX_t SymVA = getLocalRelTarget(*File, RI, A); uint8_t *PairedLoc = nullptr; if (Config->EMachine == EM_MIPS) { @@ -305,26 +290,26 @@ } if (Target->isTlsGlobalDynamicRel(Type) && - !Target->canRelaxTls(Type, Body)) { + !Target->canRelaxTls(Type, &Body)) { Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, - Out::Got->getGlobalDynAddr(*Body) + + Out::Got->getGlobalDynAddr(Body) + getAddend(RI)); continue; } - uintX_t SymVA = Body->getVA(); + uintX_t SymVA = Body.getVA(); bool CBP = canBePreempted(Body); - if (Target->needsPlt(Type, *Body)) { - SymVA = Body->getPltVA(); - } else if (Target->needsGot(Type, *Body)) { + if (Target->needsPlt(Type, Body)) { + SymVA = Body.getPltVA(); + } else if (Target->needsGot(Type, Body)) { if (Config->EMachine == EM_MIPS && !CBP) // Under some conditions relocations against non-local symbols require // entries in the local part of MIPS GOT. In that case we need an entry // initialized by full address of the symbol. - SymVA = Out::Got->getMipsLocalFullAddr(*Body); + SymVA = Out::Got->getMipsLocalFullAddr(Body); else - SymVA = Body->getGotVA(); - if (Body->IsTls) + SymVA = Body.getGotVA(); + if (Body.IsTls) Type = Target->getTlsGotRel(Type); } else if (Target->isSizeRel(Type) && CBP) { // A SIZE relocation is supposed to set a symbol size, but if a symbol @@ -333,16 +318,16 @@ // with a possibly incorrect value. continue; } else if (Config->EMachine == EM_MIPS) { - if (Type == R_MIPS_HI16 && Body == Config->MipsGpDisp) + if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp) SymVA = getMipsGpAddr() - AddrLoc; - else if (Type == R_MIPS_LO16 && Body == Config->MipsGpDisp) + else if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp) SymVA = getMipsGpAddr() - AddrLoc + 4; - else if (Body == Config->MipsLocalGp) + else if (&Body == Config->MipsLocalGp) SymVA = getMipsGpAddr(); - } else if (!Target->needsCopyRel(Type, *Body) && CBP) { + } else if (!Target->needsCopyRel(Type, Body) && CBP) { continue; } - uintX_t Size = Body->getSize(); + uintX_t Size = Body.getSize(); Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + A, Size + A, findMipsPairedReloc(Buf, SymIndex, getMipsPairedRelocType(Type), Index: ELF/MarkLive.cpp =================================================================== --- ELF/MarkLive.cpp +++ ELF/MarkLive.cpp @@ -99,7 +99,7 @@ auto MarkSymbol = [&](SymbolBody *Sym) { if (Sym) - if (auto *D = dyn_cast>(Sym->repl())) + if (auto *D = dyn_cast>(&Sym->repl())) Enqueue(D->Section); }; Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -47,7 +47,7 @@ return Rel.r_addend; } -bool canBePreempted(const SymbolBody *Body); +bool canBePreempted(const SymbolBody &Body); bool isValidCIdentifier(StringRef S); @@ -106,9 +106,9 @@ GotSection(); void finalize() override; void writeTo(uint8_t *Buf) override; - void addEntry(SymbolBody *Sym); + void addEntry(SymbolBody &Sym); void addMipsLocalEntry(); - bool addDynTlsEntry(SymbolBody *Sym); + bool addDynTlsEntry(SymbolBody &Sym); bool addTlsIndex(); bool empty() const { return MipsLocalEntries == 0 && Entries.empty(); } uintX_t getMipsLocalFullAddr(const SymbolBody &B); @@ -145,7 +145,7 @@ GotPltSection(); void finalize() override; void writeTo(uint8_t *Buf) override; - void addEntry(SymbolBody *Sym); + void addEntry(SymbolBody &Sym); bool empty() const; private: @@ -160,7 +160,7 @@ PltSection(); void finalize() override; void writeTo(uint8_t *Buf) override; - void addEntry(SymbolBody *Sym); + void addEntry(SymbolBody &Sym); bool empty() const { return Entries.empty(); } private: @@ -235,9 +235,6 @@ unsigned NumLocals = 0; StringTableSection &StrTabSec; - // Local symbol -> ID, filled only when producing relocatable output. - llvm::DenseMap Locals; - private: void writeLocalSymbols(uint8_t *&Buf); void writeGlobalSymbols(uint8_t *Buf); Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -52,9 +52,9 @@ this->Header.sh_addralign = sizeof(uintX_t); } -template void GotPltSection::addEntry(SymbolBody *Sym) { - Sym->GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size(); - Entries.push_back(Sym); +template void GotPltSection::addEntry(SymbolBody &Sym) { + Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size(); + Entries.push_back(&Sym); } template bool GotPltSection::empty() const { @@ -83,21 +83,21 @@ this->Header.sh_addralign = sizeof(uintX_t); } -template void GotSection::addEntry(SymbolBody *Sym) { - Sym->GotIndex = Entries.size(); - Entries.push_back(Sym); +template void GotSection::addEntry(SymbolBody &Sym) { + Sym.GotIndex = Entries.size(); + Entries.push_back(&Sym); } template void GotSection::addMipsLocalEntry() { ++MipsLocalEntries; } -template bool GotSection::addDynTlsEntry(SymbolBody *Sym) { - if (Sym->hasGlobalDynIndex()) +template bool GotSection::addDynTlsEntry(SymbolBody &Sym) { + if (Sym.hasGlobalDynIndex()) return false; - Sym->GlobalDynIndex = Target->GotHeaderEntriesNum + Entries.size(); + Sym.GlobalDynIndex = Target->GotHeaderEntriesNum + Entries.size(); // Global Dynamic TLS entries take two GOT slots. - Entries.push_back(Sym); + Entries.push_back(&Sym); Entries.push_back(nullptr); return true; } @@ -176,7 +176,7 @@ // for detailed description: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf // As the first approach, we can just store addresses for all symbols. - if (Config->EMachine != EM_MIPS && canBePreempted(B)) + if (Config->EMachine != EM_MIPS && canBePreempted(*B)) continue; // The dynamic linker will take care of it. uintX_t VA = B->getVA(); write(Entry, VA); @@ -208,12 +208,12 @@ } } -template void PltSection::addEntry(SymbolBody *Sym) { - Sym->PltIndex = Entries.size(); +template void PltSection::addEntry(SymbolBody &Sym) { + Sym.PltIndex = Entries.size(); unsigned RelOff = Target->UseLazyBinding ? Out::RelaPlt->getRelocOffset() : Out::RelaDyn->getRelocOffset(); - Entries.push_back(std::make_pair(Sym, RelOff)); + Entries.push_back(std::make_pair(&Sym, RelOff)); } template void PltSection::finalize() { @@ -890,14 +890,15 @@ // 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. -bool elf::canBePreempted(const SymbolBody *Body) { - if (!Body) - return false; // Body is a local symbol. - if (Body->isShared()) +bool elf::canBePreempted(const SymbolBody &Body) { + if (Body.isLocal()) + return false; + + if (Body.isShared()) return true; - if (Body->isUndefined()) { - if (!Body->isWeak()) + if (Body.isUndefined()) { + if (!Body.isWeak()) return true; // Ideally the static linker should see a definition for every symbol, but @@ -911,9 +912,9 @@ } if (!Config->Shared) return false; - if (Body->getVisibility() != STV_DEFAULT) + if (Body.getVisibility() != STV_DEFAULT) return false; - if (Config->Bsymbolic || (Config->BsymbolicFunctions && Body->IsFunc)) + if (Config->Bsymbolic || (Config->BsymbolicFunctions && Body.IsFunc)) return false; return true; } @@ -1126,7 +1127,7 @@ SymbolBody *Personality = nullptr; if (HasReloc) { uint32_t SymIndex = RelI->getSymbol(Config->Mips64EL); - Personality = S->getFile()->getSymbolBody(SymIndex)->repl(); + Personality = &S->getFile()->getSymbolBody(SymIndex).repl(); } std::pair CieInfo(Entry, Personality); @@ -1490,9 +1491,9 @@ case SymbolBody::DefinedSyntheticKind: return &cast>(Sym)->Section; case SymbolBody::DefinedRegularKind: { - auto *D = cast>(Sym->repl()); - if (D->Section) - return D->Section->OutSec; + auto &D = cast>(Sym->repl()); + if (D.Section) + return D.Section->OutSec; break; } case SymbolBody::DefinedCommonKind: @@ -1507,6 +1508,8 @@ break; case SymbolBody::DefinedBitcodeKind: llvm_unreachable("Should have been replaced"); + case SymbolBody::DefinedLocalKind: + llvm_unreachable("Should not be used"); } return nullptr; } Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -92,7 +92,7 @@ auto *F = cast>(FileP); ObjectFiles.emplace_back(cast>(File.release())); F->parse(ComdatGroups); - for (SymbolBody *B : F->getSymbols()) + for (SymbolBody *B : F->getNonLocalSymbolBodies()) resolve(B); } @@ -146,7 +146,7 @@ /*ShouldLazyLoadMetadata*/ false)); std::vector Keep; for (SymbolBody *B : F.getSymbols()) { - if (B->repl() != B) + if (&B->repl() != B) continue; auto *DB = dyn_cast(B); if (!DB) @@ -189,7 +189,7 @@ ObjectFile *Obj = createCombinedLtoObject(); llvm::DenseSet DummyGroups; Obj->parse(DummyGroups); - for (SymbolBody *Body : Obj->getSymbols()) { + for (SymbolBody *Body : Obj->getNonLocalSymbolBodies()) { Symbol *Sym = insert(Body); if (!Sym->Body->isUndefined() && Body->isUndefined()) continue; Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -62,7 +62,8 @@ DefinedFirst, DefinedRegularKind = DefinedFirst, SharedKind, - DefinedElfLast = SharedKind, + DefinedLocalKind, + DefinedElfLast = DefinedLocalKind, DefinedCommonKind, DefinedBitcodeKind, DefinedSyntheticKind, @@ -82,6 +83,7 @@ bool isCommon() const { return SymbolKind == DefinedCommonKind; } bool isLazy() const { return SymbolKind == LazyKind; } bool isShared() const { return SymbolKind == SharedKind; } + bool isLocal() const { return SymbolKind == DefinedLocalKind; } bool isUsedInRegularObj() const { return IsUsedInRegularObj; } // Returns the symbol name. @@ -116,7 +118,7 @@ // has chosen the object among other objects having the same name, // you can access P->Backref->Body to get the resolver's result. void setBackref(Symbol *P) { Backref = P; } - SymbolBody *repl() { return Backref ? Backref->Body : this; } + SymbolBody &repl() { return Backref ? *Backref->Body : *this; } Symbol *getSymbol() { return Backref; } // Decides which symbol should "win" in the symbol table, this or @@ -307,6 +309,18 @@ bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->IsFunc; } }; +template class LocalSymbol : public DefinedElf { + typedef typename llvm::object::ELFFile::Elf_Sym Elf_Sym; + +public: + LocalSymbol(const Elf_Sym &Sym) + : DefinedElf(SymbolBody::DefinedLocalKind, "", Sym) {} + + static bool classof(const SymbolBody *S) { + return S->kind() == SymbolBody::DefinedLocalKind; + } +}; + // This class represents a symbol defined in an archive file. It is // created from an archive file header, and it knows how to load an // object file from an archive to replace itself with a defined Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -68,6 +68,8 @@ return 0; case DefinedBitcodeKind: llvm_unreachable("Should have been replaced"); + case DefinedLocalKind: + llvm_unreachable("Should not be used"); } llvm_unreachable("Invalid symbol kind"); } Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -70,7 +70,7 @@ template bool needsCopyRel(uint32_t Type, const SymbolBody &S) const; virtual size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, - uint64_t P, uint64_t SA, const SymbolBody *S) const; + uint64_t P, uint64_t SA, const SymbolBody &S) const; virtual ~TargetInfo(); unsigned PageSize = 4096; Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -99,7 +99,7 @@ uint64_t SA, uint64_t ZA = 0, uint8_t *PairedLoc = nullptr) const override; size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, - uint64_t SA, const SymbolBody *S) const override; + uint64_t SA, const SymbolBody &S) const override; bool isGotRelative(uint32_t Type) const override; bool refersToGotEntry(uint32_t Type) const override; @@ -137,7 +137,7 @@ bool isRelRelative(uint32_t Type) const override; bool isSizeRel(uint32_t Type) const override; size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, - uint64_t SA, const SymbolBody *S) const override; + uint64_t SA, const SymbolBody &S) const override; private: void relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, @@ -191,7 +191,7 @@ uint64_t SA, uint64_t ZA = 0, uint8_t *PairedLoc = nullptr) const override; size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, - uint64_t SA, const SymbolBody *S) const override; + uint64_t SA, const SymbolBody &S) const override; private: void relocateTlsGdToLe(uint32_t Type, uint8_t *Loc, uint8_t *BufEnd, @@ -278,7 +278,7 @@ // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally // defined. if (isTlsInitialExecRel(Type)) - return !canBePreempted(S); + return !canBePreempted(*S); return false; } @@ -317,7 +317,7 @@ const SymbolBody &S) const { if (isGnuIFunc(S)) return Plt_Explicit; - if (canBePreempted(&S) && needsPltImpl(Type)) + if (canBePreempted(S) && needsPltImpl(Type)) return Plt_Explicit; // This handles a non PIC program call to function in a shared library. @@ -363,7 +363,7 @@ size_t TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, - const SymbolBody *S) const { + const SymbolBody &S) const { return 0; } @@ -470,7 +470,7 @@ bool X86TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const { if (S.IsTls && Type == R_386_TLS_GD) - return Target->canRelaxTls(Type, &S) && canBePreempted(&S); + return Target->canRelaxTls(Type, &S) && canBePreempted(S); if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE) return !canRelaxTls(Type, &S); return Type == R_386_GOT32 || needsPlt(Type, S); @@ -545,7 +545,7 @@ size_t X86TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, - const SymbolBody *S) const { + const SymbolBody &S) const { switch (Type) { case R_386_TLS_GD: if (canBePreempted(S)) @@ -732,7 +732,7 @@ bool X86_64TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const { if (Type == R_X86_64_TLSGD) - return Target->canRelaxTls(Type, &S) && canBePreempted(&S); + return Target->canRelaxTls(Type, &S) && canBePreempted(S); if (Type == R_X86_64_GOTTPOFF) return !canRelaxTls(Type, &S); return refersToGotEntry(Type) || needsPlt(Type, S); @@ -890,7 +890,7 @@ // This function returns a number of relocations that need to be skipped. size_t X86_64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, - const SymbolBody *S) const { + const SymbolBody &S) const { switch (Type) { case R_X86_64_DTPOFF32: relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA); @@ -1463,7 +1463,7 @@ size_t AArch64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t SA, - const SymbolBody *S) const { + const SymbolBody &S) const { switch (Type) { case R_AARCH64_TLSDESC_ADR_PAGE21: case R_AARCH64_TLSDESC_LD64_LO12_NC: @@ -1471,13 +1471,13 @@ case R_AARCH64_TLSDESC_CALL: { if (canBePreempted(S)) fatal("Unsupported TLS optimization"); - uint64_t X = S ? S->getVA() : SA; + uint64_t X = S.getVA(); relocateTlsGdToLe(Type, Loc, BufEnd, P, X); return 0; } case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: - relocateTlsIeToLe(Type, Loc, BufEnd, P, S->getVA()); + relocateTlsIeToLe(Type, Loc, BufEnd, P, S.getVA()); return 0; } llvm_unreachable("Unknown TLS optimization"); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -256,7 +256,7 @@ } template -static bool handleTlsRelocation(uint32_t Type, SymbolBody *Body, +static bool handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, RelT &RI) { if (Target->pointsToLocalDynamicGotEntry(Type)) { if (Target->canRelaxTls(Type, nullptr)) @@ -268,16 +268,17 @@ return true; } - if (!Body || !Body->IsTls) + if (!Body.IsTls) return false; if (Target->isTlsGlobalDynamicRel(Type)) { - if (!Target->canRelaxTls(Type, Body)) { + if (!Target->canRelaxTls(Type, &Body)) { if (Out::Got->addDynTlsEntry(Body)) { Out::RelaDyn->addReloc({Target->TlsModuleIndexRel, - DynamicReloc::Off_GTlsIndex, Body}); + DynamicReloc::Off_GTlsIndex, + &Body}); Out::RelaDyn->addReloc( - {Target->TlsOffsetRel, DynamicReloc::Off_GTlsOffset, Body}); + {Target->TlsOffsetRel, DynamicReloc::Off_GTlsOffset, &Body}); } return true; } @@ -309,7 +310,8 @@ const ObjectFile &File = *C.getFile(); for (const RelType &RI : Rels) { uint32_t SymIndex = RI.getSymbol(Config->Mips64EL); - SymbolBody *Body = File.getSymbolBody(SymIndex); + SymbolBody &OrigBody = File.getSymbolBody(SymIndex); + SymbolBody &Body = OrigBody.repl(); uint32_t Type = RI.getType(Config->Mips64EL); // Ignore "hint" relocation because it is for optional code optimization. @@ -320,20 +322,17 @@ HasGotOffRel = true; // Set "used" bit for --as-needed. - if (Body && Body->isUndefined() && !Body->isWeak()) - if (auto *S = dyn_cast>(Body->repl())) + if (OrigBody.isUndefined() && !OrigBody.isWeak()) + if (auto *S = dyn_cast>(&Body)) S->File->IsUsed = true; - if (Body) - Body = Body->repl(); - bool CBP = canBePreempted(Body); if (handleTlsRelocation(Type, Body, C, RI)) continue; if (Target->needsDynRelative(Type)) Out::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true, - Body, getAddend(RI)}); + &Body, getAddend(RI)}); // MIPS has a special rule to create GOTs for local symbols. if (Config->EMachine == EM_MIPS && !CBP && @@ -345,7 +344,7 @@ // If a symbol in a DSO is referenced directly instead of through GOT, // we need to create a copy relocation for the symbol. - if (auto *B = dyn_cast_or_null>(Body)) { + if (auto *B = dyn_cast_or_null>(&Body)) { if (B->needsCopy()) continue; if (Target->needsCopyRel(Type, *B)) { @@ -359,53 +358,51 @@ // An STT_GNU_IFUNC symbol always uses a PLT entry, and all references // to the symbol go through the PLT. This is true even for a local // symbol, although local symbols normally do not require PLT entries. - if (Body && isGnuIFunc(*Body)) { - if (Body->isInPlt()) + if (isGnuIFunc(Body)) { + if (Body.isInPlt()) continue; Out::Plt->addEntry(Body); if (Target->UseLazyBinding) { Out::GotPlt->addEntry(Body); Out::RelaPlt->addReloc( {CBP ? Target->PltRel : Target->IRelativeRel, - DynamicReloc::Off_GotPlt, !CBP, Body}); + DynamicReloc::Off_GotPlt, !CBP, &Body}); } else { Out::Got->addEntry(Body); Out::RelaDyn->addReloc( {CBP ? Target->PltRel : Target->IRelativeRel, - DynamicReloc::Off_Got, !CBP, Body}); + DynamicReloc::Off_Got, !CBP, &Body}); } continue; } // If a relocation needs PLT, we create a PLT and a GOT slot // for the symbol. - TargetInfo::PltNeed NeedPlt = TargetInfo::Plt_No; - if (Body) - NeedPlt = Target->needsPlt(Type, *Body); + TargetInfo::PltNeed NeedPlt = Target->needsPlt(Type, Body); if (NeedPlt) { if (NeedPlt == TargetInfo::Plt_Implicit) - Body->NeedsCopyOrPltAddr = true; - if (Body->isInPlt()) + Body.NeedsCopyOrPltAddr = true; + if (Body.isInPlt()) continue; Out::Plt->addEntry(Body); if (Target->UseLazyBinding) { Out::GotPlt->addEntry(Body); Out::RelaPlt->addReloc( - {Target->PltRel, DynamicReloc::Off_GotPlt, Body}); + {Target->PltRel, DynamicReloc::Off_GotPlt, &Body}); } else { - if (Body->isInGot()) + if (Body.isInGot()) continue; Out::Got->addEntry(Body); Out::RelaDyn->addReloc( - {Target->GotRel, DynamicReloc::Off_Got, Body}); + {Target->GotRel, DynamicReloc::Off_Got, &Body}); } continue; } // If a relocation needs GOT, we create a GOT slot for the symbol. - if (Body && Target->needsGot(Type, *Body)) { - if (Body->isInGot()) + if (Target->needsGot(Type, Body)) { + if (Body.isInGot()) continue; Out::Got->addEntry(Body); @@ -415,7 +412,7 @@ // See "Global Offset Table" in Chapter 5 in the following document // for detailed description: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - Body->MustBeInDynSym = true; + Body.MustBeInDynSym = true; continue; } @@ -424,11 +421,11 @@ if (CBP || Dynrel) { uint32_t DynType; if (CBP) - DynType = Body->IsTls ? Target->TlsGotRel : Target->GotRel; + DynType = Body.IsTls ? Target->TlsGotRel : Target->GotRel; else DynType = Target->RelativeRel; Out::RelaDyn->addReloc( - {DynType, DynamicReloc::Off_Got, !CBP, Body}); + {DynType, DynamicReloc::Off_Got, !CBP, &Body}); } continue; } @@ -443,7 +440,7 @@ // relocation too because that case is possible for executable file // linking only. continue; - if (Body == Config->MipsGpDisp || Body == Config->MipsLocalGp) + if (&Body == Config->MipsGpDisp || &Body == Config->MipsLocalGp) // MIPS _gp_disp designates offset between start of function and 'gp' // pointer into GOT. __gnu_local_gp is equal to the current value of // the 'gp'. Therefore any relocations against them do not require @@ -455,7 +452,7 @@ // We don't know anything about the finaly symbol. Just ask the dynamic // linker to handle the relocation for us. Out::RelaDyn->addReloc({Target->getDynRel(Type), &C, RI.r_offset, - false, Body, getAddend(RI)}); + false, &Body, getAddend(RI)}); continue; } @@ -477,16 +474,15 @@ (uintX_t)getPPC64TocBase() + Addend}); continue; } - if (Body) { + if (!Body.isLocal()) { Out::RelaDyn->addReloc( - {Target->RelativeRel, &C, RI.r_offset, true, Body, Addend}); + {Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend}); continue; } - const Elf_Sym *Sym = - File.getObj().getRelocationSymbol(&RI, File.getSymbolTable()); - InputSectionBase *Section = File.getSection(*Sym); - uintX_t Offset = Sym->st_value; - if (Sym->getType() == STT_SECTION) { + const Elf_Sym &Sym = cast>(Body).Sym; + InputSectionBase *Section = File.getSection(Sym); + uintX_t Offset = Sym.st_value; + if (Sym.getType() == STT_SECTION) { Offset += Addend; Addend = 0; } @@ -563,7 +559,9 @@ if (!Out::SymTab) return; for (const std::unique_ptr> &F : Symtab.getObjectFiles()) { - for (const Elf_Sym &Sym : F->getLocalSymbols()) { + for (SymbolBody *B : F->getLocalSymbolBodies()) { + auto *L = dyn_cast>(B); + const Elf_Sym &Sym = cast>(B)->Sym; StringRef SymName = check(Sym.getName(F->getStringTable())); if (!shouldKeepInSymtab(*F, SymName, Sym)) continue; @@ -577,7 +575,7 @@ } ++Out::SymTab->NumLocals; if (Config->Relocatable) - Out::SymTab->Locals[&Sym] = Out::SymTab->NumLocals; + L->DynsymIndex = Out::SymTab->NumLocals; F->KeptLocalSyms.push_back(std::make_pair( &Sym, Out::SymTab->StrTabSec.addString(SymName))); } @@ -1428,11 +1426,8 @@ template static typename ELFFile::uintX_t getEntryAddr() { - if (Config->EntrySym) { - if (SymbolBody *B = Config->EntrySym->repl()) - return B->getVA(); - return 0; - } + if (SymbolBody *B = Config->EntrySym) + return B->repl().getVA(); if (Config->EntryAddr != uint64_t(-1)) return Config->EntryAddr; return 0;