33 using namespace dwarf;
42 :
Kind(K), Offset(Offset), Length(Length) {}
60 virtual void dumpInstructions(
raw_ostream &OS)
const;
93 Instructions.back().Ops.push_back(Operand1);
98 Instructions.back().Ops.push_back(Operand1);
99 Instructions.back().Ops.push_back(Operand2);
109 while (*Offset < EndOffset) {
110 uint8_t Opcode = Data.
getU8(Offset);
120 case DW_CFA_advance_loc:
122 addInstruction(Primary, Op1);
125 addInstruction(Primary, Op1, Data.
getULEB128(Offset));
133 case DW_CFA_remember_state:
134 case DW_CFA_restore_state:
135 case DW_CFA_GNU_window_save:
137 addInstruction(Opcode);
141 addInstruction(Opcode, Data.
getAddress(Offset));
143 case DW_CFA_advance_loc1:
145 addInstruction(Opcode, Data.
getU8(Offset));
147 case DW_CFA_advance_loc2:
149 addInstruction(Opcode, Data.
getU16(Offset));
151 case DW_CFA_advance_loc4:
153 addInstruction(Opcode, Data.
getU32(Offset));
155 case DW_CFA_restore_extended:
156 case DW_CFA_undefined:
157 case DW_CFA_same_value:
158 case DW_CFA_def_cfa_register:
159 case DW_CFA_def_cfa_offset:
161 addInstruction(Opcode, Data.
getULEB128(Offset));
163 case DW_CFA_def_cfa_offset_sf:
165 addInstruction(Opcode, Data.
getSLEB128(Offset));
167 case DW_CFA_offset_extended:
168 case DW_CFA_register:
170 case DW_CFA_val_offset: {
177 addInstruction(Opcode, op1, op2);
180 case DW_CFA_offset_extended_sf:
181 case DW_CFA_def_cfa_sf:
182 case DW_CFA_val_offset_sf: {
187 addInstruction(Opcode, op1, op2);
190 case DW_CFA_def_cfa_expression:
191 case DW_CFA_expression:
192 case DW_CFA_val_expression:
209 uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
210 int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
213 :
FrameEntry(FK_CIE, Offset, Length), Version(Version),
214 Augmentation(std::move(Augmentation)), AddressSize(AddressSize),
215 SegmentDescriptorSize(SegmentDescriptorSize),
216 CodeAlignmentFactor(CodeAlignmentFactor),
217 DataAlignmentFactor(DataAlignmentFactor),
218 ReturnAddressRegister(ReturnAddressRegister),
219 AugmentationData(std::move(AugmentationData)),
220 FDEPointerEncoding(FDEPointerEncoding),
221 LSDAPointerEncoding(LSDAPointerEncoding) {}
223 ~CIE()
override =
default;
225 StringRef getAugmentationString()
const {
return Augmentation; }
226 uint64_t getCodeAlignmentFactor()
const {
return CodeAlignmentFactor; }
229 uint32_t getFDEPointerEncoding()
const {
230 return FDEPointerEncoding;
233 uint32_t getLSDAPointerEncoding()
const {
234 return LSDAPointerEncoding;
238 OS <<
format(
"%08x %08x %08x CIE",
242 OS <<
" Augmentation: \"" << Augmentation <<
"\"\n";
244 OS <<
format(
" Address size: %u\n",
246 OS <<
format(
" Segment desc size: %u\n",
249 OS <<
format(
" Code alignment factor: %u\n",
251 OS <<
format(
" Data alignment factor: %d\n",
252 (int32_t)DataAlignmentFactor);
253 OS <<
format(
" Return address column: %d\n",
254 (int32_t)ReturnAddressRegister);
255 if (!AugmentationData.empty()) {
256 OS <<
" Augmentation data: ";
257 for (uint8_t Byte : AugmentationData)
258 OS << ' ' << hexdigit(Byte >> 4) <<
hexdigit(Byte & 0xf);
265 return FE->
getKind() == FK_CIE;
273 uint8_t SegmentDescriptorSize;
274 uint64_t CodeAlignmentFactor;
275 int64_t DataAlignmentFactor;
276 uint64_t ReturnAddressRegister;
290 FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
291 uint64_t InitialLocation, uint64_t AddressRange,
293 :
FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
294 InitialLocation(InitialLocation), AddressRange(AddressRange),
297 ~FDE()
override =
default;
299 CIE *getLinkedCIE()
const {
return LinkedCIE; }
302 OS <<
format(
"%08x %08x %08x FDE ",
304 OS <<
format(
"cie=%08x pc=%08x...%08x\n",
305 (int32_t)LinkedCIEOffset,
311 return FE->
getKind() == FK_FDE;
316 uint64_t LinkedCIEOffset;
317 uint64_t InitialLocation;
318 uint64_t AddressRange;
328 OT_FactoredCodeOffset,
329 OT_SignedFactDataOffset,
330 OT_UnsignedFactDataOffset,
341 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
343 OpTypes[OP][0] = OPTYPE0; \
344 OpTypes[OP][1] = OPTYPE1; \
346 #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
347 #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
350 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
351 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
352 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
353 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
354 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
355 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
356 DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
359 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
360 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
363 DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
364 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
365 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
366 DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
367 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
368 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
369 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
370 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
391 uint64_t Operand, uint64_t CodeAlignmentFactor,
392 int64_t DataAlignmentFactor) {
398 OS <<
" Unsupported " << (OperandIdx ?
"second" :
"first") <<
" operand to";
400 if (!OpcodeName.empty())
401 OS <<
" " << OpcodeName;
403 OS <<
format(
" Opcode %x", Opcode);
409 OS <<
format(
" %" PRIx64, Operand);
415 OS <<
format(
" %+" PRId64, int64_t(Operand));
417 case OT_FactoredCodeOffset:
418 if (CodeAlignmentFactor)
419 OS <<
format(
" %" PRId64, Operand * CodeAlignmentFactor);
421 OS <<
format(
" %" PRId64
"*code_alignment_factor" , Operand);
423 case OT_SignedFactDataOffset:
424 if (DataAlignmentFactor)
425 OS <<
format(
" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
427 OS <<
format(
" %" PRId64
"*data_alignment_factor" , int64_t(Operand));
429 case OT_UnsignedFactDataOffset:
430 if (DataAlignmentFactor)
431 OS <<
format(
" %" PRId64, Operand * DataAlignmentFactor);
433 OS <<
format(
" %" PRId64
"*data_alignment_factor" , Operand);
436 OS <<
format(
" reg%" PRId64, Operand);
445 uint64_t CodeAlignmentFactor = 0;
446 int64_t DataAlignmentFactor = 0;
447 const CIE *Cie =
dyn_cast<CIE>(
this);
450 Cie = cast<FDE>(
this)->getLinkedCIE();
452 CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
453 DataAlignmentFactor = Cie->getDataAlignmentFactor();
456 for (
const auto &Instr : Instructions) {
457 uint8_t Opcode = Instr.Opcode;
461 for (
unsigned i = 0;
i < Instr.Ops.size(); ++
i)
463 DataAlignmentFactor);
476 for (
int i = 0;
i < Length; ++
i) {
477 uint8_t c = Data.
getU8(&Offset);
484 unsigned symbolEncoding) {
485 unsigned format = symbolEncoding & 0x0f;
507 return Data.
getU16(&Offset);
509 return Data.
getU32(&Offset);
511 return Data.
getU64(&Offset);
524 auto ReportError = [StartOffset](
const char *ErrorMsg) {
527 OS <<
format(ErrorMsg, StartOffset);
532 bool IsDWARF64 =
false;
533 uint64_t Length = Data.
getU32(&Offset);
536 if (Length == UINT32_MAX) {
541 Length = Data.
getU64(&Offset);
554 Id = Data.
getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
561 const char *Augmentation = Data.
getCStr(&Offset);
562 StringRef AugmentationString(Augmentation ? Augmentation :
"");
566 uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.
getU8(&Offset);
567 uint64_t CodeAlignmentFactor = Data.
getULEB128(&Offset);
568 int64_t DataAlignmentFactor = Data.
getSLEB128(&Offset);
569 uint64_t ReturnAddressRegister = Data.
getULEB128(&Offset);
584 for (
unsigned i = 0, e = AugmentationString.
size();
i != e; ++
i) {
585 switch (AugmentationString[
i]) {
587 ReportError(
"Unknown augmentation character in entry at %lx");
589 LSDAPointerEncoding = Data.
getU8(&Offset);
593 ReportError(
"Duplicate personality in entry at %lx");
594 PersonalityEncoding = Data.
getU8(&Offset);
595 Personality =
readPointer(Data, Offset, *PersonalityEncoding);
599 FDEPointerEncoding = Data.
getU8(&Offset);
603 ReportError(
"'z' must be the first character at %lx");
606 AugmentationLength = Data.
getULEB128(&Offset);
607 StartAugmentationOffset =
Offset;
608 EndAugmentationOffset = Offset +
609 static_cast<uint32_t>(*AugmentationLength);
613 if (AugmentationLength.
hasValue()) {
614 if (Offset != EndAugmentationOffset)
615 ReportError(
"Parsing augmentation data at %lx failed");
617 AugmentationData = Data.
getData().
slice(StartAugmentationOffset,
618 EndAugmentationOffset);
622 auto Cie = llvm::make_unique<CIE>(StartOffset, Length,
Version,
623 AugmentationString, AddressSize,
624 SegmentDescriptorSize,
627 ReturnAddressRegister,
628 AugmentationData, FDEPointerEncoding,
629 LSDAPointerEncoding);
630 CIEs[StartOffset] = Cie.get();
631 Entries.emplace_back(std::move(Cie));
634 uint64_t CIEPointer =
Id;
635 uint64_t InitialLocation = 0;
636 uint64_t AddressRange = 0;
637 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
642 ReportError(
"Parsing FDE data at %lx failed due to missing CIE");
645 Cie->getFDEPointerEncoding());
647 Cie->getFDEPointerEncoding());
649 StringRef AugmentationString = Cie->getAugmentationString();
650 if (!AugmentationString.empty()) {
652 uint64_t AugmentationLength = Data.
getULEB128(&Offset);
655 Offset +
static_cast<uint32_t>(AugmentationLength);
659 readPointer(Data, Offset, Cie->getLSDAPointerEncoding());
661 if (Offset != EndAugmentationOffset)
662 ReportError(
"Parsing augmentation data at %lx failed");
669 Entries.emplace_back(
new FDE(StartOffset, Length, CIEPointer,
670 InitialLocation, AddressRange,
674 Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
676 if (Offset != EndStructureOffset)
677 ReportError(
"Parsing entry instructions at %lx failed");
683 for (
const auto &Entry : Entries) {
684 Entry->dumpHeader(OS);
685 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
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Instruction(uint8_t Opcode)
uint64_t Offset
Offset of this entry in the section.
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK
uint64_t Length
Entry length as specified in DWARF.
FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset, unsigned Encoding)
virtual void dumpInstructions(raw_ostream &OS) const
Dump the entry's instructions to the given output stream.
static unsigned getSizeForEncoding(const DataExtractor &Data, unsigned symbolEncoding)
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)...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
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...
StringRef CallFrameString(unsigned Encoding)
#define LLVM_ATTRIBUTE_UNUSED
void addInstruction(uint8_t Opcode, uint64_t Operand1)
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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
static char hexdigit(unsigned X, bool LowerCase=false)
hexdigit - Return the hexadecimal character for the given number X (which should be less than 16)...
#define DECLARE_OP1(OP, OPTYPE0)
static ArrayRef< OperandType[2]> getOperandTypes()
Initialize the array describing the types of operands.
DWARFDebugFrame(bool IsEH)
OperandType
Types of operands to CF instructions.
void parse(DataExtractor Data)
Parse the section from raw data.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
virtual uint64_t getOffset() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.