Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===--- DWARFExpression.h - DWARF Expression handling ----------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
10
#define LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
11
 
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/ADT/iterator.h"
14
#include "llvm/BinaryFormat/Dwarf.h"
15
#include "llvm/Support/DataExtractor.h"
16
 
17
namespace llvm {
18
class DWARFUnit;
19
struct DIDumpOptions;
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
      BaseTypeRef = 8,
46
      WasmLocationArg = 30,
47
      SignBit = 0x80,
48
      SignedSize1 = SignBit | Size1,
49
      SignedSize2 = SignBit | Size2,
50
      SignedSize4 = SignBit | Size4,
51
      SignedSize8 = SignBit | Size8,
52
      SignedSizeLEB = SignBit | SizeLEB,
53
      SizeNA = 0xFF ///< Unused operands get this encoding.
54
    };
55
 
56
    enum DwarfVersion : uint8_t {
57
      DwarfNA, ///< Serves as a marker for unused entries
58
      Dwarf2 = 2,
59
      Dwarf3,
60
      Dwarf4,
61
      Dwarf5
62
    };
63
 
64
    /// Description of the encoding of one expression Op.
65
    struct Description {
66
      DwarfVersion Version; ///< Dwarf version where the Op was introduced.
67
      Encoding Op[2];       ///< Encoding for Op operands, or SizeNA.
68
 
69
      Description(DwarfVersion Version = DwarfNA, Encoding Op1 = SizeNA,
70
                  Encoding Op2 = SizeNA)
71
          : Version(Version) {
72
        Op[0] = Op1;
73
        Op[1] = Op2;
74
      }
75
    };
76
 
77
  private:
78
    friend class DWARFExpression::iterator;
79
    uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
80
    Description Desc;
81
    bool Error = false;
82
    uint64_t EndOffset;
83
    uint64_t Operands[2];
84
    uint64_t OperandEndOffsets[2];
85
 
86
  public:
87
    const Description &getDescription() const { return Desc; }
88
    uint8_t getCode() const { return Opcode; }
89
    uint64_t getRawOperand(unsigned Idx) const { return Operands[Idx]; }
90
    uint64_t getOperandEndOffset(unsigned Idx) const {
91
      return OperandEndOffsets[Idx];
92
    }
93
    uint64_t getEndOffset() const { return EndOffset; }
94
    bool isError() const { return Error; }
95
    bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
96
               const DWARFExpression *Expr, DWARFUnit *U) const;
97
 
98
    /// Verify \p Op. Does not affect the return of \a isError().
99
    static bool verify(const Operation &Op, DWARFUnit *U);
100
 
101
  private:
102
    bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
103
                 std::optional<dwarf::DwarfFormat> Format);
104
  };
105
 
106
  /// An iterator to go through the expression operations.
107
  class iterator
108
      : public iterator_facade_base<iterator, std::forward_iterator_tag,
109
                                    const Operation> {
110
    friend class DWARFExpression;
111
    const DWARFExpression *Expr;
112
    uint64_t Offset;
113
    Operation Op;
114
    iterator(const DWARFExpression *Expr, uint64_t Offset)
115
        : Expr(Expr), Offset(Offset) {
116
      Op.Error =
117
          Offset >= Expr->Data.getData().size() ||
118
          !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
119
    }
120
 
121
  public:
122
    iterator &operator++() {
123
      Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
124
      Op.Error =
125
          Offset >= Expr->Data.getData().size() ||
126
          !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
127
      return *this;
128
    }
129
 
130
    const Operation &operator*() const { return Op; }
131
 
132
    iterator skipBytes(uint64_t Add) const {
133
      return iterator(Expr, Op.EndOffset + Add);
134
    }
135
 
136
    // Comparison operators are provided out of line.
137
    friend bool operator==(const iterator &, const iterator &);
138
  };
139
 
140
  DWARFExpression(DataExtractor Data, uint8_t AddressSize,
141
                  std::optional<dwarf::DwarfFormat> Format = std::nullopt)
142
      : Data(Data), AddressSize(AddressSize), Format(Format) {
143
    assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2);
144
  }
145
 
146
  iterator begin() const { return iterator(this, 0); }
147
  iterator end() const { return iterator(this, Data.getData().size()); }
148
 
149
  void print(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U,
150
             bool IsEH = false) const;
151
 
152
  /// Print the expression in a format intended to be compact and useful to a
153
  /// user, but not perfectly unambiguous, or capable of representing every
154
  /// valid DWARF expression. Returns true if the expression was sucessfully
155
  /// printed.
156
  bool printCompact(raw_ostream &OS,
157
                    std::function<StringRef(uint64_t RegNum, bool IsEH)>
158
                        GetNameForDWARFReg = nullptr);
159
 
160
  bool verify(DWARFUnit *U);
161
 
162
  bool operator==(const DWARFExpression &RHS) const;
163
 
164
  StringRef getData() const { return Data.getData(); }
165
 
166
  static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
167
                                    DIDumpOptions DumpOpts, uint8_t Opcode,
168
                                    const uint64_t Operands[2]);
169
 
170
private:
171
  DataExtractor Data;
172
  uint8_t AddressSize;
173
  std::optional<dwarf::DwarfFormat> Format;
174
};
175
 
176
inline bool operator==(const DWARFExpression::iterator &LHS,
177
                       const DWARFExpression::iterator &RHS) {
178
  return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
179
}
180
}
181
#endif