#include "ARMWinEHPrinter.h"
#include "Error.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ARMWinEH.h"
#include "llvm/Support/Format.h"
ErrorOr<object::SectionRef>
Decoder::getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) {
for (const auto &Section : COFF.sections()) {
- uint64_t Address;
- uint64_t Size;
-
- if (error_code EC = Section.getAddress(Address))
- return EC;
- if (error_code EC = Section.getSize(Size))
- return EC;
+ uint64_t Address = Section.getAddress();
+ uint64_t Size = Section.getSize();
if (VA >= Address && (VA - Address) <= Size)
return Section;
ErrorOr<object::SymbolRef> Decoder::getSymbol(const COFFObjectFile &COFF,
uint64_t VA, bool FunctionOnly) {
for (const auto &Symbol : COFF.symbols()) {
- if (FunctionOnly) {
- SymbolRef::Type Type;
- if (error_code EC = Symbol.getType(Type))
- return EC;
- if (Type != SymbolRef::ST_Function)
- continue;
- }
+ if (FunctionOnly && Symbol.getType() != SymbolRef::ST_Function)
+ continue;
- uint64_t Address;
- if (error_code EC = Symbol.getAddress(Address))
+ ErrorOr<uint64_t> Address = Symbol.getAddress();
+ if (std::error_code EC = Address.getError())
return EC;
- if (Address == VA)
+ if (*Address == VA)
return Symbol;
}
return readobj_error::unknown_symbol;
const SectionRef &Section,
uint64_t Offset) {
for (const auto &Relocation : Section.relocations()) {
- uint64_t RelocationOffset;
- if (auto Error = Relocation.getOffset(RelocationOffset))
- return Error;
+ uint64_t RelocationOffset = Relocation.getOffset();
if (RelocationOffset == Offset)
return *Relocation.getSymbol();
}
return readobj_error::unknown_symbol;
}
-bool Decoder::opcode_0xxxxxxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_0xxxxxxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint8_t Imm = OC[Offset] & 0x7f;
SW.startLine() << format("0x%02x ; %s sp, #(%u * 4)\n",
return false;
}
-bool Decoder::opcode_10Lxxxxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_10Lxxxxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Link = (OC[Offset] & 0x20) >> 5;
uint16_t RegisterMask = (Link << (Prologue ? 14 : 15))
return false;
}
-bool Decoder::opcode_1100xxxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_1100xxxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
if (Prologue)
SW.startLine() << format("0x%02x ; mov r%u, sp\n",
return false;
}
-bool Decoder::opcode_11010Lxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11010Lxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Link = (OC[Offset] & 0x4) >> 3;
unsigned Count = (OC[Offset] & 0x3);
return false;
}
-bool Decoder::opcode_11011Lxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11011Lxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Link = (OC[Offset] & 0x4) >> 2;
unsigned Count = (OC[Offset] & 0x3) + 4;
return false;
}
-bool Decoder::opcode_11100xxx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11100xxx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned High = (OC[Offset] & 0x7);
uint32_t VFPMask = (((1 << (High + 1)) - 1) << 8);
return false;
}
-bool Decoder::opcode_111010xx(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_111010xx(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint16_t Imm = ((OC[Offset + 0] & 0x03) << 8) | ((OC[Offset + 1] & 0xff) << 0);
return false;
}
-bool Decoder::opcode_1110110L(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_1110110L(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint8_t GPRMask = ((OC[Offset + 0] & 0x01) << (Prologue ? 14 : 15))
| ((OC[Offset + 1] & 0xff) << 0);
return false;
}
-bool Decoder::opcode_11101110(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11101110(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
assert(!Prologue && "may not be used in prologue");
return false;
}
-bool Decoder::opcode_11101111(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11101111(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
assert(!Prologue && "may not be used in prologue");
return false;
}
-bool Decoder::opcode_11110101(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11110101(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
return false;
}
-bool Decoder::opcode_11110110(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11110110(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
return false;
}
-bool Decoder::opcode_11110111(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11110111(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
return false;
}
-bool Decoder::opcode_11111000(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111000(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 16)
| (OC[Offset + 2] << 8)
return false;
}
-bool Decoder::opcode_11111001(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111001(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
return false;
}
-bool Decoder::opcode_11111010(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111010(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
uint32_t Imm = (OC[Offset + 1] << 16)
| (OC[Offset + 2] << 8)
return false;
}
-bool Decoder::opcode_11111011(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111011(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; nop\n", OC[Offset]);
++Offset;
return false;
}
-bool Decoder::opcode_11111100(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111100(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; nop.w\n", OC[Offset]);
++Offset;
return false;
}
-bool Decoder::opcode_11111101(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111101(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; b\n", OC[Offset]);
++Offset;
return true;
}
-bool Decoder::opcode_11111110(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111110(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; b.w\n", OC[Offset]);
++Offset;
return true;
}
-bool Decoder::opcode_11111111(const ulittle8_t *OC, unsigned &Offset,
+bool Decoder::opcode_11111111(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
++Offset;
return true;
}
-void Decoder::decodeOpcodes(ArrayRef<ulittle8_t> Opcodes, unsigned Offset,
+void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
bool Prologue) {
assert((!Prologue || Offset == 0) && "prologue should always use offset 0");
bool Terminated = false;
for (unsigned OI = Offset, OE = Opcodes.size(); !Terminated && OI < OE; ) {
- bool Decoded = false;
- for (unsigned DI = 0, DE = array_lengthof(Ring); DI < DE; ++DI) {
+ for (unsigned DI = 0;; ++DI) {
if ((Opcodes[OI] & Ring[DI].Mask) == Ring[DI].Value) {
Terminated = (this->*Ring[DI].Routine)(Opcodes.data(), OI, 0, Prologue);
- Decoded = true;
break;
}
+ assert(DI < array_lengthof(Ring) && "unhandled opcode");
}
- assert(Decoded && "unhandled opcode");
}
}
if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
return false;
- uint64_t SectionVA;
- if (Section.getAddress(SectionVA))
- return false;
-
+ uint64_t SectionVA = Section.getAddress();
uint64_t Offset = VA - SectionVA;
const ulittle32_t *Data =
reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
static_cast<uint64_t>(XData.CodeWords() * sizeof(uint32_t)));
if (XData.E()) {
- ArrayRef<ulittle8_t> UC = XData.UnwindByteCode();
+ ArrayRef<uint8_t> UC = XData.UnwindByteCode();
if (!XData.F()) {
ListScope PS(SW, "Prologue");
decodeOpcodes(UC, 0, /*Prologue=*/true);
if (!Symbol)
Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true);
- StringRef Name;
- if (Symbol)
- Symbol->getName(Name);
+ ErrorOr<StringRef> Name = Symbol->getName();
+ if (std::error_code EC = Name.getError())
+ report_fatal_error(EC.message());
ListScope EHS(SW, "ExceptionHandler");
- SW.printString("Routine", formatSymbol(Name, Address));
+ SW.printString("Routine", formatSymbol(*Name, Address));
SW.printHex("Parameter", Parameter);
}
StringRef FunctionName;
uint64_t FunctionAddress;
if (Function) {
- Function->getName(FunctionName);
- Function->getAddress(FunctionAddress);
+ ErrorOr<StringRef> FunctionNameOrErr = Function->getName();
+ if (std::error_code EC = FunctionNameOrErr.getError())
+ report_fatal_error(EC.message());
+ FunctionName = *FunctionNameOrErr;
+ ErrorOr<uint64_t> FunctionAddressOrErr = Function->getAddress();
+ if (std::error_code EC = FunctionAddressOrErr.getError())
+ report_fatal_error(EC.message());
+ FunctionAddress = *FunctionAddressOrErr;
} else {
const pe32_header *PEHeader;
if (COFF.getPE32Header(PEHeader))
SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
if (XDataRecord) {
- StringRef Name;
- uint64_t Address;
+ ErrorOr<StringRef> Name = XDataRecord->getName();
+ if (std::error_code EC = Name.getError())
+ report_fatal_error(EC.message());
- XDataRecord->getName(Name);
- XDataRecord->getAddress(Address);
+ ErrorOr<uint64_t> AddressOrErr = XDataRecord->getAddress();
+ if (std::error_code EC = AddressOrErr.getError())
+ report_fatal_error(EC.message());
+ uint64_t Address = *AddressOrErr;
- SW.printString("ExceptionRecord", formatSymbol(Name, Address));
+ SW.printString("ExceptionRecord", formatSymbol(*Name, Address));
- section_iterator SI = COFF.section_end();
- if (XDataRecord->getSection(SI))
+ ErrorOr<section_iterator> SIOrErr = XDataRecord->getSection();
+ if (!SIOrErr)
return false;
+ section_iterator SI = *SIOrErr;
return dumpXDataRecord(COFF, *SI, FunctionAddress, Address);
} else {
StringRef FunctionName;
uint64_t FunctionAddress;
if (Function) {
- Function->getName(FunctionName);
- Function->getAddress(FunctionAddress);
+ ErrorOr<StringRef> FunctionNameOrErr = Function->getName();
+ if (std::error_code EC = FunctionNameOrErr.getError())
+ report_fatal_error(EC.message());
+ FunctionName = *FunctionNameOrErr;
+ ErrorOr<uint64_t> FunctionAddressOrErr = Function->getAddress();
+ FunctionAddress = *FunctionAddressOrErr;
} else {
const pe32_header *PEHeader;
if (COFF.getPE32Header(PEHeader))
break;
}
-error_code Decoder::dumpProcedureData(const COFFObjectFile &COFF) {
+std::error_code Decoder::dumpProcedureData(const COFFObjectFile &COFF) {
for (const auto &Section : COFF.sections()) {
StringRef SectionName;
- if (error_code EC = COFF.getSectionName(COFF.getCOFFSection(Section),
- SectionName))
+ if (std::error_code EC =
+ COFF.getSectionName(COFF.getCOFFSection(Section), SectionName))
return EC;
if (SectionName.startswith(".pdata"))
dumpProcedureData(COFF, Section);
}
- return error_code();
+ return std::error_code();
}
}
}
}
-