Simplify memory management by having ELFData contain a ELFObj.

llvm-svn: 248502
This commit is contained in:
Rafael Espindola 2015-09-24 15:11:50 +00:00
parent f209cdfade
commit e1901cc33d
7 changed files with 53 additions and 45 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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; }

View File

@ -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];

View File

@ -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())

View File

@ -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();
}