Line data Source code
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 127930 : : Version(Version) {
69 127930 : Op[0] = Op1;
70 123268 : 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 0 : uint8_t getCode() { return Opcode; }
85 : uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
86 0 : uint32_t getEndOffset() { return EndOffset; }
87 : bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
88 : uint32_t Offset);
89 0 : 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,
97 : Operation> {
98 : friend class DWARFExpression;
99 : const DWARFExpression *Expr;
100 : uint32_t Offset;
101 : Operation Op;
102 5530 : iterator(const DWARFExpression *Expr, uint32_t Offset)
103 5530 : : Expr(Expr), Offset(Offset) {
104 5530 : Op.Error =
105 8294 : Offset >= Expr->Data.getData().size() ||
106 2764 : !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
107 5530 : }
108 :
109 : public:
110 2931 : class Operation &operator++() {
111 2931 : Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
112 2931 : Op.Error =
113 3383 : Offset >= Expr->Data.getData().size() ||
114 452 : !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
115 2931 : return Op;
116 : }
117 :
118 : class Operation &operator*() {
119 : return Op;
120 : }
121 :
122 : // Comparison operators are provided out of line.
123 : friend bool operator==(const iterator &, const iterator &);
124 : };
125 :
126 : DWARFExpression(DataExtractor Data, uint16_t Version, uint8_t AddressSize)
127 2331 : : Data(Data), Version(Version), AddressSize(AddressSize) {
128 : assert(AddressSize == 8 || AddressSize == 4);
129 : }
130 :
131 2331 : iterator begin() const { return iterator(this, 0); }
132 2331 : iterator end() const { return iterator(this, Data.getData().size()); }
133 :
134 : void print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
135 : bool IsEH = false) const;
136 :
137 : private:
138 : DataExtractor Data;
139 : uint16_t Version;
140 : uint8_t AddressSize;
141 : };
142 :
143 0 : inline bool operator==(const DWARFExpression::iterator &LHS,
144 : const DWARFExpression::iterator &RHS) {
145 5095 : return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
146 : }
147 :
148 : inline bool operator!=(const DWARFExpression::iterator &LHS,
149 : const DWARFExpression::iterator &RHS) {
150 5095 : return !(LHS == RHS);
151 : }
152 : }
153 : #endif
|