Skip to content

Commit

Permalink
ELF: De-template ELFFileBase. NFCI.
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D60304

llvm-svn: 357806
  • Loading branch information
pcc committed Apr 5, 2019
1 parent c8f78f8 commit 883ab23
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 67 deletions.
2 changes: 1 addition & 1 deletion lld/ELF/Arch/Mips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ bool MIPS<ELFT>::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
if (Type != R_MIPS_26 && Type != R_MIPS_PC26_S2 &&
Type != R_MICROMIPS_26_S1 && Type != R_MICROMIPS_PC26_S1)
return false;
auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
auto *F = dyn_cast_or_null<ObjFile<ELFT>>(File);
if (!F)
return false;
// If current file has PIC code, LA25 stub is not required.
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Arch/MipsArchTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,8 @@ uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
}

template <class ELFT> static bool isN32Abi(const InputFile *F) {
if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
if (auto *EF = dyn_cast<ELFFileBase>(F))
return EF->template getObj<ELFT>().getHeader()->e_flags & EF_MIPS_ABI2;
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/DWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ LLDDwarfObj<ELFT>::findAux(const InputSectionBase &Sec, uint64_t Pos,

const ObjFile<ELFT> *File = Sec.getFile<ELFT>();
uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
const typename ELFT::Sym &Sym = File->getELFSyms()[SymIndex];
const typename ELFT::Sym &Sym = File->template getELFSyms<ELFT>()[SymIndex];
uint32_t SecIndex = File->getSectionIndex(Sym);

// Broken debug info can point to a non-Defined symbol.
Expand Down
82 changes: 40 additions & 42 deletions lld/ELF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,45 +241,46 @@ std::string lld::toString(const InputFile *F) {
return F->ToStringCache;
}

template <class ELFT>
ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
ELFFileBase::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {}

template <class ELFT> void ELFFileBase::parseHeader() {
if (ELFT::TargetEndianness == support::little)
EKind = ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
else
EKind = ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;

EMachine = getObj().getHeader()->e_machine;
OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
ABIVersion = getObj().getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
EMachine = getObj<ELFT>().getHeader()->e_machine;
OSABI = getObj<ELFT>().getHeader()->e_ident[llvm::ELF::EI_OSABI];
ABIVersion = getObj<ELFT>().getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
}

template <class ELFT>
typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalELFSyms() {
return makeArrayRef(ELFSyms.begin() + FirstGlobal, ELFSyms.end());
}

template <class ELFT>
void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections,
const Elf_Shdr *Symtab) {
void ELFFileBase::initSymtab(ArrayRef<typename ELFT::Shdr> Sections,
const typename ELFT::Shdr *Symtab) {
FirstGlobal = Symtab->sh_info;
ELFSyms = CHECK(getObj().symbols(Symtab), this);
ArrayRef<typename ELFT::Sym> ELFSyms =
CHECK(getObj<ELFT>().symbols(Symtab), this);
if (FirstGlobal == 0 || FirstGlobal > ELFSyms.size())
fatal(toString(this) + ": invalid sh_info in symbol table");
this->ELFSyms = reinterpret_cast<const void *>(ELFSyms.data());
this->NumELFSyms = ELFSyms.size();

StringTable =
CHECK(getObj().getStringTableForSymtab(*Symtab, Sections), this);
CHECK(getObj<ELFT>().getStringTableForSymtab(*Symtab, Sections), this);
}

template <class ELFT>
ObjFile<ELFT>::ObjFile(MemoryBufferRef M, StringRef ArchiveName)
: ELFFileBase<ELFT>(Base::ObjKind, M) {
: ELFFileBase(ObjKind, M) {
parseHeader<ELFT>();
this->ArchiveName = ArchiveName;
}

template <class ELFT>
uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
return CHECK(this->getObj().getSectionIndex(&Sym, this->ELFSyms, SymtabSHNDX),
this);
return CHECK(
this->getObj().getSectionIndex(&Sym, getELFSyms<ELFT>(), SymtabSHNDX),
this);
}

template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getLocalSymbols() {
Expand Down Expand Up @@ -312,12 +313,12 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
const Elf_Shdr &Sec) {
// Group signatures are stored as symbol names in object files.
// sh_info contains a symbol index, so we fetch a symbol and read its name.
if (this->ELFSyms.empty())
this->initSymtab(
if (this->getELFSyms<ELFT>().empty())
this->initSymtab<ELFT>(
Sections, CHECK(object::getSection<ELFT>(Sections, Sec.sh_link), this));

const Elf_Sym *Sym =
CHECK(object::getSymbol<ELFT>(this->ELFSyms, Sec.sh_info), this);
CHECK(object::getSymbol<ELFT>(this->getELFSyms<ELFT>(), Sec.sh_info), this);
StringRef Signature = CHECK(Sym->getName(this->StringTable), this);

// As a special case, if a symbol is a section symbol and has no name,
Expand Down Expand Up @@ -392,7 +393,7 @@ template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
for (const Elf_Shdr &Sec : ObjSections) {
if (Sec.sh_type != SHT_SYMTAB)
continue;
this->initSymtab(ObjSections, &Sec);
this->initSymtab<ELFT>(ObjSections, &Sec);
return;
}
}
Expand Down Expand Up @@ -475,10 +476,10 @@ void ObjFile<ELFT>::initializeSections(
break;
}
case SHT_SYMTAB:
this->initSymtab(ObjSections, &Sec);
this->initSymtab<ELFT>(ObjSections, &Sec);
break;
case SHT_SYMTAB_SHNDX:
this->SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
break;
case SHT_STRTAB:
case SHT_NULL:
Expand Down Expand Up @@ -678,12 +679,12 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
}

if (Sec.sh_type == SHT_RELA) {
ArrayRef<Elf_Rela> Rels = CHECK(this->getObj().relas(&Sec), this);
ArrayRef<Elf_Rela> Rels = CHECK(getObj().relas(&Sec), this);
Target->FirstRelocation = Rels.begin();
Target->NumRelocations = Rels.size();
Target->AreRelocsRela = true;
} else {
ArrayRef<Elf_Rel> Rels = CHECK(this->getObj().rels(&Sec), this);
ArrayRef<Elf_Rel> Rels = CHECK(getObj().rels(&Sec), this);
Target->FirstRelocation = Rels.begin();
Target->NumRelocations = Rels.size();
Target->AreRelocsRela = false;
Expand Down Expand Up @@ -771,19 +772,19 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {

template <class ELFT>
StringRef ObjFile<ELFT>::getSectionName(const Elf_Shdr &Sec) {
return CHECK(this->getObj().getSectionName(&Sec, SectionStringTable), this);
return CHECK(getObj().getSectionName(&Sec, SectionStringTable), this);
}

template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
this->Symbols.reserve(this->ELFSyms.size());
for (const Elf_Sym &Sym : this->ELFSyms)
this->Symbols.reserve(this->getELFSyms<ELFT>().size());
for (const Elf_Sym &Sym : this->getELFSyms<ELFT>())
this->Symbols.push_back(createSymbol(&Sym));
}

template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
int Binding = Sym->getBinding();

uint32_t SecIdx = this->getSectionIndex(*Sym);
uint32_t SecIdx = getSectionIndex(*Sym);
if (SecIdx >= this->Sections.size())
fatal(toString(this) + ": invalid section index: " + Twine(SecIdx));

Expand Down Expand Up @@ -870,14 +871,16 @@ InputFile *ArchiveFile::fetch(const Archive::Symbol &Sym) {

template <class ELFT>
SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
: ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName),
IsNeeded(!Config->AsNeeded) {}
: ELFFileBase(SharedKind, M), SoName(DefaultSoName),
IsNeeded(!Config->AsNeeded) {
parseHeader<ELFT>();
}

// Partially parse the shared object file so that we can call
// getSoName on this object.
template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
ArrayRef<Elf_Dyn> DynamicTags;
const ELFFile<ELFT> Obj = this->getObj();
const ELFFile<ELFT> Obj = this->getObj<ELFT>();
ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);

// Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
Expand All @@ -886,7 +889,7 @@ template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
default:
continue;
case SHT_DYNSYM:
this->initSymtab(Sections, &Sec);
this->initSymtab<ELFT>(Sections, &Sec);
break;
case SHT_DYNAMIC:
DynamicTags =
Expand All @@ -901,7 +904,7 @@ template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
}
}

