Merge ELFFileBase::{initSymtab,parseHeader} as ELFFileBase:init. NFC.
This patch simplifies ELFFile instance initialization by merging two similar functions into a single function and call it from the ctor. llvm-svn: 361789
This commit is contained in:
parent
50d502826b
commit
92069605bf
|
@ -368,39 +368,66 @@ std::string lld::toString(const InputFile *F) {
|
||||||
return F->ToStringCache;
|
return F->ToStringCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
ELFFileBase::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {}
|
ELFFileBase::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
|
||||||
|
EKind = getELFKind(MB, "");
|
||||||
|
|
||||||
template <class ELFT> void ELFFileBase::parseHeader() {
|
switch (EKind) {
|
||||||
if (ELFT::TargetEndianness == support::little)
|
case ELF32LEKind:
|
||||||
EKind = ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
|
init<ELF32LE>();
|
||||||
else
|
break;
|
||||||
EKind = ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
|
case ELF32BEKind:
|
||||||
|
init<ELF32BE>();
|
||||||
EMachine = getObj<ELFT>().getHeader()->e_machine;
|
break;
|
||||||
OSABI = getObj<ELFT>().getHeader()->e_ident[llvm::ELF::EI_OSABI];
|
case ELF64LEKind:
|
||||||
ABIVersion = getObj<ELFT>().getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
|
init<ELF64LE>();
|
||||||
|
break;
|
||||||
|
case ELF64BEKind:
|
||||||
|
init<ELF64BE>();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("getELFKind");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <typename Elf_Shdr>
|
||||||
void ELFFileBase::initSymtab(ArrayRef<typename ELFT::Shdr> Sections,
|
static const Elf_Shdr *findSection(ArrayRef<Elf_Shdr> Sections, uint32_t Type) {
|
||||||
const typename ELFT::Shdr *Symtab) {
|
for (const Elf_Shdr &Sec : Sections)
|
||||||
FirstGlobal = Symtab->sh_info;
|
if (Sec.sh_type == Type)
|
||||||
ArrayRef<typename ELFT::Sym> ELFSyms =
|
return &Sec;
|
||||||
CHECK(getObj<ELFT>().symbols(Symtab), this);
|
return nullptr;
|
||||||
if (FirstGlobal == 0 || FirstGlobal > ELFSyms.size())
|
}
|
||||||
|
|
||||||
|
template <class ELFT> void ELFFileBase::init() {
|
||||||
|
using Elf_Shdr = typename ELFT::Shdr;
|
||||||
|
using Elf_Sym = typename ELFT::Sym;
|
||||||
|
|
||||||
|
// Initialize trivial attributes.
|
||||||
|
const ELFFile<ELFT> &Obj = getObj<ELFT>();
|
||||||
|
EMachine = Obj.getHeader()->e_machine;
|
||||||
|
OSABI = Obj.getHeader()->e_ident[llvm::ELF::EI_OSABI];
|
||||||
|
ABIVersion = Obj.getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
|
||||||
|
|
||||||
|
ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
|
||||||
|
|
||||||
|
// Find a symbol table.
|
||||||
|
bool IsDSO =
|
||||||
|
(identify_magic(MB.getBuffer()) == file_magic::elf_shared_object);
|
||||||
|
const Elf_Shdr *SymtabSec =
|
||||||
|
findSection(Sections, IsDSO ? SHT_DYNSYM : SHT_SYMTAB);
|
||||||
|
|
||||||
|
if (!SymtabSec)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Initialize members corresponding to a symbol table.
|
||||||
|
FirstGlobal = SymtabSec->sh_info;
|
||||||
|
|
||||||
|
ArrayRef<Elf_Sym> ESyms = CHECK(Obj.symbols(SymtabSec), this);
|
||||||
|
if (FirstGlobal == 0 || FirstGlobal > ESyms.size())
|
||||||
fatal(toString(this) + ": invalid sh_info in symbol table");
|
fatal(toString(this) + ": invalid sh_info in symbol table");
|
||||||
this->ELFSyms = reinterpret_cast<const void *>(ELFSyms.data());
|
|
||||||
this->NumELFSyms = ELFSyms.size();
|
|
||||||
|
|
||||||
StringTable =
|
ELFSyms = reinterpret_cast<const void *>(ESyms.data());
|
||||||
CHECK(getObj<ELFT>().getStringTableForSymtab(*Symtab, Sections), this);
|
NumELFSyms = ESyms.size();
|
||||||
}
|
StringTable = CHECK(Obj.getStringTableForSymtab(*SymtabSec, Sections), this);
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
ObjFile<ELFT>::ObjFile(MemoryBufferRef M, StringRef ArchiveName)
|
|
||||||
: ELFFileBase(ObjKind, M) {
|
|
||||||
parseHeader<ELFT>();
|
|
||||||
this->ArchiveName = ArchiveName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
|
@ -439,12 +466,6 @@ void ObjFile<ELFT>::parse(
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
|
StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
|
||||||
const Elf_Shdr &Sec) {
|
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->getELFSyms<ELFT>().empty())
|
|
||||||
this->initSymtab<ELFT>(
|
|
||||||
Sections, CHECK(object::getSection<ELFT>(Sections, Sec.sh_link), this));
|
|
||||||
|
|
||||||
const Elf_Sym *Sym =
|
const Elf_Sym *Sym =
|
||||||
CHECK(object::getSymbol<ELFT>(this->getELFSyms<ELFT>(), Sec.sh_info), this);
|
CHECK(object::getSymbol<ELFT>(this->getELFSyms<ELFT>(), Sec.sh_info), this);
|
||||||
StringRef Signature = CHECK(Sym->getName(this->StringTable), this);
|
StringRef Signature = CHECK(Sym->getName(this->StringTable), this);
|
||||||
|
@ -515,15 +536,8 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
|
||||||
// When the option is given, we link "just symbols". The section table is
|
// When the option is given, we link "just symbols". The section table is
|
||||||
// initialized with null pointers.
|
// initialized with null pointers.
|
||||||
template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
|
template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
|
||||||
ArrayRef<Elf_Shdr> ObjSections = CHECK(this->getObj().sections(), this);
|
ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this);
|
||||||
this->Sections.resize(ObjSections.size());
|
this->Sections.resize(Sections.size());
|
||||||
|
|
||||||
for (const Elf_Shdr &Sec : ObjSections) {
|
|
||||||
if (Sec.sh_type != SHT_SYMTAB)
|
|
||||||
continue;
|
|
||||||
this->initSymtab<ELFT>(ObjSections, &Sec);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// An ELF object file may contain a `.deplibs` section. If it exists, the
|
// An ELF object file may contain a `.deplibs` section. If it exists, the
|
||||||
|
@ -625,12 +639,10 @@ void ObjFile<ELFT>::initializeSections(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHT_SYMTAB:
|
|
||||||
this->initSymtab<ELFT>(ObjSections, &Sec);
|
|
||||||
break;
|
|
||||||
case SHT_SYMTAB_SHNDX:
|
case SHT_SYMTAB_SHNDX:
|
||||||
ShndxTable = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
|
ShndxTable = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
|
||||||
break;
|
break;
|
||||||
|
case SHT_SYMTAB:
|
||||||
case SHT_STRTAB:
|
case SHT_STRTAB:
|
||||||
case SHT_NULL:
|
case SHT_NULL:
|
||||||
break;
|
break;
|
||||||
|
@ -1066,27 +1078,6 @@ void ArchiveFile::fetch(const Archive::Symbol &Sym) {
|
||||||
|
|
||||||
unsigned SharedFile::VernauxNum;
|
unsigned SharedFile::VernauxNum;
|
||||||
|
|
||||||
SharedFile::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
|
|
||||||
: ELFFileBase(SharedKind, M), SoName(DefaultSoName),
|
|
||||||
IsNeeded(!Config->AsNeeded) {
|
|
||||||
switch (getELFKind(MB, "")) {
|
|
||||||
case ELF32LEKind:
|
|
||||||
parseHeader<ELF32LE>();
|
|
||||||
break;
|
|
||||||
case ELF32BEKind:
|
|
||||||
parseHeader<ELF32BE>();
|
|
||||||
break;
|
|
||||||
case ELF64LEKind:
|
|
||||||
parseHeader<ELF64LE>();
|
|
||||||
break;
|
|
||||||
case ELF64BEKind:
|
|
||||||
parseHeader<ELF64BE>();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
llvm_unreachable("getELFKind");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the version definitions in the object file if present, and return a
|
// Parse the version definitions in the object file if present, and return a
|
||||||
// vector whose nth element contains a pointer to the Elf_Verdef for version
|
// vector whose nth element contains a pointer to the Elf_Verdef for version
|
||||||
// identifier n. Version identifiers that are not definitions map to nullptr.
|
// identifier n. Version identifiers that are not definitions map to nullptr.
|
||||||
|
@ -1165,9 +1156,6 @@ template <class ELFT> void SharedFile::parse() {
|
||||||
switch (Sec.sh_type) {
|
switch (Sec.sh_type) {
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
case SHT_DYNSYM:
|
|
||||||
this->initSymtab<ELFT>(Sections, &Sec);
|
|
||||||
break;
|
|
||||||
case SHT_DYNAMIC:
|
case SHT_DYNAMIC:
|
||||||
DynamicTags =
|
DynamicTags =
|
||||||
CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(&Sec), this);
|
CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(&Sec), this);
|
||||||
|
@ -1181,7 +1169,7 @@ template <class ELFT> void SharedFile::parse() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VersymSec && this->getELFSyms<ELFT>().empty()) {
|
if (VersymSec && NumELFSyms == 0) {
|
||||||
error("SHT_GNU_versym should be associated with symbol table");
|
error("SHT_GNU_versym should be associated with symbol table");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1221,7 +1209,7 @@ template <class ELFT> void SharedFile::parse() {
|
||||||
// Parse ".gnu.version" section which is a parallel array for the symbol
|
// Parse ".gnu.version" section which is a parallel array for the symbol
|
||||||
// table. If a given file doesn't have a ".gnu.version" section, we use
|
// table. If a given file doesn't have a ".gnu.version" section, we use
|
||||||
// VER_NDX_GLOBAL.
|
// VER_NDX_GLOBAL.
|
||||||
size_t Size = this->getELFSyms<ELFT>().size() - this->FirstGlobal;
|
size_t Size = NumELFSyms - FirstGlobal;
|
||||||
std::vector<uint32_t> Versyms(Size, VER_NDX_GLOBAL);
|
std::vector<uint32_t> Versyms(Size, VER_NDX_GLOBAL);
|
||||||
if (VersymSec) {
|
if (VersymSec) {
|
||||||
ArrayRef<Elf_Versym> Versym =
|
ArrayRef<Elf_Versym> Versym =
|
||||||
|
|
|
@ -152,7 +152,6 @@ private:
|
||||||
class ELFFileBase : public InputFile {
|
class ELFFileBase : public InputFile {
|
||||||
public:
|
public:
|
||||||
ELFFileBase(Kind K, MemoryBufferRef M);
|
ELFFileBase(Kind K, MemoryBufferRef M);
|
||||||
template <typename ELFT> void parseHeader();
|
|
||||||
static bool classof(const InputFile *F) { return F->isElf(); }
|
static bool classof(const InputFile *F) { return F->isElf(); }
|
||||||
|
|
||||||
template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
|
template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
|
||||||
|
@ -170,13 +169,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Initializes this class's member variables.
|
||||||
|
template <typename ELFT> void init();
|
||||||
|
|
||||||
const void *ELFSyms = nullptr;
|
const void *ELFSyms = nullptr;
|
||||||
size_t NumELFSyms = 0;
|
size_t NumELFSyms = 0;
|
||||||
uint32_t FirstGlobal = 0;
|
uint32_t FirstGlobal = 0;
|
||||||
StringRef StringTable;
|
StringRef StringTable;
|
||||||
template <typename ELFT>
|
|
||||||
void initSymtab(ArrayRef<typename ELFT::Shdr> Sections,
|
|
||||||
const typename ELFT::Shdr *Symtab);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// .o file.
|
// .o file.
|
||||||
|
@ -198,7 +197,10 @@ public:
|
||||||
ArrayRef<Symbol *> getLocalSymbols();
|
ArrayRef<Symbol *> getLocalSymbols();
|
||||||
ArrayRef<Symbol *> getGlobalSymbols();
|
ArrayRef<Symbol *> getGlobalSymbols();
|
||||||
|
|
||||||
ObjFile(MemoryBufferRef M, StringRef ArchiveName);
|
ObjFile(MemoryBufferRef M, StringRef ArchiveName) : ELFFileBase(ObjKind, M) {
|
||||||
|
this->ArchiveName = ArchiveName;
|
||||||
|
}
|
||||||
|
|
||||||
void parse(llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *>
|
void parse(llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *>
|
||||||
&ComdatGroups);
|
&ComdatGroups);
|
||||||
|
|
||||||
|
@ -345,6 +347,10 @@ public:
|
||||||
// .so file.
|
// .so file.
|
||||||
class SharedFile : public ELFFileBase {
|
class SharedFile : public ELFFileBase {
|
||||||
public:
|
public:
|
||||||
|
SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
|
||||||
|
: ELFFileBase(SharedKind, M), SoName(DefaultSoName),
|
||||||
|
IsNeeded(!Config->AsNeeded) {}
|
||||||
|
|
||||||
// This is actually a vector of Elf_Verdef pointers.
|
// This is actually a vector of Elf_Verdef pointers.
|
||||||
std::vector<const void *> Verdefs;
|
std::vector<const void *> Verdefs;
|
||||||
|
|
||||||
|
@ -360,8 +366,6 @@ public:
|
||||||
|
|
||||||
static bool classof(const InputFile *F) { return F->kind() == SharedKind; }
|
static bool classof(const InputFile *F) { return F->kind() == SharedKind; }
|
||||||
|
|
||||||
SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
|
|
||||||
|
|
||||||
template <typename ELFT> void parse();
|
template <typename ELFT> void parse();
|
||||||
|
|
||||||
// Used for --no-allow-shlib-undefined.
|
// Used for --no-allow-shlib-undefined.
|
||||||
|
|
Loading…
Reference in New Issue