15 #include "llvm/Support/DataTypes.h"
24 using namespace dwarf;
33 :
Kind(K), Offset(Offset), Length(Length) {}
39 virtual uint64_t
getOffset()
const {
return Offset; }
45 virtual void parseInstructions(
DataExtractor Data, uint32_t *Offset,
52 virtual void dumpInstructions(
raw_ostream &OS)
const;
85 Instructions.back().Ops.push_back(Operand1);
90 Instructions.back().Ops.push_back(Operand1);
91 Instructions.back().Ops.push_back(Operand2);
101 uint32_t EndOffset) {
102 while (*Offset < EndOffset) {
103 uint8_t Opcode = Data.
getU8(Offset);
115 addInstruction(Primary, Op1);
118 addInstruction(Primary, Op1, Data.
getULEB128(Offset));
130 addInstruction(Opcode);
134 addInstruction(Opcode, Data.
getAddress(Offset));
138 addInstruction(Opcode, Data.
getU8(Offset));
142 addInstruction(Opcode, Data.
getU16(Offset));
146 addInstruction(Opcode, Data.
getU32(Offset));
154 addInstruction(Opcode, Data.
getULEB128(Offset));
158 addInstruction(Opcode, Data.
getSLEB128(Offset));
165 addInstruction(Opcode, Data.
getULEB128(Offset),
172 addInstruction(Opcode, Data.
getULEB128(Offset),
191 CIE(uint64_t Offset, uint64_t Length, uint8_t
Version,
193 uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
194 int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
195 :
FrameEntry(FK_CIE, Offset, Length), Version(Version),
196 Augmentation(std::move(Augmentation)),
197 AddressSize(AddressSize),
198 SegmentDescriptorSize(SegmentDescriptorSize),
199 CodeAlignmentFactor(CodeAlignmentFactor),
200 DataAlignmentFactor(DataAlignmentFactor),
201 ReturnAddressRegister(ReturnAddressRegister) {}
205 uint64_t getCodeAlignmentFactor()
const {
return CodeAlignmentFactor; }
209 OS <<
format(
"%08x %08x %08x CIE",
210 (uint32_t)Offset, (uint32_t)Length,
DW_CIE_ID)
213 OS <<
" Augmentation: \"" << Augmentation <<
"\"\n";
215 OS <<
format(
" Address size: %u\n",
216 (uint32_t)AddressSize);
217 OS <<
format(
" Segment desc size: %u\n",
218 (uint32_t)SegmentDescriptorSize);
220 OS <<
format(
" Code alignment factor: %u\n",
221 (uint32_t)CodeAlignmentFactor);
222 OS <<
format(
" Data alignment factor: %d\n",
223 (int32_t)DataAlignmentFactor);
224 OS <<
format(
" Return address column: %d\n",
225 (int32_t)ReturnAddressRegister);
230 return FE->
getKind() == FK_CIE;
238 uint8_t SegmentDescriptorSize;
239 uint64_t CodeAlignmentFactor;
240 int64_t DataAlignmentFactor;
241 uint64_t ReturnAddressRegister;
251 FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
252 uint64_t InitialLocation, uint64_t AddressRange,
254 :
FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
255 InitialLocation(InitialLocation), AddressRange(AddressRange),
260 CIE *getLinkedCIE()
const {
return LinkedCIE; }
263 OS <<
format(
"%08x %08x %08x FDE ",
264 (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);
265 OS <<
format(
"cie=%08x pc=%08x...%08x\n",
266 (int32_t)LinkedCIEOffset,
267 (uint32_t)InitialLocation,
268 (uint32_t)InitialLocation + (uint32_t)AddressRange);
272 return FE->
getKind() == FK_FDE;
277 uint64_t LinkedCIEOffset;
278 uint64_t InitialLocation;
279 uint64_t AddressRange;
289 OT_FactoredCodeOffset,
290 OT_SignedFactDataOffset,
291 OT_UnsignedFactDataOffset,
302 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
304 OpTypes[OP][0] = OPTYPE0; \
305 OpTypes[OP][1] = OPTYPE1; \
307 #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
308 #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
351 uint64_t Operand, uint64_t CodeAlignmentFactor,
352 int64_t DataAlignmentFactor) {
353 assert(OperandIdx < 2);
358 OS <<
" Unsupported " << (OperandIdx ?
"second" :
"first") <<
" operand to";
360 OS <<
" " << OpcodeName;
362 OS <<
format(
" Opcode %x", Opcode);
367 OS <<
format(
" %" PRIx64, Operand);
373 OS <<
format(
" %+" PRId64, int64_t(Operand));
375 case OT_FactoredCodeOffset:
376 if (CodeAlignmentFactor)
377 OS <<
format(
" %" PRId64, Operand * CodeAlignmentFactor);
379 OS <<
format(
" %" PRId64
"*code_alignment_factor" , Operand);
381 case OT_SignedFactDataOffset:
382 if (DataAlignmentFactor)
383 OS <<
format(
" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
385 OS <<
format(
" %" PRId64
"*data_alignment_factor" , int64_t(Operand));
387 case OT_UnsignedFactDataOffset:
388 if (DataAlignmentFactor)
389 OS <<
format(
" %" PRId64, Operand * DataAlignmentFactor);
391 OS <<
format(
" %" PRId64
"*data_alignment_factor" , Operand);
394 OS <<
format(
" reg%" PRId64, Operand);
403 uint64_t CodeAlignmentFactor = 0;
404 int64_t DataAlignmentFactor = 0;
405 const CIE *Cie =
dyn_cast<CIE>(
this);
408 Cie = cast<FDE>(
this)->getLinkedCIE();
410 CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
411 DataAlignmentFactor = Cie->getDataAlignmentFactor();
414 for (
const auto &Instr : Instructions) {
415 uint8_t Opcode = Instr.Opcode;
419 for (
unsigned i = 0; i < Instr.Ops.size(); ++i)
420 printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,
421 DataAlignmentFactor);
433 uint32_t Offset,
int Length) {
435 for (
int i = 0; i < Length; ++i) {
436 uint8_t c = Data.
getU8(&Offset);
448 uint32_t StartOffset = Offset;
450 bool IsDWARF64 =
false;
451 uint64_t Length = Data.
getU32(&Offset);
454 if (Length == UINT32_MAX) {
459 Length = Data.
getU64(&Offset);
468 uint32_t EndStructureOffset = Offset +
static_cast<uint32_t
>(Length);
476 const char *Augmentation = Data.
getCStr(&Offset);
479 uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.
getU8(&Offset);
480 uint64_t CodeAlignmentFactor = Data.
getULEB128(&Offset);
481 int64_t DataAlignmentFactor = Data.
getSLEB128(&Offset);
482 uint64_t ReturnAddressRegister = Data.
getULEB128(&Offset);
484 auto Cie = make_unique<CIE>(StartOffset, Length,
Version,
486 SegmentDescriptorSize, CodeAlignmentFactor,
487 DataAlignmentFactor, ReturnAddressRegister);
488 CIEs[StartOffset] = Cie.get();
489 Entries.emplace_back(std::move(Cie));
492 uint64_t CIEPointer =
Id;
493 uint64_t InitialLocation = Data.
getAddress(&Offset);
494 uint64_t AddressRange = Data.
getAddress(&Offset);
496 Entries.emplace_back(
new FDE(StartOffset, Length, CIEPointer,
497 InitialLocation, AddressRange,
501 Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
503 if (Offset != EndStructureOffset) {
506 OS <<
format(
"Parsing entry instructions at %lx failed", StartOffset);
515 for (
const auto &Entry : Entries) {
516 Entry->dumpHeader(OS);
517 Entry->dumpInstructions(OS);
static int getDataAlignmentFactor(MCStreamer &streamer)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static ArrayRef< OperandType[2]> OpTypes
Instruction(uint8_t Opcode)
uint64_t Offset
Offset of this entry in the section.
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
uint64_t Length
Entry length as specified in DWARF.
FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
virtual void dumpInstructions(raw_ostream &OS) const
Dump the entry's instructions to the given output stream.
static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx, uint64_t Operand, uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor)
Print Opcode's operand number OperandIdx which has value Operand.
FrameKind getKind() const
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
The instances of the Type class are immutable: once they are created, they are never changed...
#define LLVM_ATTRIBUTE_UNUSED
void addInstruction(uint8_t Opcode, uint64_t Operand1)
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK
virtual void parseInstructions(DataExtractor Data, uint32_t *Offset, uint32_t EndOffset)
Parse and store a sequence of CFI instructions from Data, starting at *Offset and ending at EndOffset...
std::vector< uint64_t > Operands
An entry may contain CFI instructions.
void addInstruction(uint8_t Opcode)
Convenience methods to add a new instruction with the given opcode and operands to the Instructions v...
std::vector< Instruction > Instructions
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const char * CallFrameString(unsigned Encoding)
#define DECLARE_OP1(OP, OPTYPE0)
static ArrayRef< OperandType[2]> getOperandTypes()
Initialize the array describing the types of operands.
OperandType
Types of operands to CF instructions.
void parse(DataExtractor Data)
Parse the section from raw data.
virtual uint64_t getOffset() const
const ARM::ArchExtKind Kind
A raw_ostream that writes to an std::string.
static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, uint32_t Offset, int Length)
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2)
void dump(raw_ostream &OS) const
Dump the section data into the given stream.
const uint64_t DW64_CIE_ID
Abstract frame entry defining the common interface concrete entries implement.