File indexing completed on 2026-05-10 08:43:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
0010 #define LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
0011
0012 #include "llvm/ADT/StringRef.h"
0013 #include "llvm/ADT/iterator.h"
0014 #include "llvm/BinaryFormat/Dwarf.h"
0015 #include "llvm/Support/DataExtractor.h"
0016
0017 namespace llvm {
0018 class DWARFUnit;
0019 struct DIDumpOptions;
0020 class MCRegisterInfo;
0021 class raw_ostream;
0022
0023 class DWARFExpression {
0024 public:
0025 class iterator;
0026
0027
0028
0029
0030
0031
0032 class Operation {
0033 public:
0034
0035 enum Encoding : uint8_t {
0036 Size1 = 0,
0037 Size2 = 1,
0038 Size4 = 2,
0039 Size8 = 3,
0040 SizeLEB = 4,
0041 SizeAddr = 5,
0042 SizeRefAddr = 6,
0043 SizeBlock = 7,
0044 BaseTypeRef = 8,
0045
0046
0047 SizeSubOpLEB = 9,
0048 WasmLocationArg = 30,
0049 SignBit = 0x80,
0050 SignedSize1 = SignBit | Size1,
0051 SignedSize2 = SignBit | Size2,
0052 SignedSize4 = SignBit | Size4,
0053 SignedSize8 = SignBit | Size8,
0054 SignedSizeLEB = SignBit | SizeLEB,
0055 };
0056
0057 enum DwarfVersion : uint8_t {
0058 DwarfNA,
0059 Dwarf2 = 2,
0060 Dwarf3,
0061 Dwarf4,
0062 Dwarf5
0063 };
0064
0065
0066 struct Description {
0067 DwarfVersion Version;
0068 SmallVector<Encoding> Op;
0069
0070 template <typename... Ts>
0071 Description(DwarfVersion Version, Ts... Op)
0072 : Version(Version), Op{Op...} {}
0073 Description() : Description(DwarfNA) {}
0074 ~Description() = default;
0075 };
0076
0077 private:
0078 friend class DWARFExpression::iterator;
0079 uint8_t Opcode;
0080 Description Desc;
0081 bool Error = false;
0082 uint64_t EndOffset;
0083 SmallVector<uint64_t> Operands;
0084 SmallVector<uint64_t> OperandEndOffsets;
0085
0086 public:
0087 const Description &getDescription() const { return Desc; }
0088 uint8_t getCode() const { return Opcode; }
0089 std::optional<unsigned> getSubCode() const;
0090 uint64_t getNumOperands() const { return Operands.size(); }
0091 ArrayRef<uint64_t> getRawOperands() const { return Operands; };
0092 uint64_t getRawOperand(unsigned Idx) const { return Operands[Idx]; }
0093 ArrayRef<uint64_t> getOperandEndOffsets() const {
0094 return OperandEndOffsets;
0095 }
0096 uint64_t getOperandEndOffset(unsigned Idx) const {
0097 return OperandEndOffsets[Idx];
0098 }
0099 uint64_t getEndOffset() const { return EndOffset; }
0100 bool isError() const { return Error; }
0101 bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
0102 const DWARFExpression *Expr, DWARFUnit *U) const;
0103
0104
0105 static bool verify(const Operation &Op, DWARFUnit *U);
0106
0107 private:
0108 bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
0109 std::optional<dwarf::DwarfFormat> Format);
0110 };
0111
0112
0113 class iterator
0114 : public iterator_facade_base<iterator, std::forward_iterator_tag,
0115 const Operation> {
0116 friend class DWARFExpression;
0117 const DWARFExpression *Expr;
0118 uint64_t Offset;
0119 Operation Op;
0120 iterator(const DWARFExpression *Expr, uint64_t Offset)
0121 : Expr(Expr), Offset(Offset) {
0122 Op.Error =
0123 Offset >= Expr->Data.getData().size() ||
0124 !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
0125 }
0126
0127 public:
0128 iterator &operator++() {
0129 Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
0130 Op.Error =
0131 Offset >= Expr->Data.getData().size() ||
0132 !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
0133 return *this;
0134 }
0135
0136 const Operation &operator*() const { return Op; }
0137
0138 iterator skipBytes(uint64_t Add) const {
0139 return iterator(Expr, Op.EndOffset + Add);
0140 }
0141
0142
0143 friend bool operator==(const iterator &, const iterator &);
0144 };
0145
0146 DWARFExpression(DataExtractor Data, uint8_t AddressSize,
0147 std::optional<dwarf::DwarfFormat> Format = std::nullopt)
0148 : Data(Data), AddressSize(AddressSize), Format(Format) {
0149 assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2);
0150 }
0151
0152 iterator begin() const { return iterator(this, 0); }
0153 iterator end() const { return iterator(this, Data.getData().size()); }
0154
0155 void print(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U,
0156 bool IsEH = false) const;
0157
0158
0159
0160
0161
0162 bool printCompact(raw_ostream &OS,
0163 std::function<StringRef(uint64_t RegNum, bool IsEH)>
0164 GetNameForDWARFReg = nullptr);
0165
0166 bool verify(DWARFUnit *U);
0167
0168 bool operator==(const DWARFExpression &RHS) const;
0169
0170 StringRef getData() const { return Data.getData(); }
0171
0172 static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
0173 DIDumpOptions DumpOpts, uint8_t Opcode,
0174 const ArrayRef<uint64_t> Operands);
0175
0176 private:
0177 DataExtractor Data;
0178 uint8_t AddressSize;
0179 std::optional<dwarf::DwarfFormat> Format;
0180 };
0181
0182 inline bool operator==(const DWARFExpression::iterator &LHS,
0183 const DWARFExpression::iterator &RHS) {
0184 return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
0185 }
0186 }
0187 #endif