39 OS <<
"reg" << RegNum;
62 std::optional<uint32_t> AddrSpace) {
68 std::optional<uint32_t> AddrSpace) {
103 if (Offset == 0 && !AddrSpace)
109 OS <<
" in addrspace" << *AddrSpace;
112 Expr->print(
OS, DumpOpts,
nullptr);
131 if (Kind !=
RHS.Kind)
139 return Offset ==
RHS.Offset && Dereference ==
RHS.Dereference;
141 return RegNum ==
RHS.RegNum && Offset ==
RHS.Offset &&
142 Dereference ==
RHS.Dereference;
144 return *Expr == *
RHS.Expr && Dereference ==
RHS.Dereference;
146 return Offset ==
RHS.Offset;
153 for (
const auto &RegLocPair : Locations) {
160 RegLocPair.second.dump(
OS, DumpOpts);
172 unsigned IndentLevel)
const {
175 OS <<
format(
"0x%" PRIx64
": ", *Address);
177 CFAValue.
dump(
OS, DumpOpts);
180 RegLocs.
dump(
OS, DumpOpts);
187 Row.dump(
OS, DumpOpts, 0);
192 unsigned IndentLevel)
const {
194 Row.dump(
OS, DumpOpts, IndentLevel);
199 Rows.
dump(
OS, DumpOpts, 0);
207 "unable to get CIE for FDE at offset 0x%" PRIx64,
218 if (
Error CieError = UT.parseRows(Cie->
cfis(), Row,
nullptr))
219 return std::move(CieError);
223 if (
Error FdeError = UT.parseRows(Fde->
cfis(), Row, &InitialLocs))
224 return std::move(FdeError);
227 if (Row.getRegisterLocations().hasLocations() ||
229 UT.Rows.push_back(Row);
240 if (
Error CieError = UT.parseRows(Cie->
cfis(), Row,
nullptr))
241 return std::move(CieError);
244 if (Row.getRegisterLocations().hasLocations() ||
246 UT.Rows.push_back(Row);
257 while (
C &&
C.tell() < EndOffset) {
268 case DW_CFA_advance_loc:
285 "invalid extended CFI opcode 0x%" PRIx8, Opcode);
287 case DW_CFA_remember_state:
288 case DW_CFA_restore_state:
289 case DW_CFA_GNU_window_save:
290 case DW_CFA_AARCH64_negate_ra_state_with_pc:
298 case DW_CFA_advance_loc1:
302 case DW_CFA_advance_loc2:
306 case DW_CFA_advance_loc4:
310 case DW_CFA_restore_extended:
311 case DW_CFA_undefined:
312 case DW_CFA_same_value:
313 case DW_CFA_def_cfa_register:
314 case DW_CFA_def_cfa_offset:
315 case DW_CFA_GNU_args_size:
319 case DW_CFA_def_cfa_offset_sf:
323 case DW_CFA_LLVM_def_aspace_cfa:
324 case DW_CFA_LLVM_def_aspace_cfa_sf: {
325 auto RegNum =
Data.getULEB128(
C);
326 auto CfaOffset = Opcode == DW_CFA_LLVM_def_aspace_cfa
328 :
Data.getSLEB128(
C);
333 case DW_CFA_offset_extended:
334 case DW_CFA_register:
336 case DW_CFA_val_offset: {
346 case DW_CFA_offset_extended_sf:
347 case DW_CFA_def_cfa_sf:
348 case DW_CFA_val_offset_sf: {
356 case DW_CFA_def_cfa_expression: {
362 Data.getAddressSize());
366 Instructions.back().Expression =
370 case DW_CFA_expression:
371 case DW_CFA_val_expression: {
378 Data.getAddressSize());
382 Instructions.back().Expression =
390 return C.takeError();
397const char *CFIProgram::operandTypeString(CFIProgram::OperandType OT) {
398#define ENUM_TO_CSTR(e) \
413 return "<unknown CFIProgram::OperandType>";
421 "operand index %" PRIu32
" is not valid",
423 OperandType
Type = CFIP.getOperandTypes()[
Opcode][OperandIdx];
430 "op[%" PRIu32
"] has type %s which has no value",
431 OperandIdx, CFIProgram::operandTypeString(
Type));
434 case OT_SignedFactDataOffset:
435 case OT_UnsignedFactDataOffset:
438 "op[%" PRIu32
"] has OperandType OT_Offset which produces a signed "
439 "result, call getOperandAsSigned instead",
444 case OT_AddressSpace:
447 case OT_FactoredCodeOffset: {
449 if (CodeAlignmentFactor == 0)
452 "op[%" PRIu32
"] has type OT_FactoredCodeOffset but code alignment "
455 return Operand * CodeAlignmentFactor;
466 "operand index %" PRIu32
" is not valid",
468 OperandType
Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
475 "op[%" PRIu32
"] has type %s which has no value",
476 OperandIdx, CFIProgram::operandTypeString(
Type));
480 case OT_AddressSpace:
483 "op[%" PRIu32
"] has OperandType %s which produces an unsigned result, "
484 "call getOperandAsUnsigned instead",
485 OperandIdx, CFIProgram::operandTypeString(
Type));
488 return (int64_t)Operand;
490 case OT_FactoredCodeOffset:
491 case OT_SignedFactDataOffset: {
492 const int64_t DataAlignmentFactor = CFIP.
dataAlign();
493 if (DataAlignmentFactor == 0)
495 "op[%" PRIu32
"] has type %s but data "
497 OperandIdx, CFIProgram::operandTypeString(
Type));
498 return int64_t(Operand) * DataAlignmentFactor;
501 case OT_UnsignedFactDataOffset: {
502 const int64_t DataAlignmentFactor = CFIP.
dataAlign();
503 if (DataAlignmentFactor == 0)
506 "] has type OT_UnsignedFactDataOffset but data "
509 return Operand * DataAlignmentFactor;
518 std::vector<std::pair<UnwindLocation, RegisterLocations>> States;
520 switch (Inst.Opcode) {
521 case dwarf::DW_CFA_set_loc: {
532 if (*NewAddress <= Row.getAddress())
535 "%s with adrress 0x%" PRIx64
" which must be greater than the "
536 "current row address 0x%" PRIx64,
537 CFIP.callFrameString(Inst.Opcode).str().c_str(), *NewAddress,
540 Row.setAddress(*NewAddress);
544 case dwarf::DW_CFA_advance_loc:
545 case dwarf::DW_CFA_advance_loc1:
546 case dwarf::DW_CFA_advance_loc2:
547 case dwarf::DW_CFA_advance_loc4: {
557 return Offset.takeError();
558 Row.slideAddress(*
Offset);
562 case dwarf::DW_CFA_restore:
563 case dwarf::DW_CFA_restore_extended: {
568 if (InitialLocs ==
nullptr)
571 CFIP.callFrameString(Inst.Opcode).str().c_str());
575 if (std::optional<UnwindLocation> O =
577 Row.getRegisterLocations().setRegisterLocation(*RegNum, *O);
579 Row.getRegisterLocations().removeRegisterLocation(*RegNum);
583 case dwarf::DW_CFA_offset:
584 case dwarf::DW_CFA_offset_extended:
585 case dwarf::DW_CFA_offset_extended_sf: {
591 return Offset.takeError();
592 Row.getRegisterLocations().setRegisterLocation(
597 case dwarf::DW_CFA_nop:
600 case dwarf::DW_CFA_remember_state:
602 std::make_pair(Row.getCFAValue(), Row.getRegisterLocations()));
605 case dwarf::DW_CFA_restore_state:
608 "DW_CFA_restore_state without a matching "
609 "previous DW_CFA_remember_state");
610 Row.getCFAValue() = States.back().first;
611 Row.getRegisterLocations() = States.back().second;
615 case dwarf::DW_CFA_GNU_window_save:
616 switch (CFIP.triple()) {
626 constexpr uint32_t AArch64DWARFPAuthRaState = 34;
627 auto LRLoc = Row.getRegisterLocations().getRegisterLocation(
628 AArch64DWARFPAuthRaState);
632 LRLoc->setConstant(LRLoc->getConstant() ^ 1);
633 Row.getRegisterLocations().setRegisterLocation(
634 AArch64DWARFPAuthRaState, *LRLoc);
638 "%s encountered when existing rule for this register is not "
640 CFIP.callFrameString(Inst.Opcode).str().c_str());
643 Row.getRegisterLocations().setRegisterLocation(
652 for (
uint32_t RegNum = 16; RegNum < 32; ++RegNum) {
653 Row.getRegisterLocations().setRegisterLocation(
661 "DW_CFA opcode %#x is not supported for architecture %s",
669 case dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc: {
670 constexpr uint32_t AArch64DWARFPAuthRaState = 34;
671 auto LRLoc = Row.getRegisterLocations().getRegisterLocation(
672 AArch64DWARFPAuthRaState);
676 LRLoc->setConstant(LRLoc->getConstant() ^ 0x3);
680 "%s encountered when existing rule for this register is not "
682 CFIP.callFrameString(Inst.Opcode).str().c_str());
685 Row.getRegisterLocations().setRegisterLocation(
691 case dwarf::DW_CFA_undefined: {
695 Row.getRegisterLocations().setRegisterLocation(
700 case dwarf::DW_CFA_same_value: {
704 Row.getRegisterLocations().setRegisterLocation(
709 case dwarf::DW_CFA_GNU_args_size:
712 case dwarf::DW_CFA_register: {
719 Row.getRegisterLocations().setRegisterLocation(
724 case dwarf::DW_CFA_val_offset:
725 case dwarf::DW_CFA_val_offset_sf: {
731 return Offset.takeError();
732 Row.getRegisterLocations().setRegisterLocation(
737 case dwarf::DW_CFA_expression: {
741 Row.getRegisterLocations().setRegisterLocation(
746 case dwarf::DW_CFA_val_expression: {
750 Row.getRegisterLocations().setRegisterLocation(
755 case dwarf::DW_CFA_def_cfa_register: {
763 Row.getCFAValue().setRegister(*RegNum);
767 case dwarf::DW_CFA_def_cfa_offset:
768 case dwarf::DW_CFA_def_cfa_offset_sf: {
771 return Offset.takeError();
775 "%s found when CFA rule was not RegPlusOffset",
776 CFIP.callFrameString(Inst.Opcode).str().c_str());
778 Row.getCFAValue().setOffset(*
Offset);
782 case dwarf::DW_CFA_def_cfa:
783 case dwarf::DW_CFA_def_cfa_sf: {
789 return Offset.takeError();
795 case dwarf::DW_CFA_LLVM_def_aspace_cfa:
796 case dwarf::DW_CFA_LLVM_def_aspace_cfa_sf: {
802 return Offset.takeError();
804 Inst.getOperandAsUnsigned(CFIP, 2);
808 *RegNum, *
Offset, *CFAAddrSpace);
812 case dwarf::DW_CFA_def_cfa_expression:
822CFIProgram::getOperandTypes() {
823 static OperandType OpTypes[DW_CFA_restore + 1][
MaxOperands];
824 static bool Initialized =
false;
830#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
832 OpTypes[OP][0] = OPTYPE0; \
833 OpTypes[OP][1] = OPTYPE1; \
834 OpTypes[OP][2] = OPTYPE2; \
836#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
837 DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)
838#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
839#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
842 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
843 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
844 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
845 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
846 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
847 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
848 DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
850 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,
852 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,
853 OT_SignedFactDataOffset, OT_AddressSpace);
855 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
856 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
859 DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
860 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
861 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
862 DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
863 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
864 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
865 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
866 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
872 DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc);
887 std::optional<uint64_t> &
Address)
const {
890 OperandType
Type = getOperandTypes()[Opcode][OperandIdx];
894 OS <<
" Unsupported " << (OperandIdx ?
"second" :
"first") <<
" operand to";
896 if (!OpcodeName.empty())
897 OS <<
" " << OpcodeName;
912 OS <<
format(
" %+" PRId64, int64_t(Operand));
914 case OT_FactoredCodeOffset:
915 if (CodeAlignmentFactor)
916 OS <<
format(
" %" PRId64, Operand * CodeAlignmentFactor);
918 OS <<
format(
" %" PRId64
"*code_alignment_factor", Operand);
919 if (
Address && CodeAlignmentFactor) {
920 *
Address += Operand * CodeAlignmentFactor;
924 case OT_SignedFactDataOffset:
925 if (DataAlignmentFactor)
926 OS <<
format(
" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
928 OS <<
format(
" %" PRId64
"*data_alignment_factor" , int64_t(Operand));
930 case OT_UnsignedFactDataOffset:
931 if (DataAlignmentFactor)
932 OS <<
format(
" %" PRId64, Operand * DataAlignmentFactor);
934 OS <<
format(
" %" PRId64
"*data_alignment_factor" , Operand);
940 case OT_AddressSpace:
941 OS <<
format(
" in addrspace%" PRId64, Operand);
944 assert(
Instr.Expression &&
"missing DWARFExpression object");
946 Instr.Expression->print(
OS, DumpOpts,
nullptr);
952 unsigned IndentLevel,
953 std::optional<uint64_t>
Address)
const {
954 for (
const auto &Instr : Instructions) {
958 for (
unsigned i = 0; i < Instr.Ops.size(); ++i)
959 printOperand(
OS, DumpOpts, Instr, i, Instr.Ops[i],
Address);
985 <<
format(
" %0*" PRIx64, IsDWARF64 && !DumpOpts.
IsEH ? 16 : 8,
990 OS <<
"WARNING: unsupported CIE version\n";
992 <<
" Augmentation: \"" << Augmentation <<
"\"\n";
995 OS <<
format(
" Segment desc size: %u\n",
998 OS <<
format(
" Code alignment factor: %u\n", (
uint32_t)CodeAlignmentFactor);
999 OS <<
format(
" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
1000 OS <<
format(
" Return address column: %d\n", (int32_t)ReturnAddressRegister);
1002 OS <<
format(
" Personality Address: %016" PRIx64
"\n", *Personality);
1003 if (!AugmentationData.empty()) {
1004 OS <<
" Augmentation data: ";
1005 for (
uint8_t Byte : AugmentationData)
1006 OS <<
' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
1010 CFIs.dump(
OS, DumpOpts, 1, {});
1014 RowsOrErr->dump(
OS, DumpOpts, 1);
1018 "decoding the CIE opcodes into rows failed"),
1019 RowsOrErr.takeError()));
1027 <<
format(
" %0*" PRIx64, IsDWARF64 && !DumpOpts.
IsEH ? 16 : 8, CIEPointer)
1030 OS <<
format(
"%08" PRIx64, LinkedCIE->getOffset());
1032 OS <<
"<invalid offset>";
1033 OS <<
format(
" pc=%08" PRIx64
"...%08" PRIx64
"\n", InitialLocation,
1037 OS <<
format(
" LSDA Address: %016" PRIx64
"\n", *LSDAAddress);
1038 CFIs.dump(
OS, DumpOpts, 1, InitialLocation);
1042 RowsOrErr->dump(
OS, DumpOpts, 1);
1046 "decoding the FDE opcodes into rows failed"),
1047 RowsOrErr.takeError()));
1053 bool IsEH,
uint64_t EHFrameAddress)
1054 : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
1061 for (
int i = 0; i <
Length; ++i) {
1084 auto Cie = std::make_unique<CIE>(
1085 IsDWARF64, StartOffset, 0, 0,
SmallString<8>(), 0, 0, 0, 0, 0,
1087 CIEs[StartOffset] = Cie.get();
1088 Entries.push_back(std::move(Cie));
1106 if (Id ==
getCIEId(IsDWARF64, IsEH)) {
1108 const char *Augmentation =
Data.getCStr(&
Offset);
1109 StringRef AugmentationString(Augmentation ? Augmentation :
"");
1112 Data.setAddressSize(AddressSize);
1115 int64_t DataAlignmentFactor =
Data.getSLEB128(&
Offset);
1123 std::optional<uint64_t> Personality;
1124 std::optional<uint32_t> PersonalityEncoding;
1126 std::optional<uint64_t> AugmentationLength;
1131 for (
unsigned i = 0, e = AugmentationString.
size(); i != e; ++i) {
1132 switch (AugmentationString[i]) {
1136 "unknown augmentation character %c in entry at 0x%" PRIx64,
1137 AugmentationString[i], StartOffset);
1145 "duplicate personality in entry at 0x%" PRIx64, StartOffset);
1147 Personality =
Data.getEncodedPointer(
1148 &
Offset, *PersonalityEncoding,
1149 EHFrameAddress ? EHFrameAddress +
Offset : 0);
1162 "'z' must be the first character at 0x%" PRIx64, StartOffset);
1165 AugmentationLength =
Data.getULEB128(&
Offset);
1166 StartAugmentationOffset =
Offset;
1167 EndAugmentationOffset =
Offset + *AugmentationLength;
1180 if (AugmentationLength) {
1181 if (
Offset != EndAugmentationOffset)
1183 "parsing augmentation data at 0x%" PRIx64
1186 AugmentationData =
Data.getData().slice(StartAugmentationOffset,
1187 EndAugmentationOffset);
1191 auto Cie = std::make_unique<CIE>(
1192 IsDWARF64, StartOffset,
Length,
Version, AugmentationString,
1193 AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
1194 DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
1195 FDEPointerEncoding, LSDAPointerEncoding, Personality,
1196 PersonalityEncoding, Arch);
1197 CIEs[StartOffset] = Cie.get();
1198 Entries.emplace_back(std::move(Cie));
1204 std::optional<uint64_t> LSDAAddress;
1205 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
1211 "parsing FDE data at 0x%" PRIx64
1212 " failed due to missing CIE",
1216 EHFrameAddress +
Offset)) {
1217 InitialLocation = *Val;
1219 if (
auto Val =
Data.getEncodedPointer(
1225 if (!AugmentationString.
empty()) {
1233 LSDAAddress =
Data.getEncodedPointer(
1235 EHFrameAddress ?
Offset + EHFrameAddress : 0);
1238 if (
Offset != EndAugmentationOffset)
1240 "parsing augmentation data at 0x%" PRIx64
1245 InitialLocation =
Data.getRelocatedAddress(&
Offset);
1249 Entries.emplace_back(
new FDE(IsDWARF64, StartOffset,
Length, CIEPointer,
1251 LSDAAddress, Arch));
1255 Entries.back()->cfis().parse(
Data, &
Offset, EndStructureOffset))
1258 if (
Offset != EndStructureOffset)
1261 "parsing entry instructions at 0x%" PRIx64
" failed", StartOffset);
1268 auto It =
partition_point(Entries, [=](
const std::unique_ptr<FrameEntry> &E) {
1269 return E->getOffset() <
Offset;
1271 if (It != Entries.end() && (*It)->getOffset() ==
Offset)
1277 std::optional<uint64_t>
Offset)
const {
1278 DumpOpts.
IsEH = IsEH;
1280 if (
auto *Entry = getEntryAtOffset(*
Offset))
1281 Entry->dump(
OS, DumpOpts);
1286 for (
const auto &Entry : Entries)
1287 Entry->dump(
OS, DumpOpts);
#define LLVM_ATTRIBUTE_UNUSED
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK
static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, uint64_t Offset, int Length)
static void printRegister(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned RegNum)
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK
#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2)
#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)
#define DECLARE_OP1(OP, OPTYPE0)
constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH)
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A class that represents an address range.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
DWARFDebugFrame(Triple::ArchType Arch, bool IsEH=false, uint64_t EHFrameAddress=0)
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, std::optional< uint64_t > Offset) const
Dump the section data into the given stream.
Error parse(DWARFDataExtractor Data)
Parse the section from raw data.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
Class representing an expression and its matching format.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
static StringRef getArchTypeName(ArchType Kind)
Get the canonical name for the Kind architecture.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Represent a sequence of Call Frame Information instructions that, when read in order,...
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel, std::optional< uint64_t > InitialLocation) const
uint64_t codeAlign() const
Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset)
Parse and store a sequence of CFI instructions from Data, starting at *Offset and ending at EndOffset...
static constexpr size_t MaxOperands
void addInstruction(const Instruction &I)
int64_t dataAlign() const
StringRef callFrameString(unsigned Opcode) const
Get a DWARF CFI call frame string for the given DW_CFA opcode.
DWARF Common Information Entry (CIE)
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override
Dump the instructions in this CFI fragment.
uint32_t getLSDAPointerEncoding() const
uint32_t getFDEPointerEncoding() const
StringRef getAugmentationString() const
DWARF Frame Description Entry (FDE)
uint64_t getAddressRange() const
uint64_t getInitialLocation() const
const CIE * getLinkedCIE() const
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const override
Dump the instructions in this CFI fragment.
An entry in either debug_frame or eh_frame.
const CFIProgram & cfis() const
uint64_t getOffset() const
A class that can track all registers with locations in a UnwindRow object.
std::optional< UnwindLocation > getRegisterLocation(uint32_t RegNum) const
Return the location for the register in RegNum if there is a location.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const
Dump all registers + locations that are currently defined in this object.
bool hasLocations() const
Returns true if we have any register locations in this object.
A class that represents a location for the Call Frame Address (CFA) or a register.
static UnwindLocation createUndefined()
Create a location where the value is undefined and not available.
static UnwindLocation createAtRegisterPlusOffset(uint32_t Reg, int32_t Off, std::optional< uint32_t > AddrSpace=std::nullopt)
static UnwindLocation createIsRegisterPlusOffset(uint32_t Reg, int32_t Off, std::optional< uint32_t > AddrSpace=std::nullopt)
Create a location where the saved value is in (Deref == false) or at (Deref == true) a regiser plus a...
static UnwindLocation createAtDWARFExpression(DWARFExpression Expr)
static UnwindLocation createUnspecified()
Create a location whose rule is set to Unspecified.
bool operator==(const UnwindLocation &RHS) const
static UnwindLocation createIsDWARFExpression(DWARFExpression Expr)
Create a location whose value is the result of evaluating a DWARF expression.
@ Undefined
Register is not available and can't be recovered.
@ Constant
Value is a constant value contained in "Offset": reg = Offset.
@ DWARFExpr
Register or CFA value is in or at a value found by evaluating a DWARF expression: reg = eval(dwarf_ex...
@ Same
Register value is in the register, nothing needs to be done to unwind it: reg = reg.
@ CFAPlusOffset
Register is in or at the CFA plus an offset: reg = CFA + offset reg = defef(CFA + offset)
@ Unspecified
Not specified.
@ RegPlusOffset
Register or CFA is in or at a register plus offset, optionally in an address space: reg = reg + offse...
static UnwindLocation createIsConstant(int32_t Value)
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const
Dump a location expression as text and use the register information if some is provided.
static UnwindLocation createAtCFAPlusOffset(int32_t Off)
static UnwindLocation createSame()
Create a location where the value is known to be in the register itself.
static UnwindLocation createIsCFAPlusOffset(int32_t Off)
Create a location that is in (Deref == false) or at (Deref == true) the CFA plus an offset.
A class that represents a single row in the unwind table that is decoded by parsing the DWARF Call Fr...
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel=0) const
Dump the UnwindRow to the stream.
bool hasAddress() const
Returns true if the address is valid in this object.
A class that contains all UnwindRow objects for an FDE or a single unwind row for a CIE.
static Expected< UnwindTable > create(const CIE *Cie)
Create an UnwindTable from a Common Information Entry (CIE).
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel=0) const
Dump the UnwindTable to the stream.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch)
StringRef FormatString(DwarfFormat Format)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
const uint32_t DW_CIE_ID
Special ID values that distinguish a CIE from a FDE in DWARF CFI.
const uint64_t DW64_CIE_ID
constexpr uint32_t InvalidRegisterNumber
raw_ostream & operator<<(raw_ostream &OS, const UnwindLocation &R)
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Container for dump options that control which debug information will be dumped.
std::function< void(Error)> RecoverableErrorHandler
std::function< llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)> GetNameForDWARFReg
An instruction consists of a DWARF CFI opcode and an optional sequence of operands.
Expected< uint64_t > getOperandAsUnsigned(const CFIProgram &CFIP, uint32_t OperandIdx) const
Expected< int64_t > getOperandAsSigned(const CFIProgram &CFIP, uint32_t OperandIdx) const