if (this->VersymSec && this->ELFSyms.empty())
if (this->VersymSec && this->getELFSyms<ELFT>().empty())
error("SHT_GNU_versym should be associated with symbol table");

// Search for a DT_SONAME tag to initialize this->SoName.
Expand All @@ -923,7 +926,7 @@ template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
// Parses ".gnu.version" section which is a parallel array for the symbol table.
// If a given file doesn't have ".gnu.version" section, returns VER_NDX_GLOBAL.
template <class ELFT> std::vector<uint32_t> SharedFile<ELFT>::parseVersyms() {
size_t Size = this->ELFSyms.size() - this->FirstGlobal;
size_t Size = this->getELFSyms<ELFT>().size() - this->FirstGlobal;
if (!VersymSec)
return std::vector<uint32_t>(Size, VER_NDX_GLOBAL);

Expand Down Expand Up @@ -1001,15 +1004,15 @@ uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections,
template <class ELFT> void SharedFile<ELFT>::parseRest() {
Verdefs = parseVerdefs(); // parse .gnu.version_d
std::vector<uint32_t> Versyms = parseVersyms(); // parse .gnu.version
ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this);
ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj<ELFT>().sections(), this);

// System libraries can have a lot of symbols with versions. Using a
// fixed buffer for computing the versions name (foo@ver) can save a
// lot of allocations.
SmallString<0> VersionedNameBuffer;

