• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
VersionDescription68           : 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:
getDescription()83     Description &getDescription() { return Desc; }
getCode()84     uint8_t getCode() { return Opcode; }
getRawOperand(unsigned Idx)85     uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
getEndOffset()86     uint32_t getEndOffset() { return EndOffset; }
87     bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
88                  uint32_t Offset);
isError()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;
iterator(const DWARFExpression * Expr,uint32_t Offset)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 
DWARFExpression(DataExtractor Data,uint16_t Version,uint8_t AddressSize)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 
begin()131   iterator begin() const { return iterator(this, 0); }
end()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 
137 private:
138   DataExtractor Data;
139   uint16_t Version;
140   uint8_t AddressSize;
141 };
142 
143 inline bool operator==(const DWARFExpression::iterator &LHS,
144                        const DWARFExpression::iterator &RHS) {
145   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   return !(LHS == RHS);
151 }
152 }
153 #endif
154