40 OS <<
"reg" << RegNum;
63 std::optional<uint32_t> AddrSpace) {
69 std::optional<uint32_t> AddrSpace) {
104 if (Offset == 0 && !AddrSpace)
110 OS <<
" in addrspace" << *AddrSpace;
113 Expr->print(
OS, DumpOpts,
nullptr);
132 if (Kind !=
RHS.Kind)
140 return Offset ==
RHS.Offset && Dereference ==
RHS.Dereference;
142 return RegNum ==
RHS.RegNum && Offset ==
RHS.Offset &&
143 Dereference ==
RHS.Dereference;
145 return *Expr == *
RHS.Expr && Dereference ==
RHS.Dereference;
147 return Offset ==
RHS.Offset;
154 for (
const auto &RegLocPair : Locations) {
161 RegLocPair.second.dump(
OS, DumpOpts);
173 unsigned IndentLevel)
const {
176 OS <<
format(
"0x%" PRIx64
": ", *Address);
178 CFAValue.
dump(
OS, DumpOpts);
181 RegLocs.
dump(
OS, DumpOpts);
188 Row.dump(
OS, DumpOpts, 0);
193 unsigned IndentLevel)
const {
195 Row.dump(
OS, DumpOpts, IndentLevel);
200 Rows.
dump(
OS, DumpOpts, 0);
208 "unable to get CIE for FDE at offset 0x%" PRIx64,
219 if (
Error CieError = UT.parseRows(Cie->
cfis(), Row,
nullptr))
220 return std::move(CieError);
224 if (
Error FdeError = UT.parseRows(Fde->
cfis(), Row, &InitialLocs))
225 return std::move(FdeError);
228 if (Row.getRegisterLocations().hasLocations() ||
230 UT.Rows.push_back(Row);
241 if (
Error CieError = UT.parseRows(Cie->
cfis(), Row,
nullptr))
242 return std::move(CieError);
245 if (Row.getRegisterLocations().hasLocations() ||
247 UT.Rows.push_back(Row);
258 while (
C &&
C.tell() < EndOffset) {
259 uint8_t Opcode =
Data.getRelocatedValue(
C, 1);
269 case DW_CFA_advance_loc:
286 "invalid extended CFI opcode 0x%" PRIx8, Opcode);
288 case DW_CFA_remember_state:
289 case DW_CFA_restore_state:
290 case DW_CFA_GNU_window_save:
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);
636 "%s encountered when existing rule for this register is not "
638 CFIP.callFrameString(Inst.Opcode).str().c_str());
641 Row.getRegisterLocations().setRegisterLocation(
650 for (
uint32_t RegNum = 16; RegNum < 32; ++RegNum) {
651 Row.getRegisterLocations().setRegisterLocation(
659 "DW_CFA opcode %#x is not supported for architecture %s",
667 case dwarf::DW_CFA_undefined: {
671 Row.getRegisterLocations().setRegisterLocation(
676 case dwarf::DW_CFA_same_value: {
680 Row.getRegisterLocations().setRegisterLocation(
685 case dwarf::DW_CFA_GNU_args_size:
688 case dwarf::DW_CFA_register: {
695 Row.getRegisterLocations().setRegisterLocation(
700 case dwarf::DW_CFA_val_offset:
701 case dwarf::DW_CFA_val_offset_sf: {
707 return Offset.takeError();
708 Row.getRegisterLocations().setRegisterLocation(
713 case dwarf::DW_CFA_expression: {
717 Row.getRegisterLocations().setRegisterLocation(
722 case dwarf::DW_CFA_val_expression: {
726 Row.getRegisterLocations().setRegisterLocation(
731 case dwarf::DW_CFA_def_cfa_register: {
739 Row.getCFAValue().setRegister(*RegNum);
743 case dwarf::DW_CFA_def_cfa_offset:
744 case dwarf::DW_CFA_def_cfa_offset_sf: {
747 return Offset.takeError();
751 "%s found when CFA rule was not RegPlusOffset",
752 CFIP.callFrameString(Inst.Opcode).str().c_str());
754 Row.getCFAValue().setOffset(*
Offset);
758 case dwarf::DW_CFA_def_cfa:
759 case dwarf::DW_CFA_def_cfa_sf: {
765 return Offset.takeError();
771 case dwarf::DW_CFA_LLVM_def_aspace_cfa:
772 case dwarf::DW_CFA_LLVM_def_aspace_cfa_sf: {
778 return Offset.takeError();
780 Inst.getOperandAsUnsigned(CFIP, 2);
784 *RegNum, *
Offset, *CFAAddrSpace);
788 case dwarf::DW_CFA_def_cfa_expression:
798CFIProgram::getOperandTypes() {
799 static OperandType OpTypes[DW_CFA_restore + 1][
MaxOperands];
800 static bool Initialized =
false;
806#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
808 OpTypes[OP][0] = OPTYPE0; \
809 OpTypes[OP][1] = OPTYPE1; \
810 OpTypes[OP][2] = OPTYPE2; \
812#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
813 DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)
814#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
815#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
818 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
819 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
820 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
821 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
822 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
823 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
824 DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
826 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,
828 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,
829 OT_SignedFactDataOffset, OT_AddressSpace);
831 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
832 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
835 DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
836 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
837 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
838 DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
839 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
840 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
841 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
842 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
863 uint8_t Opcode =
Instr.Opcode;
864 OperandType
Type = getOperandTypes()[Opcode][OperandIdx];
868 OS <<
" Unsupported " << (OperandIdx ?
"second" :
"first") <<
" operand to";
870 if (!OpcodeName.empty())
871 OS <<
" " << OpcodeName;
885 OS <<
format(
" %+" PRId64, int64_t(Operand));
887 case OT_FactoredCodeOffset:
888 if (CodeAlignmentFactor)
889 OS <<
format(
" %" PRId64, Operand * CodeAlignmentFactor);
891 OS <<
format(
" %" PRId64
"*code_alignment_factor" , Operand);
893 case OT_SignedFactDataOffset:
894 if (DataAlignmentFactor)
895 OS <<
format(
" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
897 OS <<
format(
" %" PRId64
"*data_alignment_factor" , int64_t(Operand));
899 case OT_UnsignedFactDataOffset:
900 if (DataAlignmentFactor)
901 OS <<
format(
" %" PRId64, Operand * DataAlignmentFactor);
903 OS <<
format(
" %" PRId64
"*data_alignment_factor" , Operand);
909 case OT_AddressSpace:
910 OS <<
format(
" in addrspace%" PRId64, Operand);
913 assert(
Instr.Expression &&
"missing DWARFExpression object");
915 Instr.Expression->print(
OS, DumpOpts,
nullptr);
921 unsigned IndentLevel)
const {
922 for (
const auto &Instr : Instructions) {
923 uint8_t Opcode = Instr.Opcode;
926 for (
unsigned i = 0; i < Instr.Ops.size(); ++i)
927 printOperand(
OS, DumpOpts, Instr, i, Instr.Ops[i]);
953 <<
format(
" %0*" PRIx64, IsDWARF64 && !DumpOpts.
IsEH ? 16 : 8,
957 if (DumpOpts.
IsEH && Version != 1)
958 OS <<
"WARNING: unsupported CIE version\n";
959 OS <<
format(
" Version: %d\n", Version)
960 <<
" Augmentation: \"" << Augmentation <<
"\"\n";
963 OS <<
format(
" Segment desc size: %u\n",
966 OS <<
format(
" Code alignment factor: %u\n", (
uint32_t)CodeAlignmentFactor);
967 OS <<
format(
" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
968 OS <<
format(
" Return address column: %d\n", (int32_t)ReturnAddressRegister);
970 OS <<
format(
" Personality Address: %016" PRIx64
"\n", *Personality);
971 if (!AugmentationData.empty()) {
972 OS <<
" Augmentation data: ";
973 for (uint8_t Byte : AugmentationData)
974 OS <<
' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
978 CFIs.dump(
OS, DumpOpts);
982 RowsOrErr->dump(
OS, DumpOpts, 1);
986 "decoding the CIE opcodes into rows failed"),
987 RowsOrErr.takeError()));
995 <<
format(
" %0*" PRIx64, IsDWARF64 && !DumpOpts.
IsEH ? 16 : 8, CIEPointer)
998 OS <<
format(
"%08" PRIx64, LinkedCIE->getOffset());
1000 OS <<
"<invalid offset>";
1001 OS <<
format(
" pc=%08" PRIx64
"...%08" PRIx64
"\n", InitialLocation,
1005 OS <<
format(
" LSDA Address: %016" PRIx64
"\n", *LSDAAddress);
1006 CFIs.dump(
OS, DumpOpts);
1010 RowsOrErr->dump(
OS, DumpOpts, 1);
1014 "decoding the FDE opcodes into rows failed"),
1015 RowsOrErr.takeError()));
1021 bool IsEH,
uint64_t EHFrameAddress)
1022 : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
1029 for (
int i = 0; i <
Length; ++i) {
1052 auto Cie = std::make_unique<CIE>(
1053 IsDWARF64, StartOffset, 0, 0,
SmallString<8>(), 0, 0, 0, 0, 0,
1055 CIEs[StartOffset] = Cie.get();
1056 Entries.push_back(std::move(Cie));
1074 if (Id ==
getCIEId(IsDWARF64, IsEH)) {
1076 const char *Augmentation =
Data.getCStr(&
Offset);
1077 StringRef AugmentationString(Augmentation ? Augmentation :
"");
1078 uint8_t AddressSize = Version < 4 ?
Data.getAddressSize() :
1080 Data.setAddressSize(AddressSize);
1081 uint8_t SegmentDescriptorSize = Version < 4 ? 0 :
Data.getU8(&
Offset);
1083 int64_t DataAlignmentFactor =
Data.getSLEB128(&
Offset);
1091 std::optional<uint64_t> Personality;
1092 std::optional<uint32_t> PersonalityEncoding;
1094 std::optional<uint64_t> AugmentationLength;
1099 for (
unsigned i = 0, e = AugmentationString.
size(); i != e; ++i) {
1100 switch (AugmentationString[i]) {
1104 "unknown augmentation character %c in entry at 0x%" PRIx64,
1105 AugmentationString[i], StartOffset);
1113 "duplicate personality in entry at 0x%" PRIx64, StartOffset);
1115 Personality =
Data.getEncodedPointer(
1116 &
Offset, *PersonalityEncoding,
1117 EHFrameAddress ? EHFrameAddress +
Offset : 0);
1130 "'z' must be the first character at 0x%" PRIx64, StartOffset);
1133 AugmentationLength =
Data.getULEB128(&
Offset);
1134 StartAugmentationOffset =
Offset;
1135 EndAugmentationOffset =
Offset + *AugmentationLength;
1148 if (AugmentationLength) {
1149 if (
Offset != EndAugmentationOffset)
1151 "parsing augmentation data at 0x%" PRIx64
1154 AugmentationData =
Data.getData().slice(StartAugmentationOffset,
1155 EndAugmentationOffset);
1159 auto Cie = std::make_unique<CIE>(
1160 IsDWARF64, StartOffset,
Length, Version, AugmentationString,
1161 AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
1162 DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
1163 FDEPointerEncoding, LSDAPointerEncoding, Personality,
1164 PersonalityEncoding, Arch);
1165 CIEs[StartOffset] = Cie.get();
1166 Entries.emplace_back(std::move(Cie));
1172 std::optional<uint64_t> LSDAAddress;
1173 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
1179 "parsing FDE data at 0x%" PRIx64
1180 " failed due to missing CIE",
1184 EHFrameAddress +
Offset)) {
1185 InitialLocation = *Val;
1187 if (
auto Val =
Data.getEncodedPointer(
1193 if (!AugmentationString.
empty()) {
1201 LSDAAddress =
Data.getEncodedPointer(
1203 EHFrameAddress ?
Offset + EHFrameAddress : 0);
1206 if (
Offset != EndAugmentationOffset)
1208 "parsing augmentation data at 0x%" PRIx64
1213 InitialLocation =
Data.getRelocatedAddress(&
Offset);
1217 Entries.emplace_back(
new FDE(IsDWARF64, StartOffset,
Length, CIEPointer,
1219 LSDAAddress, Arch));
1223 Entries.back()->cfis().parse(
Data, &
Offset, EndStructureOffset))
1226 if (
Offset != EndStructureOffset)
1229 "parsing entry instructions at 0x%" PRIx64
" failed", StartOffset);
1236 auto It =
partition_point(Entries, [=](
const std::unique_ptr<FrameEntry> &
E) {
1237 return E->getOffset() <
Offset;
1239 if (It != Entries.end() && (*It)->getOffset() ==
Offset)
1245 std::optional<uint64_t>
Offset)
const {
1246 DumpOpts.
IsEH = IsEH;
1248 if (
auto *Entry = getEntryAtOffset(*
Offset))
1249 Entry->dump(
OS, DumpOpts);
1254 for (
const auto &Entry : Entries)
1255 Entry->dump(
OS, DumpOpts);
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#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=1) 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