Value.h revision 321369
1//===-- Value.h -------------------------------------------------*- 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 liblldb_Value_h_
11#define liblldb_Value_h_
12
13#include "lldb/Core/Scalar.h"
14#include "lldb/Symbol/CompilerType.h"
15#include "lldb/Utility/DataBufferHeap.h"
16#include "lldb/Utility/Status.h"
17#include "lldb/lldb-enumerations.h"         // for ByteOrder, ByteOrder::eB...
18#include "lldb/lldb-private-enumerations.h" // for AddressType
19#include "lldb/lldb-private-types.h"        // for type128, RegisterInfo
20
21#include "llvm/ADT/APInt.h" // for APInt
22
23#include <vector>
24
25#include <stdint.h> // for uint8_t, uint32_t, uint64_t
26#include <string.h> // for size_t, memcpy
27
28namespace lldb_private {
29class DataExtractor;
30}
31namespace lldb_private {
32class ExecutionContext;
33}
34namespace lldb_private {
35class Module;
36}
37namespace lldb_private {
38class Stream;
39}
40namespace lldb_private {
41class Type;
42}
43namespace lldb_private {
44class Variable;
45}
46
47namespace lldb_private {
48
49class Value {
50public:
51  // Values Less than zero are an error, greater than or equal to zero
52  // returns what the Scalar result is.
53  enum ValueType {
54    // m_value contains...
55    // ============================
56    eValueTypeScalar,      // raw scalar value
57    eValueTypeVector,      // byte array of m_vector.length with endianness of
58                           // m_vector.byte_order
59    eValueTypeFileAddress, // file address value
60    eValueTypeLoadAddress, // load address value
61    eValueTypeHostAddress  // host address value (for memory in the process that
62                           // is using liblldb)
63  };
64
65  enum ContextType // Type that describes Value::m_context
66  {
67    // m_context contains...
68    // ====================
69    eContextTypeInvalid,      // undefined
70    eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector
71                              // register)
72    eContextTypeLLDBType,     // lldb_private::Type *
73    eContextTypeVariable      // lldb_private::Variable *
74  };
75
76  const static size_t kMaxByteSize = 32u;
77
78  struct Vector {
79    // The byte array must be big enough to hold vector registers for any
80    // supported target.
81    uint8_t bytes[kMaxByteSize];
82    size_t length;
83    lldb::ByteOrder byte_order;
84
85    Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {}
86
87    Vector(const Vector &vector) { *this = vector; }
88    const Vector &operator=(const Vector &vector) {
89      SetBytes(vector.bytes, vector.length, vector.byte_order);
90      return *this;
91    }
92
93    void Clear() { length = 0; }
94
95    bool SetBytes(const void *bytes, size_t length,
96                  lldb::ByteOrder byte_order) {
97      this->length = length;
98      this->byte_order = byte_order;
99      if (length)
100        ::memcpy(this->bytes, bytes,
101                 length < kMaxByteSize ? length : kMaxByteSize);
102      return IsValid();
103    }
104
105    bool IsValid() const {
106      return (length > 0 && length < kMaxByteSize &&
107              byte_order != lldb::eByteOrderInvalid);
108    }
109    // Casts a vector, if valid, to an unsigned int of matching or largest
110    // supported size.
111    // Truncates to the beginning of the vector if required.
112    // Returns a default constructed Scalar if the Vector data is internally
113    // inconsistent.
114    llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
115                                  ((type128 *)bytes)->x);
116    Scalar GetAsScalar() const {
117      Scalar scalar;
118      if (IsValid()) {
119        if (length == 1)
120          scalar = *(const uint8_t *)bytes;
121        else if (length == 2)
122          scalar = *(const uint16_t *)bytes;
123        else if (length == 4)
124          scalar = *(const uint32_t *)bytes;
125        else if (length == 8)
126          scalar = *(const uint64_t *)bytes;
127        else if (length >= 16)
128          scalar = rhs;
129      }
130      return scalar;
131    }
132  };
133
134  Value();
135  Value(const Scalar &scalar);
136  Value(const Vector &vector);
137  Value(const void *bytes, int len);
138  Value(const Value &rhs);
139
140  void SetBytes(const void *bytes, int len);
141
142  void AppendBytes(const void *bytes, int len);
143
144  Value &operator=(const Value &rhs);
145
146  const CompilerType &GetCompilerType();
147
148  void SetCompilerType(const CompilerType &compiler_type);
149
150  ValueType GetValueType() const;
151
152  AddressType GetValueAddressType() const;
153
154  ContextType GetContextType() const { return m_context_type; }
155
156  void SetValueType(ValueType value_type) { m_value_type = value_type; }
157
158  void ClearContext() {
159    m_context = nullptr;
160    m_context_type = eContextTypeInvalid;
161  }
162
163  void SetContext(ContextType context_type, void *p) {
164    m_context_type = context_type;
165    m_context = p;
166    if (m_context_type == eContextTypeRegisterInfo) {
167      RegisterInfo *reg_info = GetRegisterInfo();
168      if (reg_info->encoding == lldb::eEncodingVector &&
169          m_vector.byte_order != lldb::eByteOrderInvalid)
170        SetValueType(eValueTypeScalar);
171    }
172  }
173
174  RegisterInfo *GetRegisterInfo() const;
175
176  Type *GetType();
177
178  Scalar &ResolveValue(ExecutionContext *exe_ctx);
179
180  const Scalar &GetScalar() const { return m_value; }
181
182  const Vector &GetVector() const { return m_vector; }
183
184  Scalar &GetScalar() { return m_value; }
185
186  Vector &GetVector() { return m_vector; }
187
188  bool SetVectorBytes(const Vector &vector) {
189    m_vector = vector;
190    return m_vector.IsValid();
191  }
192
193  bool SetVectorBytes(uint8_t *bytes, size_t length,
194                      lldb::ByteOrder byte_order) {
195    return m_vector.SetBytes(bytes, length, byte_order);
196  }
197
198  bool SetScalarFromVector() {
199    if (m_vector.IsValid()) {
200      m_value = m_vector.GetAsScalar();
201      return true;
202    }
203    return false;
204  }
205
206  size_t ResizeData(size_t len);
207
208  size_t AppendDataToHostBuffer(const Value &rhs);
209
210  DataBufferHeap &GetBuffer() { return m_data_buffer; }
211
212  const DataBufferHeap &GetBuffer() const { return m_data_buffer; }
213
214  bool ValueOf(ExecutionContext *exe_ctx);
215
216  Variable *GetVariable();
217
218  void Dump(Stream *strm);
219
220  lldb::Format GetValueDefaultFormat();
221
222  uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx);
223
224  Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
225                        uint32_t data_offset,
226                        Module *module); // Can be nullptr
227
228  static const char *GetValueTypeAsCString(ValueType context_type);
229
230  static const char *GetContextTypeAsCString(ContextType context_type);
231
232  bool GetData(DataExtractor &data);
233
234  void Clear();
235
236protected:
237  Scalar m_value;
238  Vector m_vector;
239  CompilerType m_compiler_type;
240  void *m_context;
241  ValueType m_value_type;
242  ContextType m_context_type;
243  DataBufferHeap m_data_buffer;
244};
245
246class ValueList {
247public:
248  ValueList() : m_values() {}
249
250  ValueList(const ValueList &rhs);
251
252  ~ValueList() = default;
253
254  const ValueList &operator=(const ValueList &rhs);
255
256  // void InsertValue (Value *value, size_t idx);
257  void PushValue(const Value &value);
258
259  size_t GetSize();
260  Value *GetValueAtIndex(size_t idx);
261  void Clear();
262
263private:
264  typedef std::vector<Value> collection;
265
266  collection m_values;
267};
268
269} // namespace lldb_private
270
271#endif // liblldb_Value_h_
272