// Add symbols to the symbol table.
ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms();
ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms<ELFT>();
for (size_t I = 0; I < Syms.size(); ++I) {
const Elf_Sym &Sym = Syms[I];

Expand Down Expand Up @@ -1347,11 +1350,6 @@ template void LazyObjFile::parse<ELF32BE>();
template void LazyObjFile::parse<ELF64LE>();
template void LazyObjFile::parse<ELF64BE>();

template class elf::ELFFileBase<ELF32LE>;
template class elf::ELFFileBase<ELF32BE>;
template class elf::ELFFileBase<ELF64LE>;
template class elf::ELFFileBase<ELF64BE>;

template class elf::ObjFile<ELF32LE>;
template class elf::ObjFile<ELF32BE>;
template class elf::ObjFile<ELF64LE>;
Expand Down
42 changes: 23 additions & 19 deletions lld/ELF/InputFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,35 +145,38 @@ class InputFile {
const Kind FileKind;
};

template <typename ELFT> class ELFFileBase : public InputFile {
class ELFFileBase : public InputFile {
public:
using Elf_Shdr = typename ELFT::Shdr;
using Elf_Sym = typename ELFT::Sym;
using Elf_Word = typename ELFT::Word;
using Elf_Sym_Range = typename ELFT::SymRange;

ELFFileBase(Kind K, MemoryBufferRef M);
template <typename ELFT> void parseHeader();
static bool classof(const InputFile *F) { return F->isElf(); }

llvm::object::ELFFile<ELFT> getObj() const {
template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
}

StringRef getStringTable() const { return StringTable; }

Elf_Sym_Range getGlobalELFSyms();
Elf_Sym_Range getELFSyms() const { return ELFSyms; }
template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
return typename ELFT::SymRange(
reinterpret_cast<const typename ELFT::Sym *>(ELFSyms), NumELFSyms);
}
template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const {
return getELFSyms<ELFT>().slice(FirstGlobal);
}

protected:
ArrayRef<Elf_Sym> ELFSyms;
const void *ELFSyms = nullptr;
size_t NumELFSyms = 0;
uint32_t FirstGlobal = 0;
StringRef StringTable;
void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab);
template <typename ELFT>
void initSymtab(ArrayRef<typename ELFT::Shdr> Sections,
const typename ELFT::Shdr *Symtab);
};

// .o file.
template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
using Base = ELFFileBase<ELFT>;
template <class ELFT> class ObjFile : public ELFFileBase {
using Elf_Rel = typename ELFT::Rel;
using Elf_Rela = typename ELFT::Rela;
using Elf_Sym = typename ELFT::Sym;
Expand All @@ -185,7 +188,11 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
const Elf_Shdr &Sec);

public:
static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
static bool classof(const InputFile *F) { return F->kind() == ObjKind; }

llvm::object::ELFFile<ELFT> getObj() const {
return this->ELFFileBase::getObj<ELFT>();
}

ArrayRef<Symbol *> getLocalSymbols();
ArrayRef<Symbol *> getGlobalSymbols();
Expand Down Expand Up @@ -321,8 +328,7 @@ class BitcodeFile : public InputFile {
};

// .so file.
template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
using Base = ELFFileBase<ELFT>;
template <class ELFT> class SharedFile : public ELFFileBase {
using Elf_Dyn = typename ELFT::Dyn;
using Elf_Shdr = typename ELFT::Shdr;
using Elf_Sym = typename ELFT::Sym;
Expand All @@ -338,9 +344,7 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
std::vector<StringRef> DtNeeded;
std::string SoName;

static bool classof(const InputFile *F) {
return F->kind() == Base::SharedKind;
}
static bool classof(const InputFile *F) { return F->kind() == SharedKind; }

SharedFile(MemoryBufferRef M, StringRef DefaultSoName);

Expand Down
5 changes: 3 additions & 2 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,8 @@ template <class ELFT> static bool isReadOnly(SharedSymbol &SS) {

// Determine if the symbol is read-only by scanning the DSO's program headers.
const SharedFile<ELFT> &File = SS.getFile<ELFT>();
for (const Elf_Phdr &Phdr : check(File.getObj().program_headers()))
for (const Elf_Phdr &Phdr :
check(File.template getObj<ELFT>().program_headers()))
if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
!(Phdr.p_flags & ELF::PF_W) && SS.Value >= Phdr.p_vaddr &&
SS.Value < Phdr.p_vaddr + Phdr.p_memsz)
Expand All @@ -503,7 +504,7 @@ static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
SharedFile<ELFT> &File = SS.getFile<ELFT>();

SmallSet<SharedSymbol *, 4> Ret;
for (const Elf_Sym &S : File.getGlobalELFSyms()) {
for (const Elf_Sym &S : File.template getGlobalELFSyms<ELFT>()) {
if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||
S.getType() == STT_TLS || S.st_value != SS.Value)
continue;
Expand Down

0 comments on commit 883ab23

Please sign in to comment.