1 //===--- DWARFExpression.h - DWARF Expression handling ----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_DWARFEXPRESSION_H 11 #define LLVM_DEBUGINFO_DWARFEXPRESSION_H 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/iterator.h" 15 #include "llvm/ADT/iterator_range.h" 16 #include "llvm/Support/DataExtractor.h" 17 18 namespace llvm { 19 class DWARFUnit; 20 class MCRegisterInfo; 21 class raw_ostream; 22 23 class DWARFExpression { 24 public: 25 class iterator; 26 27 /// This class represents an Operation in the Expression. Each operation can 28 /// have up to 2 oprerands. 29 /// 30 /// An Operation can be in Error state (check with isError()). This 31 /// means that it couldn't be decoded successfully and if it is the 32 /// case, all others fields contain undefined values. 33 class Operation { 34 public: 35 /// Size and signedness of expression operations' operands. 36 enum Encoding : uint8_t { 37 Size1 = 0, 38 Size2 = 1, 39 Size4 = 2, 40 Size8 = 3, 41 SizeLEB = 4, 42 SizeAddr = 5, 43 SizeRefAddr = 6, 44 SizeBlock = 7, ///< Preceding operand contains block size 45 SignBit = 0x8, 46 SignedSize1 = SignBit | Size1, 47 SignedSize2 = SignBit | Size2, 48 SignedSize4 = SignBit | Size4, 49 SignedSize8 = SignBit | Size8, 50 SignedSizeLEB = SignBit | SizeLEB, 51 SizeNA = 0xFF ///< Unused operands get this encoding. 52 }; 53 54 enum DwarfVersion : uint8_t { 55 DwarfNA, ///< Serves as a marker for unused entries 56 Dwarf2 = 2, 57 Dwarf3, 58 Dwarf4 59 }; 60 61 /// Description of the encoding of one expression Op. 62 struct Description { 63 DwarfVersion Version; ///< Dwarf version where the Op was introduced. 64 Encoding Op[2]; ///< Encoding for Op operands, or SizeNA. 65 66 Description(DwarfVersion Version = DwarfNA, Encoding Op1 = SizeNA, 67 Encoding Op2 = SizeNA) 68 : Version(Version) { 69 Op[0] = Op1; 70 Op[1] = Op2; 71 } 72 }; 73 74 private: 75 friend class DWARFExpression::iterator; 76 uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>. 77 Description Desc; 78 bool Error; 79 uint32_t EndOffset; 80 uint64_t Operands[2]; 81 82 public: 83 Description &getDescription() { return Desc; } 84 uint8_t getCode() { return Opcode; } 85 uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; } 86 uint32_t getEndOffset() { return EndOffset; } 87 bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize, 88 uint32_t Offset); 89 bool isError() { return Error; } 90 bool print(raw_ostream &OS, const DWARFExpression *U, 91 const MCRegisterInfo *RegInfo, bool isEH); 92 }; 93 94 /// An iterator to go through the expression operations. 95 class iterator 96 : public iterator_facade_base<iterator, std::forward_iterator_tag, Operation> { 97 friend class DWARFExpression; 98 DWARFExpression *Expr; 99 uint32_t Offset; 100 Operation Op; 101 iterator(DWARFExpression *Expr, uint32_t Offset) 102 : Expr(Expr), Offset(Offset) { 103 Op.Error = 104 Offset >= Expr->Data.getData().size() || 105 !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset); 106 } 107 108 public: 109 class Operation &operator++() { 110 Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset; 111 Op.Error = 112 Offset >= Expr->Data.getData().size() || 113 !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset); 114 return Op; 115 } 116 117 class Operation &operator*() { 118 return Op; 119 } 120 121 // Comparison operators are provided out of line. 122 friend bool operator==(const iterator &, const iterator &); 123 }; 124 125 DWARFExpression(DataExtractor Data, uint16_t Version, uint8_t AddressSize) 126 : Data(Data), Version(Version), AddressSize(AddressSize) { 127 assert(AddressSize == 8 || AddressSize == 4); 128 } 129 130 iterator begin() { return iterator(this, 0); } 131 iterator end() { return iterator(this, Data.getData().size()); } 132 133 void print(raw_ostream &OS, const MCRegisterInfo *RegInfo); 134 135 private: 136 DataExtractor Data; 137 uint16_t Version; 138 uint8_t AddressSize; 139 }; 140 141 inline bool operator==(const DWARFExpression::iterator &LHS, 142 const DWARFExpression::iterator &RHS) { 143 return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset; 144 } 145 146 inline bool operator!=(const DWARFExpression::iterator &LHS, 147 const DWARFExpression::iterator &RHS) { 148 return !(LHS == RHS); 149 } 150 } 151 #endif 152