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);
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_undefined: {
673 Row.getRegisterLocations().setRegisterLocation(
678 case dwarf::DW_CFA_same_value: {
682 Row.getRegisterLocations().setRegisterLocation(
687 case dwarf::DW_CFA_GNU_args_size:
690 case dwarf::DW_CFA_register: {
697 Row.getRegisterLocations().setRegisterLocation(
702 case dwarf::DW_CFA_val_offset:
703 case dwarf::DW_CFA_val_offset_sf: {
709 return Offset.takeError();
710 Row.getRegisterLocations().setRegisterLocation(
715 case dwarf::DW_CFA_expression: {
719 Row.getRegisterLocations().setRegisterLocation(
724 case dwarf::DW_CFA_val_expression: {
728 Row.getRegisterLocations().setRegisterLocation(
733 case dwarf::DW_CFA_def_cfa_register: {
741 Row.getCFAValue().setRegister(*RegNum);
745 case dwarf::DW_CFA_def_cfa_offset:
746 case dwarf::DW_CFA_def_cfa_offset_sf: {
749 return Offset.takeError();
753 "%s found when CFA rule was not RegPlusOffset",
754 CFIP.callFrameString(Inst.Opcode).str().c_str());
756 Row.getCFAValue().setOffset(*
Offset);
760 case dwarf::DW_CFA_def_cfa:
761 case dwarf::DW_CFA_def_cfa_sf: {
767 return Offset.takeError();
773 case dwarf::DW_CFA_LLVM_def_aspace_cfa:
774 case dwarf::DW_CFA_LLVM_def_aspace_cfa_sf: {
780 return Offset.takeError();
782 Inst.getOperandAsUnsigned(CFIP, 2);
786 *RegNum, *
Offset, *CFAAddrSpace);
790 case dwarf::DW_CFA_def_cfa_expression:
800CFIProgram::getOperandTypes() {
801 static OperandType OpTypes[DW_CFA_restore + 1][
MaxOperands];
802 static bool Initialized =
false;
808#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
810 OpTypes[OP][0] = OPTYPE0; \
811 OpTypes[OP][1] = OPTYPE1; \
812 OpTypes[OP][2] = OPTYPE2; \
814#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
815 DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)
816#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
817#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
820 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
821 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
822 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
823 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
824 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
825 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
826 DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
828 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,
830 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,
831 OT_SignedFactDataOffset, OT_AddressSpace);
833 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
834 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
837 DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
838 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
839 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
840 DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
841 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
842 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
843 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
844 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
864 std::optional<uint64_t> &
Address)
const {
866 uint8_t Opcode =
Instr.Opcode;
867 OperandType
Type = getOperandTypes()[Opcode][OperandIdx];
871 OS <<
" Unsupported " << (OperandIdx ?
"second" :
"first") <<
" operand to";
873 if (!OpcodeName.empty())
874 OS <<
" " << OpcodeName;
889 OS <<
format(
" %+" PRId64, int64_t(Operand));
891 case OT_FactoredCodeOffset:
892 if (CodeAlignmentFactor)
893 OS <<
format(
" %" PRId64, Operand * CodeAlignmentFactor);
895 OS <<
format(
" %" PRId64
"*code_alignment_factor", Operand);
896 if (
Address && CodeAlignmentFactor) {
897 *
Address += Operand * CodeAlignmentFactor;
901 case OT_SignedFactDataOffset:
902 if (DataAlignmentFactor)
903 OS <<
format(
" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
905 OS <<
format(
" %" PRId64
"*data_alignment_factor" , int64_t(Operand));
907 case OT_UnsignedFactDataOffset:
908 if (DataAlignmentFactor)
909 OS <<
format(
" %" PRId64, Operand * DataAlignmentFactor);
911 OS <<
format(
" %" PRId64
"*data_alignment_factor" , Operand);
917 case OT_AddressSpace:
918 OS <<
format(
" in addrspace%" PRId64, Operand);
921 assert(
Instr.Expression &&
"missing DWARFExpression object");
923 Instr.Expression->print(
OS, DumpOpts,
nullptr);
929 unsigned IndentLevel,
930 std::optional<uint64_t>
Address)
const {
931 for (
const auto &Instr : Instructions) {
932 uint8_t Opcode = Instr.Opcode;
935 for (
unsigned i = 0; i < Instr.Ops.size(); ++i)
936 printOperand(
OS, DumpOpts, Instr, i, Instr.Ops[i],
Address);
962 <<
format(
" %0*" PRIx64, IsDWARF64 && !DumpOpts.
IsEH ? 16 : 8,
967 OS <<
"WARNING: unsupported CIE version\n";
969 <<
" Augmentation: \"" << Augmentation <<
"\"\n";
972 OS <<
format(
" Segment desc size: %u\n",
975 OS <<
format(
" Code alignment factor: %u\n", (
uint32_t)CodeAlignmentFactor);
976 OS <<
format(
" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
977 OS <<
format(
" Return address column: %d\n", (int32_t)ReturnAddressRegister);
979 OS <<
format(
" Personality Address: %016" PRIx64
"\n", *Personality);
980 if (!AugmentationData.empty()) {
981 OS <<
" Augmentation data: ";
982 for (uint8_t Byte : AugmentationData)
983 OS <<
' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
987 CFIs.dump(
OS, DumpOpts, 1, {});
991 RowsOrErr->dump(
OS, DumpOpts, 1);
995 "decoding the CIE opcodes into rows failed"),
996 RowsOrErr.takeError()));
1004 <<
format(
" %0*" PRIx64, IsDWARF64 && !DumpOpts.
IsEH ? 16 : 8, CIEPointer)
1007 OS <<
format(
"%08" PRIx64, LinkedCIE->getOffset());
1009 OS <<
"<invalid offset>";
1010 OS <<
format(
" pc=%08" PRIx64
"...%08" PRIx64
"\n", InitialLocation,
1014 OS <<
format(
" LSDA Address: %016" PRIx64
"\n", *LSDAAddress);
1015 CFIs.dump(
OS, DumpOpts, 1, InitialLocation);
1019 RowsOrErr->dump(
OS, DumpOpts, 1);
1023 "decoding the FDE opcodes into rows failed"),
1024 RowsOrErr.takeError()));
1030 bool IsEH,
uint64_t EHFrameAddress)
1031 : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
1038 for (
int i = 0; i <
Length; ++i) {
1061 auto Cie = std::make_unique<CIE>(
1062 IsDWARF64, StartOffset, 0, 0,
SmallString<8>(), 0, 0, 0, 0, 0,
1064 CIEs[StartOffset] = Cie.get();
1065 Entries.push_back(std::move(Cie));
1083 if (Id ==
getCIEId(IsDWARF64, IsEH)) {
1085 const char *Augmentation =
Data.getCStr(&
Offset);
1086 StringRef AugmentationString(Augmentation ? Augmentation :
"");
1087 uint8_t AddressSize =
Version < 4 ?
Data.getAddressSize() :
1089 Data.setAddressSize(AddressSize);
1092 int64_t DataAlignmentFactor =
Data.getSLEB128(&
Offset);
1100 std::optional<uint64_t> Personality;
1101 std::optional<uint32_t> PersonalityEncoding;
1103 std::optional<uint64_t> AugmentationLength;
1108 for (
unsigned i = 0, e = AugmentationString.
size(); i != e; ++i) {
1109 switch (AugmentationString[i]) {
1113 "unknown augmentation character %c in entry at 0x%" PRIx64,
1114 AugmentationString[i], StartOffset);
1122 "duplicate personality in entry at 0x%" PRIx64, StartOffset);
1124 Personality =
Data.getEncodedPointer(
1125 &
Offset, *PersonalityEncoding,
1126 EHFrameAddress ? EHFrameAddress +
Offset : 0);
1139 "'z' must be the first character at 0x%" PRIx64, StartOffset);
1142 AugmentationLength =
Data.getULEB128(&
Offset);
1143 StartAugmentationOffset =
Offset;
1144 EndAugmentationOffset =
Offset + *AugmentationLength;
1157 if (AugmentationLength) {
1158 if (
Offset != EndAugmentationOffset)
1160 "parsing augmentation data at 0x%" PRIx64
1163 AugmentationData =
Data.getData().slice(StartAugmentationOffset,
1164 EndAugmentationOffset);
1168 auto Cie = std::make_unique<CIE>(
1169 IsDWARF64, StartOffset,
Length,
Version, AugmentationString,
1170 AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
1171 DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
1172 FDEPointerEncoding, LSDAPointerEncoding, Personality,
1173 PersonalityEncoding, Arch);
1174 CIEs[StartOffset] = Cie.get();
1175 Entries.emplace_back(std::move(Cie));
1181 std::optional<uint64_t> LSDAAddress;
1182 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
1188 "parsing FDE data at 0x%" PRIx64
1189 " failed due to missing CIE",
1193 EHFrameAddress +
Offset)) {
1194 InitialLocation = *Val;
1196 if (
auto Val =
Data.getEncodedPointer(
1202 if (!AugmentationString.
empty()) {
1210 LSDAAddress =
Data.getEncodedPointer(
1212 EHFrameAddress ?
Offset + EHFrameAddress : 0);
1215 if (
Offset != EndAugmentationOffset)
1217 "parsing augmentation data at 0x%" PRIx64
1222 InitialLocation =
Data.getRelocatedAddress(&
Offset);
1226 Entries.emplace_back(
new FDE(IsDWARF64, StartOffset,
Length, CIEPointer,
1228 LSDAAddress, Arch));
1232 Entries.back()->cfis().parse(
Data, &
Offset, EndStructureOffset))
1235 if (
Offset != EndStructureOffset)
1238 "parsing entry instructions at 0x%" PRIx64
" failed", StartOffset);
1245 auto It =
partition_point(Entries, [=](
const std::unique_ptr<FrameEntry> &E) {
1246 return E->getOffset() <
Offset;
1248 if (It != Entries.end() && (*It)->getOffset() ==
Offset)
1254 std::optional<uint64_t>
Offset)
const {
1255 DumpOpts.
IsEH = IsEH;
1257 if (
auto *Entry = getEntryAtOffset(*
Offset))
1258 Entry->dump(
OS, DumpOpts);
1263 for (
const auto &Entry : Entries)
1264 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