typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
- typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter;
- typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter;
-
protected:
ELFFile<ELFT> EF;
void moveSymbolNext(DataRefImpl &Symb) const override;
- std::error_code getSymbolName(DataRefImpl Symb,
- StringRef &Res) const override;
- std::error_code getSymbolAddress(DataRefImpl Symb,
- uint64_t &Res) const override;
- uint64_t getSymbolValue(DataRefImpl Symb) const override;
+ ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
bool isSectionData(DataRefImpl Sec) const override;
bool isSectionBSS(DataRefImpl Sec) const override;
bool isSectionVirtual(DataRefImpl Sec) const override;
- bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
- std::error_code getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const override;
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
uint64_t getRelocationType(DataRefImpl Rel) const override;
uint32_t getSectionType(DataRefImpl Sec) const override;
uint64_t getSectionFlags(DataRefImpl Sec) const override;
- uint64_t getROffset(DataRefImpl Rel) const;
StringRef getRelocationTypeName(uint32_t Type) const;
/// \brief Get the relocation section that contains \a Rel.
const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
- return EF.getSection(Rel.d.a);
+ return *EF.getSection(Rel.d.a);
}
- const Elf_Rel *getRel(DataRefImpl Rel) const;
- const Elf_Rela *getRela(DataRefImpl Rela) const;
-
const Elf_Sym *toELFSymIter(DataRefImpl Sym) const {
- return reinterpret_cast<const Elf_Sym *>(Sym.p & ~uintptr_t(1));
+ return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
}
- DataRefImpl toDRI(const Elf_Sym *Sym, bool IsDynamic) const {
+ DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
DataRefImpl DRI;
- DRI.p =
- reinterpret_cast<uintptr_t>(Sym) | static_cast<uintptr_t>(IsDynamic);
- return DRI;
- }
+ if (!SymTable) {
+ DRI.d.a = 0;
+ DRI.d.b = 0;
+ return DRI;
+ }
+ assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
+ SymTable->sh_type == ELF::SHT_DYNSYM);
- Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const {
- return Elf_Shdr_Iter(EF.getHeader()->e_shentsize,
- reinterpret_cast<const char *>(Sec.p));
- }
+ uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin());
+ unsigned SymTableIndex =
+ (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
- DataRefImpl toDRI(Elf_Shdr_Iter Sec) const {
- DataRefImpl DRI;
- DRI.p = reinterpret_cast<uintptr_t>(Sec.get());
+ DRI.d.a = SymTableIndex;
+ DRI.d.b = SymbolNum;
return DRI;
}
+ const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
+ return reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ }
+
DataRefImpl toDRI(const Elf_Shdr *Sec) const {
DataRefImpl DRI;
DRI.p = reinterpret_cast<uintptr_t>(Sec);
return DRI;
}
- Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const {
- return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(),
- reinterpret_cast<const char *>(Dyn.p));
- }
-
- DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const {
+ DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
DataRefImpl DRI;
- DRI.p = reinterpret_cast<uintptr_t>(Dyn.get());
+ DRI.p = reinterpret_cast<uintptr_t>(Dyn);
return DRI;
}
public:
ELFObjectFile(MemoryBufferRef Object, std::error_code &EC);
+ const Elf_Rel *getRel(DataRefImpl Rel) const;
+ const Elf_Rela *getRela(DataRefImpl Rela) const;
+
const Elf_Sym *getSymbol(DataRefImpl Symb) const;
basic_symbol_iterator symbol_begin_impl() const override;
template <class ELFT>
void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
- const Elf_Sym *S = toELFSymIter(Sym);
- Sym = toDRI(++S, Sym.p & 1);
+ ++Sym.d.b;
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym,
- StringRef &Result) const {
+ErrorOr<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
const Elf_Sym *ESym = toELFSymIter(Sym);
- ErrorOr<StringRef> Name = EF.getSymbolName(ESym, Sym.p & 1);
- if (!Name)
- return Name.getError();
- Result = *Name;
- return std::error_code();
+ const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a);
+ const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link);
+ StringRef SymTable = *EF.getStringTable(StringTableSec);
+ return ESym->getName(SymTable);
}
template <class ELFT>
}
template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const {
+uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
const Elf_Sym *ESym = getSymbol(Symb);
- switch (ESym->st_shndx) {
- case ELF::SHN_COMMON:
- case ELF::SHN_UNDEF:
- return UnknownAddress;
- case ELF::SHN_ABS:
- return ESym->st_value;
- }
-
- const Elf_Ehdr *Header = EF.getHeader();
uint64_t Ret = ESym->st_value;
+ if (ESym->st_shndx == ELF::SHN_ABS)
+ return Ret;
+ const Elf_Ehdr *Header = EF.getHeader();
// Clear the ARM/Thumb or microMIPS indicator flag.
if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
ESym->getType() == ELF::STT_FUNC)
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
- uint64_t &Result) const {
- Result = getSymbolValue(Symb);
+ErrorOr<uint64_t>
+ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
+ uint64_t Result = getSymbolValue(Symb);
const Elf_Sym *ESym = getSymbol(Symb);
switch (ESym->st_shndx) {
case ELF::SHN_COMMON:
case ELF::SHN_UNDEF:
case ELF::SHN_ABS:
- return std::error_code();
+ return Result;
}
const Elf_Ehdr *Header = EF.getHeader();
if (Header->e_type == ELF::ET_REL) {
- const typename ELFFile<ELFT>::Elf_Shdr * Section = EF.getSection(ESym);
- if (Section != nullptr)
+ ErrorOr<const Elf_Shdr *> SectionOrErr = EF.getSection(ESym);
+ if (std::error_code EC = SectionOrErr.getError())
+ return EC;
+ const Elf_Shdr *Section = *SectionOrErr;
+ if (Section)
Result += Section->sh_addr;
}
- return std::error_code();
+ return Result;
}
template <class ELFT>
Result |= SymbolRef::SF_Absolute;
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
- ESym == EF.begin_symbols() || ESym == EF.begin_dynamic_symbols())
+ ESym == EF.symbol_begin() || ESym == EF.dynamic_symbol_begin())
Result |= SymbolRef::SF_FormatSpecific;
if (EF.getHeader()->e_machine == ELF::EM_ARM) {
- ErrorOr<StringRef> NameOrErr = EF.getSymbolName(ESym, Sym.p & 1);
- if (NameOrErr) {
+ if (ErrorOr<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
if (Name.startswith("$d") || Name.startswith("$t") ||
Name.startswith("$a"))
template <class ELFT>
section_iterator
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym) const {
- const Elf_Shdr *ESec = EF.getSection(ESym);
+ ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym);
+ if (std::error_code EC = ESecOrErr.getError())
+ report_fatal_error(EC.message());
+
+ const Elf_Shdr *ESec = *ESecOrErr;
if (!ESec)
return section_end();
- else {
- DataRefImpl Sec;
- Sec.p = reinterpret_cast<intptr_t>(ESec);
- return section_iterator(SectionRef(Sec, this));
- }
+
+ DataRefImpl Sec;
+ Sec.p = reinterpret_cast<intptr_t>(ESec);
+ return section_iterator(SectionRef(Sec, this));
}
template <class ELFT>
template <class ELFT>
void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
- Sec = toDRI(++toELFShdrIter(Sec));
+ const Elf_Shdr *ESec = toELFShdrIter(Sec);
+ Sec = toDRI(++ESec);
}
template <class ELFT>
std::error_code
ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
StringRef &Result) const {
- Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+ const Elf_Shdr *EShdr = toELFShdrIter(Sec);
Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
return std::error_code();
}
template <class ELFT>
bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
- Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+ const Elf_Shdr *EShdr = toELFShdrIter(Sec);
return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
EShdr->sh_type == ELF::SHT_PROGBITS;
}
template <class ELFT>
bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
- Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+ const Elf_Shdr *EShdr = toELFShdrIter(Sec);
return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
EShdr->sh_type == ELF::SHT_NOBITS;
}
return toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
}
-template <class ELFT>
-bool ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
- DataRefImpl Symb) const {
- const Elf_Sym *ESym = toELFSymIter(Symb);
-
- uintX_t Index = ESym->st_shndx;
- bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE;
-
- return !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx));
-}
-
template <class ELFT>
relocation_iterator
ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
DataRefImpl RelData;
- uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
+ uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin());
RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
RelData.d.b = 0;
+
+ const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
+ return relocation_iterator(RelocationRef(RelData, this));
+
+ const Elf_Shdr *RelSec = getRelSection(RelData);
+ ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link);
+ if (std::error_code EC = SymSecOrErr.getError())
+ report_fatal_error(EC.message());
+ const Elf_Shdr *SymSec = *SymSecOrErr;
+ uint32_t SymSecType = SymSec->sh_type;
+ if (SymSecType != ELF::SHT_SYMTAB && SymSecType != ELF::SHT_DYNSYM)
+ report_fatal_error("Invalid symbol table section type!");
+ if (SymSecType == ELF::SHT_DYNSYM)
+ RelData.d.b = 1;
+
return relocation_iterator(RelocationRef(RelData, this));
}
template <class ELFT>
relocation_iterator
ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
- DataRefImpl RelData;
- uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
+ relocation_iterator Begin = section_rel_begin(Sec);
if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
- RelData.d.b = 0;
- else
- RelData.d.b = S->sh_size / S->sh_entsize;
-
+ return Begin;
+ DataRefImpl RelData = Begin->getRawDataRefImpl();
+ RelData.d.b += (S->sh_size / S->sh_entsize) << 1;
return relocation_iterator(RelocationRef(RelData, this));
}
if (EF.getHeader()->e_type != ELF::ET_REL)
return section_end();
- Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+ const Elf_Shdr *EShdr = toELFShdrIter(Sec);
uintX_t Type = EShdr->sh_type;
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
return section_end();
- const Elf_Shdr *R = EF.getSection(EShdr->sh_info);
- return section_iterator(SectionRef(toDRI(R), this));
+ ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info);
+ if (std::error_code EC = R.getError())
+ report_fatal_error(EC.message());
+ return section_iterator(SectionRef(toDRI(*R), this));
}
// Relocations
template <class ELFT>
void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
- ++Rel.d.b;
+ Rel.d.b += 2;
}
template <class ELFT>
if (!symbolIdx)
return symbol_end();
- const Elf_Shdr *SymSec = EF.getSection(sec->sh_link);
-
+ bool IsDyn = Rel.d.b & 1;
DataRefImpl SymbolData;
- switch (SymSec->sh_type) {
- default:
- report_fatal_error("Invalid symbol table section type!");
- case ELF::SHT_SYMTAB:
- SymbolData = toDRI(EF.begin_symbols() + symbolIdx, false);
- break;
- case ELF::SHT_DYNSYM:
- SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx, true);
- break;
- }
-
+ if (IsDyn)
+ SymbolData = toDRI(EF.getDotDynSymSec(), symbolIdx);
+ else
+ SymbolData = toDRI(EF.getDotSymtabSec(), symbolIdx);
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template <class ELFT>
-std::error_code
-ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
- uint64_t &Result) const {
- uint64_t ROffset = getROffset(Rel);
- const Elf_Ehdr *Header = EF.getHeader();
-
- if (Header->e_type == ELF::ET_REL) {
- const Elf_Shdr *RelocationSec = getRelSection(Rel);
- const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
- Result = ROffset + RelocatedSec->sh_addr;
- } else {
- Result = ROffset;
- }
-
- return std::error_code();
-}
-
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
assert(EF.getHeader()->e_type == ELF::ET_REL &&
"Only relocatable object files have relocation offsets");
- return getROffset(Rel);
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
const Elf_Shdr *sec = getRelSection(Rel);
if (sec->sh_type == ELF::SHT_REL)
return getRel(Rel)->r_offset;
const typename ELFObjectFile<ELFT>::Elf_Rel *
ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
- return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
+ return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b >> 1);
}
template <class ELFT>
const typename ELFObjectFile<ELFT>::Elf_Rela *
ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
- return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
+ return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b >> 1);
}
template <class ELFT>
template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
- DataRefImpl Sym = toDRI(EF.begin_symbols(), false);
+ DataRefImpl Sym = toDRI(EF.getDotSymtabSec(), 0);
return basic_symbol_iterator(SymbolRef(Sym, this));
}
template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
- DataRefImpl Sym = toDRI(EF.end_symbols(), false);
+ const Elf_Shdr *SymTab = EF.getDotSymtabSec();
+ if (!SymTab)
+ return symbol_begin_impl();
+ DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
return basic_symbol_iterator(SymbolRef(Sym, this));
}
template <class ELFT>
elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
- DataRefImpl Sym = toDRI(EF.begin_dynamic_symbols(), true);
+ DataRefImpl Sym = toDRI(EF.getDotDynSymSec(), 0);
return symbol_iterator(SymbolRef(Sym, this));
}
template <class ELFT>
elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
- DataRefImpl Sym = toDRI(EF.end_dynamic_symbols(), true);
- return symbol_iterator(SymbolRef(Sym, this));
+ const Elf_Shdr *SymTab = EF.getDotDynSymSec();
+ DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
+ return basic_symbol_iterator(SymbolRef(Sym, this));
}
template <class ELFT>
section_iterator ELFObjectFile<ELFT>::section_begin() const {
- return section_iterator(SectionRef(toDRI(EF.begin_sections()), this));
+ return section_iterator(SectionRef(toDRI(EF.section_begin()), this));
}
template <class ELFT>
section_iterator ELFObjectFile<ELFT>::section_end() const {
- return section_iterator(SectionRef(toDRI(EF.end_sections()), this));
+ return section_iterator(SectionRef(toDRI(EF.section_end()), this));
}
template <class ELFT>
StringRef ELFObjectFile<ELFT>::getLoadName() const {
- Elf_Dyn_Iter DI = EF.begin_dynamic_table();
- Elf_Dyn_Iter DE = EF.end_dynamic_table();
+ const Elf_Dyn *DI = EF.dynamic_table_begin();
+ const Elf_Dyn *DE = EF.dynamic_table_end();
while (DI != DE && DI->getTag() != ELF::DT_SONAME)
++DI;