//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_READOBJ_ARMEHABI_PRINTER_H
-#define LLVM_READOBJ_ARMEHABI_PRINTER_H
+#ifndef LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
+#define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
#include "Error.h"
#include "StreamWriter.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Support/ARMEHABI.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/type_traits.h"
-namespace {
-template <typename type_, size_t N>
-size_t countof(const type_ (&)[N]) {
- return N;
-}
-}
-
namespace llvm {
namespace ARM {
namespace EHABI {
void OpcodeDecoder::Decode(const uint8_t *Opcodes, off_t Offset, size_t Length) {
for (unsigned OCI = Offset; OCI < Length + Offset; ) {
bool Decoded = false;
- for (unsigned REI = 0, REE = countof(Ring); REI != REE && !Decoded; ++REI) {
+ for (unsigned REI = 0, REE = array_lengthof(Ring);
+ REI != REE && !Decoded; ++REI) {
if ((Opcodes[OCI ^ 3] & Ring[REI].Mask) == Ring[REI].Value) {
(this->*Ring[REI].Routine)(Opcodes, OCI);
Decoded = true;
template <typename ET>
class PrinterContext {
- StreamWriter &SW;
- const object::ELFFile<ET> *ELF;
-
typedef typename object::ELFFile<ET>::Elf_Sym Elf_Sym;
typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr;
+ typedef typename object::ELFFile<ET>::Elf_Rel Elf_Rel;
+ typedef typename object::ELFFile<ET>::Elf_Word Elf_Word;
- typedef typename object::ELFFile<ET>::Elf_Rel_Iter Elf_Rel_iterator;
- typedef typename object::ELFFile<ET>::Elf_Sym_Iter Elf_Sym_iterator;
- typedef typename object::ELFFile<ET>::Elf_Shdr_Iter Elf_Shdr_iterator;
+ StreamWriter &SW;
+ const object::ELFFile<ET> *ELF;
+ const Elf_Shdr *Symtab;
+ ArrayRef<Elf_Word> ShndxTable;
static const size_t IndexTableEntrySize;
void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const;
public:
- PrinterContext(StreamWriter &Writer, const object::ELFFile<ET> *File)
- : SW(Writer), ELF(File) {}
+ PrinterContext(StreamWriter &SW, const object::ELFFile<ET> *ELF,
+ const Elf_Shdr *Symtab)
+ : SW(SW), ELF(ELF), Symtab(Symtab) {}
void PrintUnwindInformation() const;
};
const size_t PrinterContext<ET>::IndexTableEntrySize = 8;
template <typename ET>
-ErrorOr<StringRef> PrinterContext<ET>::FunctionAtAddress(unsigned Section,
- uint64_t Address) const {
- for (Elf_Sym_iterator SI = ELF->begin_symbols(), SE = ELF->end_symbols();
- SI != SE; ++SI)
- if (SI->st_shndx == Section && SI->st_value == Address &&
- SI->getType() == ELF::STT_FUNC)
- return ELF->getSymbolName(SI);
+ErrorOr<StringRef>
+PrinterContext<ET>::FunctionAtAddress(unsigned Section,
+ uint64_t Address) const {
+ ErrorOr<StringRef> StrTableOrErr = ELF->getStringTableForSymtab(*Symtab);
+ error(StrTableOrErr.getError());
+ StringRef StrTable = *StrTableOrErr;
+
+ for (const Elf_Sym &Sym : ELF->symbols(Symtab))
+ if (Sym.st_shndx == Section && Sym.st_value == Address &&
+ Sym.getType() == ELF::STT_FUNC)
+ return Sym.getName(StrTable);
return readobj_error::unknown_symbol;
}
/// handling table. Use this symbol to recover the actual exception handling
/// table.
- for (Elf_Shdr_iterator SI = ELF->begin_sections(), SE = ELF->end_sections();
- SI != SE; ++SI) {
- if (SI->sh_type == ELF::SHT_REL && SI->sh_info == IndexSectionIndex) {
- for (Elf_Rel_iterator RI = ELF->begin_rel(&*SI), RE = ELF->end_rel(&*SI);
- RI != RE; ++RI) {
- if (RI->r_offset == IndexTableOffset) {
- typename object::ELFFile<ET>::Elf_Rela RelA;
- RelA.r_offset = RI->r_offset;
- RelA.r_info = RI->r_info;
- RelA.r_addend = 0;
-
- std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol =
- ELF->getRelocationSymbol(&(*SI), &RelA);
-
- return ELF->getSection(Symbol.second);
- }
- }
+ for (const Elf_Shdr &Sec : ELF->sections()) {
+ if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex)
+ continue;
+
+ ErrorOr<const Elf_Shdr *> SymTabOrErr = ELF->getSection(Sec.sh_link);
+ error(SymTabOrErr.getError());
+ const Elf_Shdr *SymTab = *SymTabOrErr;
+
+ for (const Elf_Rel &R : ELF->rels(&Sec)) {
+ if (R.r_offset != static_cast<unsigned>(IndexTableOffset))
+ continue;
+
+ typename object::ELFFile<ET>::Elf_Rela RelA;
+ RelA.r_offset = R.r_offset;
+ RelA.r_info = R.r_info;
+ RelA.r_addend = 0;
+
+ const Elf_Sym *Symbol = ELF->getRelocationSymbol(&RelA, SymTab);
+
+ ErrorOr<const Elf_Shdr *> Ret =
+ ELF->getSection(Symbol, SymTab, ShndxTable);
+ if (std::error_code EC = Ret.getError())
+ report_fatal_error(EC.message());
+ return *Ret;
}
}
- return NULL;
+ return nullptr;
}
template <typename ET>
switch (PersonalityIndex) {
case AEABI_UNWIND_CPP_PR0:
- llvm_unreachable("Personality 0 should be compact inline!");
+ PrintOpcodes(Contents->data() + TableEntryOffset, 3, 1);
break;
case AEABI_UNWIND_CPP_PR1:
case AEABI_UNWIND_CPP_PR2:
DictScope UI(SW, "UnwindInformation");
int SectionIndex = 0;
- for (Elf_Shdr_iterator SI = ELF->begin_sections(), SE = ELF->end_sections();
- SI != SE; ++SI, ++SectionIndex) {
- if (SI->sh_type == ELF::SHT_ARM_EXIDX) {
- const Elf_Shdr *IT = &(*SI);
-
+ for (const Elf_Shdr &Sec : ELF->sections()) {
+ if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
DictScope UIT(SW, "UnwindIndexTable");
SW.printNumber("SectionIndex", SectionIndex);
- if (ErrorOr<StringRef> SectionName = ELF->getSectionName(IT))
+ if (ErrorOr<StringRef> SectionName = ELF->getSectionName(&Sec))
SW.printString("SectionName", *SectionName);
- SW.printHex("SectionOffset", IT->sh_offset);
+ SW.printHex("SectionOffset", Sec.sh_offset);
- PrintIndexTable(SectionIndex, IT);
+ PrintIndexTable(SectionIndex, &Sec);
}
+ ++SectionIndex;
}
}
}