blob: 3fad68a9b48b930675505448bf243f2cb817a6b0 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===--- 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
18namespace llvm {
19class DWARFUnit;
20class MCRegisterInfo;
21class raw_ostream;
22
23class DWARFExpression {
24public:
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,
97 Operation> {
98 friend class DWARFExpression;
99 const DWARFExpression *Expr;
100 uint32_t Offset;
101 Operation Op;
102 iterator(const DWARFExpression *Expr, uint32_t Offset)
103 : Expr(Expr), Offset(Offset) {
104 Op.Error =
105 Offset >= Expr->Data.getData().size() ||
106 !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
107 }
108
109 public:
110 class Operation &operator++() {
111 Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
112 Op.Error =
113 Offset >= Expr->Data.getData().size() ||
114 !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
115 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 : Data(Data), Version(Version), AddressSize(AddressSize) {
128 assert(AddressSize == 8 || AddressSize == 4);
129 }
130
131 iterator begin() const { return iterator(this, 0); }
132 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
137private:
138 DataExtractor Data;
139 uint16_t Version;
140 uint8_t AddressSize;
141};
142
143inline bool operator==(const DWARFExpression::iterator &LHS,
144 const DWARFExpression::iterator &RHS) {
145 return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
146}
147
148inline bool operator!=(const DWARFExpression::iterator &LHS,
149 const DWARFExpression::iterator &RHS) {
150 return !(LHS == RHS);
151}
152}
153#endif