mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-06 08:02:18 +00:00
Simplify memory management by having ELFData contain a ELFObj.
llvm-svn: 248502
This commit is contained in:
parent
f209cdfade
commit
e1901cc33d
@ -46,19 +46,26 @@ bool ELFFileBase::isCompatibleWith(const ELFFileBase &Other) const {
|
||||
getEMachine() == Other.getEMachine();
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFData<ELFT>::openELF(MemoryBufferRef MB) {
|
||||
// Parse a memory buffer as a ELF file.
|
||||
namespace {
|
||||
class ECRAII {
|
||||
std::error_code EC;
|
||||
ELFObj = llvm::make_unique<ELFFile<ELFT>>(MB.getBuffer(), EC);
|
||||
error(EC);
|
||||
|
||||
public:
|
||||
std::error_code &getEC() { return EC; }
|
||||
~ECRAII() { error(EC); }
|
||||
};
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ELFData<ELFT>::ELFData(MemoryBufferRef MB)
|
||||
: ELFObj(MB.getBuffer(), ECRAII().getEC()) {}
|
||||
|
||||
template <class ELFT>
|
||||
typename ELFData<ELFT>::Elf_Sym_Range
|
||||
ELFData<ELFT>::getSymbolsHelper(bool Local) {
|
||||
if (!Symtab)
|
||||
return Elf_Sym_Range(nullptr, nullptr);
|
||||
Elf_Sym_Range Syms = ELFObj->symbols(Symtab);
|
||||
Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
|
||||
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
|
||||
uint32_t FirstNonLocal = Symtab->sh_info;
|
||||
if (FirstNonLocal > NumSymbols)
|
||||
@ -74,38 +81,39 @@ template <class ELFT>
|
||||
typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() {
|
||||
if (!Symtab)
|
||||
return Elf_Sym_Range(nullptr, nullptr);
|
||||
ErrorOr<StringRef> StringTableOrErr =
|
||||
ELFObj->getStringTableForSymtab(*Symtab);
|
||||
ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
|
||||
error(StringTableOrErr.getError());
|
||||
StringTable = *StringTableOrErr;
|
||||
return getSymbolsHelper(false);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
|
||||
: ObjectFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {}
|
||||
|
||||
template <class ELFT>
|
||||
typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() {
|
||||
return this->getSymbolsHelper(true);
|
||||
}
|
||||
|
||||
template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
|
||||
this->openELF(MB);
|
||||
|
||||
// Read section and symbol tables.
|
||||
initializeSections();
|
||||
initializeSymbols();
|
||||
}
|
||||
|
||||
template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSections() {
|
||||
uint64_t Size = this->ELFObj->getNumSections();
|
||||
uint64_t Size = this->ELFObj.getNumSections();
|
||||
Sections.resize(Size);
|
||||
unsigned I = 0;
|
||||
for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
|
||||
for (const Elf_Shdr &Sec : this->ELFObj.sections()) {
|
||||
switch (Sec.sh_type) {
|
||||
case SHT_SYMTAB:
|
||||
this->Symtab = &Sec;
|
||||
break;
|
||||
case SHT_SYMTAB_SHNDX: {
|
||||
ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable =
|
||||
this->ELFObj->getSHNDXTable(Sec);
|
||||
this->ELFObj.getSHNDXTable(Sec);
|
||||
error(ErrorOrTable);
|
||||
SymtabSHNDX = *ErrorOrTable;
|
||||
break;
|
||||
@ -156,8 +164,8 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
|
||||
case SHN_COMMON:
|
||||
return new (Alloc) DefinedCommon<ELFT>(Name, *Sym);
|
||||
case SHN_XINDEX:
|
||||
SecIndex = this->ELFObj->getExtendedSymbolTableIndex(Sym, this->Symtab,
|
||||
SymtabSHNDX);
|
||||
SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab,
|
||||
SymtabSHNDX);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -203,10 +211,12 @@ MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
template <class ELFT> void SharedFile<ELFT>::parse() {
|
||||
this->openELF(MB);
|
||||
template <class ELFT>
|
||||
SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
|
||||
: SharedFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {}
|
||||
|
||||
for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
|
||||
template <class ELFT> void SharedFile<ELFT>::parse() {
|
||||
for (const Elf_Shdr &Sec : this->ELFObj.sections()) {
|
||||
if (Sec.sh_type == SHT_DYNSYM) {
|
||||
this->Symtab = &Sec;
|
||||
break;
|
||||
|
@ -97,23 +97,23 @@ template <class ELFT> static ELFKind getStaticELFKind() {
|
||||
|
||||
template <class ELFT> class ELFData {
|
||||
public:
|
||||
ELFData(MemoryBufferRef MB);
|
||||
typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
|
||||
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
|
||||
|
||||
llvm::object::ELFFile<ELFT> *getObj() const { return ELFObj.get(); }
|
||||
const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; }
|
||||
llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; }
|
||||
|
||||
uint16_t getEMachine() const { return getObj()->getHeader()->e_machine; }
|
||||
uint16_t getEMachine() const { return getObj().getHeader()->e_machine; }
|
||||
|
||||
StringRef getStringTable() const { return StringTable; }
|
||||
|
||||
protected:
|
||||
std::unique_ptr<llvm::object::ELFFile<ELFT>> ELFObj;
|
||||
llvm::object::ELFFile<ELFT> ELFObj;
|
||||
const Elf_Shdr *Symtab = nullptr;
|
||||
StringRef StringTable;
|
||||
Elf_Sym_Range getNonLocalSymbols();
|
||||
Elf_Sym_Range getSymbolsHelper(bool);
|
||||
|
||||
void openELF(MemoryBufferRef MB);
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
@ -131,8 +131,7 @@ public:
|
||||
cast<ELFFileBase>(F)->getELFKind() == getStaticELFKind<ELFT>();
|
||||
}
|
||||
|
||||
explicit ObjectFile(MemoryBufferRef M)
|
||||
: ObjectFileBase(getStaticELFKind<ELFT>(), M) {}
|
||||
explicit ObjectFile(MemoryBufferRef M);
|
||||
void parse() override;
|
||||
|
||||
ArrayRef<InputSection<ELFT> *> getSections() const { return Sections; }
|
||||
@ -207,8 +206,7 @@ public:
|
||||
cast<ELFFileBase>(F)->getELFKind() == getStaticELFKind<ELFT>();
|
||||
}
|
||||
|
||||
explicit SharedFile(MemoryBufferRef M)
|
||||
: SharedFileBase(getStaticELFKind<ELFT>(), M) {}
|
||||
explicit SharedFile(MemoryBufferRef M);
|
||||
|
||||
void parse() override;
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ void InputSection<ELFT>::relocate(
|
||||
const OutputSection<ELFT> &BssSec, const PltSection<ELFT> &PltSec,
|
||||
const GotSection<ELFT> &GotSec) {
|
||||
typedef Elf_Rel_Impl<ELFT, isRela> RelType;
|
||||
bool IsMips64EL = File.getObj()->isMips64EL();
|
||||
bool IsMips64EL = File.getObj().isMips64EL();
|
||||
for (const RelType &RI : Rels) {
|
||||
uint32_t SymIndex = RI.getSymbol(IsMips64EL);
|
||||
uint32_t Type = RI.getType(IsMips64EL);
|
||||
@ -42,7 +42,7 @@ void InputSection<ELFT>::relocate(
|
||||
// resolved so we don't allocate a SymbolBody.
|
||||
const Elf_Shdr *SymTab = File.getSymbolTable();
|
||||
if (SymIndex < SymTab->sh_info) {
|
||||
const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab);
|
||||
const Elf_Sym *Sym = File.getObj().getRelocationSymbol(&RI, SymTab);
|
||||
if (!Sym)
|
||||
continue;
|
||||
SymVA = getLocalSymVA(Sym, File);
|
||||
@ -98,26 +98,26 @@ void InputSection<ELFT>::writeTo(uint8_t *Buf,
|
||||
if (Header->sh_type == SHT_NOBITS)
|
||||
return;
|
||||
// Copy section contents from source object file to output file.
|
||||
ArrayRef<uint8_t> Data = *File->getObj()->getSectionContents(Header);
|
||||
ArrayRef<uint8_t> Data = *File->getObj().getSectionContents(Header);
|
||||
memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
|
||||
|
||||
const ObjectFile<ELFT> *File = getFile();
|
||||
ELFFile<ELFT> *EObj = File->getObj();
|
||||
ObjectFile<ELFT> *File = getFile();
|
||||
ELFFile<ELFT> &EObj = File->getObj();
|
||||
uint8_t *Base = Buf + getOutputSectionOff();
|
||||
uintX_t BaseAddr = Out->getVA() + getOutputSectionOff();
|
||||
// Iterate over all relocation sections that apply to this section.
|
||||
for (const Elf_Shdr *RelSec : RelocSections) {
|
||||
if (RelSec->sh_type == SHT_RELA)
|
||||
relocate(Base, EObj->relas(RelSec), *File, BaseAddr, BssSec, PltSec,
|
||||
relocate(Base, EObj.relas(RelSec), *File, BaseAddr, BssSec, PltSec,
|
||||
GotSec);
|
||||
else
|
||||
relocate(Base, EObj->rels(RelSec), *File, BaseAddr, BssSec, PltSec,
|
||||
relocate(Base, EObj.rels(RelSec), *File, BaseAddr, BssSec, PltSec,
|
||||
GotSec);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT> StringRef InputSection<ELFT>::getSectionName() const {
|
||||
ErrorOr<StringRef> Name = File->getObj()->getSectionName(Header);
|
||||
ErrorOr<StringRef> Name = File->getObj().getSectionName(Header);
|
||||
error(Name);
|
||||
return *Name;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
|
||||
StringRef getSectionName() const;
|
||||
const Elf_Shdr *getSectionHdr() const { return Header; }
|
||||
const ObjectFile<ELFT> *getFile() const { return File; }
|
||||
ObjectFile<ELFT> *getFile() const { return File; }
|
||||
|
||||
// The writer sets and uses the addresses.
|
||||
uintX_t getOutputSectionOff() const { return OutputSectionOff; }
|
||||
|
@ -64,7 +64,7 @@ PltSection<ELFT>::getEntryAddr(const SymbolBody &B) const {
|
||||
|
||||
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
|
||||
bool IsMips64EL = Relocs[0].C.getFile()->getObj()->isMips64EL();
|
||||
bool IsMips64EL = Relocs[0].C.getFile()->getObj().isMips64EL();
|
||||
for (const DynamicReloc<ELFT> &Rel : Relocs) {
|
||||
auto *P = reinterpret_cast<Elf_Rel *>(Buf);
|
||||
Buf += EntrySize;
|
||||
@ -242,7 +242,7 @@ lld::elf2::getLocalSymVA(const typename ELFFile<ELFT>::Elf_Sym *Sym,
|
||||
uint32_t SecIndex = Sym->st_shndx;
|
||||
|
||||
if (SecIndex == SHN_XINDEX)
|
||||
SecIndex = File.getObj()->getExtendedSymbolTableIndex(
|
||||
SecIndex = File.getObj().getExtendedSymbolTableIndex(
|
||||
Sym, File.getSymbolTable(), File.getSymbolTableShndx());
|
||||
ArrayRef<InputSection<ELFT> *> Sections = File.getSections();
|
||||
InputSection<ELFT> *Section = Sections[SecIndex];
|
||||
@ -309,7 +309,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
ESym->st_size = Sym.st_size;
|
||||
ESym->setBindingAndType(Sym.getBinding(), Sym.getType());
|
||||
if (SecIndex == SHN_XINDEX)
|
||||
SecIndex = File.getObj()->getExtendedSymbolTableIndex(
|
||||
SecIndex = File.getObj().getExtendedSymbolTableIndex(
|
||||
&Sym, File.getSymbolTable(), File.getSymbolTableShndx());
|
||||
ArrayRef<InputSection<ELFT> *> Sections = File.getSections();
|
||||
Section = Sections[SecIndex];
|
||||
|
@ -130,7 +130,7 @@ void SymbolTable::dupError(const SymbolBody &Old, const SymbolBody &New) {
|
||||
|
||||
for (const std::unique_ptr<ObjectFileBase> &F : ObjectFiles) {
|
||||
const auto &File = cast<ObjectFile<ELFT>>(*F);
|
||||
Elf_Sym_Range Syms = File.getObj()->symbols(File.getSymbolTable());
|
||||
Elf_Sym_Range Syms = File.getObj().symbols(File.getSymbolTable());
|
||||
if (&OldE > Syms.begin() && &OldE < Syms.end())
|
||||
OldFile = F.get();
|
||||
if (&NewE > Syms.begin() && &NewE < Syms.end())
|
||||
|
@ -249,7 +249,7 @@ void Writer<ELFT>::scanRelocs(
|
||||
iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels) {
|
||||
typedef Elf_Rel_Impl<ELFT, isRela> RelType;
|
||||
const ObjectFile<ELFT> &File = *C.getFile();
|
||||
bool IsMips64EL = File.getObj()->isMips64EL();
|
||||
bool IsMips64EL = File.getObj().isMips64EL();
|
||||
for (const RelType &RI : Rels) {
|
||||
uint32_t SymIndex = RI.getSymbol(IsMips64EL);
|
||||
SymbolBody *Body = File.getSymbolBody(SymIndex);
|
||||
@ -275,17 +275,17 @@ void Writer<ELFT>::scanRelocs(
|
||||
|
||||
template <class ELFT>
|
||||
void Writer<ELFT>::scanRelocs(const InputSection<ELFT> &C) {
|
||||
const ObjectFile<ELFT> *File = C.getFile();
|
||||
ELFFile<ELFT> *EObj = File->getObj();
|
||||
ObjectFile<ELFT> *File = C.getFile();
|
||||
ELFFile<ELFT> &EObj = File->getObj();
|
||||
|
||||
if (!(C.getSectionHdr()->sh_flags & SHF_ALLOC))
|
||||
return;
|
||||
|
||||
for (const Elf_Shdr *RelSec : C.RelocSections) {
|
||||
if (RelSec->sh_type == SHT_RELA)
|
||||
scanRelocs(C, EObj->relas(RelSec));
|
||||
scanRelocs(C, EObj.relas(RelSec));
|
||||
else
|
||||
scanRelocs(C, EObj->rels(RelSec));
|
||||
scanRelocs(C, EObj.rels(RelSec));
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,7 +299,7 @@ static void undefError(const SymbolTable &S, const SymbolBody &Sym) {
|
||||
|
||||
for (const std::unique_ptr<ObjectFileBase> &F : S.getObjectFiles()) {
|
||||
const auto &File = cast<ObjectFile<ELFT>>(*F);
|
||||
Elf_Sym_Range Syms = File.getObj()->symbols(File.getSymbolTable());
|
||||
Elf_Sym_Range Syms = File.getObj().symbols(File.getSymbolTable());
|
||||
if (&SymE > Syms.begin() && &SymE < Syms.end())
|
||||
SymFile = F.get();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user