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/Symbol/CompilerType.h"
14 #include "lldb/Utility/DataBufferHeap.h"
15 #include "lldb/Utility/Scalar.h"
16 #include "lldb/Utility/Status.h"
17 #include "lldb/lldb-enumerations.h"
18 #include "lldb/lldb-private-enumerations.h"
19 #include "lldb/lldb-private-types.h"
20 
21 #include "llvm/ADT/APInt.h"
22 
23 #include <vector>
24 
25 #include <stdint.h>
26 #include <string.h>
27 
28 namespace lldb_private {
29 class DataExtractor;
30 }
31 namespace lldb_private {
32 class ExecutionContext;
33 }
34 namespace lldb_private {
35 class Module;
36 }
37 namespace lldb_private {
38 class Stream;
39 }
40 namespace lldb_private {
41 class Type;
42 }
43 namespace lldb_private {
44 class Variable;
45 }
46 
47 namespace lldb_private {
48 
49 class Value {
50 public:
51   // Values Less than zero are an error, greater than or equal to zero returns
52   // 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 
VectorVector85     Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {}
86 
VectorVector87     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 
ClearVector93     void Clear() { length = 0; }
94 
SetBytesVector95     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 
IsValidVector105     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. Truncates to the beginning of the vector if required.
111     // Returns a default constructed Scalar if the Vector data is internally
112     // inconsistent.
113     llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
114                                   ((type128 *)bytes)->x);
GetAsScalarVector115     Scalar GetAsScalar() const {
116       Scalar scalar;
117       if (IsValid()) {
118         if (length == 1)
119           scalar = *(const uint8_t *)bytes;
120         else if (length == 2)
121           scalar = *(const uint16_t *)bytes;
122         else if (length == 4)
123           scalar = *(const uint32_t *)bytes;
124         else if (length == 8)
125           scalar = *(const uint64_t *)bytes;
126         else if (length >= 16)
127           scalar = rhs;
128       }
129       return scalar;
130     }
131   };
132 
133   Value();
134   Value(const Scalar &scalar);
135   Value(const Vector &vector);
136   Value(const void *bytes, int len);
137   Value(const Value &rhs);
138 
139   void SetBytes(const void *bytes, int len);
140 
141   void AppendBytes(const void *bytes, int len);
142 
143   Value &operator=(const Value &rhs);
144 
145   const CompilerType &GetCompilerType();
146 
147   void SetCompilerType(const CompilerType &compiler_type);
148 
149   ValueType GetValueType() const;
150 
151   AddressType GetValueAddressType() const;
152 
GetContextType()153   ContextType GetContextType() const { return m_context_type; }
154 
SetValueType(ValueType value_type)155   void SetValueType(ValueType value_type) { m_value_type = value_type; }
156 
ClearContext()157   void ClearContext() {
158     m_context = nullptr;
159     m_context_type = eContextTypeInvalid;
160   }
161 
SetContext(ContextType context_type,void * p)162   void SetContext(ContextType context_type, void *p) {
163     m_context_type = context_type;
164     m_context = p;
165     if (m_context_type == eContextTypeRegisterInfo) {
166       RegisterInfo *reg_info = GetRegisterInfo();
167       if (reg_info->encoding == lldb::eEncodingVector &&
168           m_vector.byte_order != lldb::eByteOrderInvalid)
169         SetValueType(eValueTypeScalar);
170     }
171   }
172 
173   RegisterInfo *GetRegisterInfo() const;
174 
175   Type *GetType();
176 
177   Scalar &ResolveValue(ExecutionContext *exe_ctx);
178 
GetScalar()179   const Scalar &GetScalar() const { return m_value; }
180 
GetVector()181   const Vector &GetVector() const { return m_vector; }
182 
GetScalar()183   Scalar &GetScalar() { return m_value; }
184 
GetVector()185   Vector &GetVector() { return m_vector; }
186 
SetVectorBytes(const Vector & vector)187   bool SetVectorBytes(const Vector &vector) {
188     m_vector = vector;
189     return m_vector.IsValid();
190   }
191 
SetVectorBytes(uint8_t * bytes,size_t length,lldb::ByteOrder byte_order)192   bool SetVectorBytes(uint8_t *bytes, size_t length,
193                       lldb::ByteOrder byte_order) {
194     return m_vector.SetBytes(bytes, length, byte_order);
195   }
196 
SetScalarFromVector()197   bool SetScalarFromVector() {
198     if (m_vector.IsValid()) {
199       m_value = m_vector.GetAsScalar();
200       return true;
201     }
202     return false;
203   }
204 
205   size_t ResizeData(size_t len);
206 
207   size_t AppendDataToHostBuffer(const Value &rhs);
208 
GetBuffer()209   DataBufferHeap &GetBuffer() { return m_data_buffer; }
210 
GetBuffer()211   const DataBufferHeap &GetBuffer() const { return m_data_buffer; }
212 
213   bool ValueOf(ExecutionContext *exe_ctx);
214 
215   Variable *GetVariable();
216 
217   void Dump(Stream *strm);
218 
219   lldb::Format GetValueDefaultFormat();
220 
221   uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx);
222 
223   Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
224                         uint32_t data_offset,
225                         Module *module); // Can be nullptr
226 
227   static const char *GetValueTypeAsCString(ValueType context_type);
228 
229   static const char *GetContextTypeAsCString(ContextType context_type);
230 
231   /// Convert this value's file address to a load address, if possible.
232   void ConvertToLoadAddress(Module *module, Target *target);
233 
234   bool GetData(DataExtractor &data);
235 
236   void Clear();
237 
238 protected:
239   Scalar m_value;
240   Vector m_vector;
241   CompilerType m_compiler_type;
242   void *m_context;
243   ValueType m_value_type;
244   ContextType m_context_type;
245   DataBufferHeap m_data_buffer;
246 };
247 
248 class ValueList {
249 public:
ValueList()250   ValueList() : m_values() {}
251 
252   ValueList(const ValueList &rhs);
253 
254   ~ValueList() = default;
255 
256   const ValueList &operator=(const ValueList &rhs);
257 
258   // void InsertValue (Value *value, size_t idx);
259   void PushValue(const Value &value);
260 
261   size_t GetSize();
262   Value *GetValueAtIndex(size_t idx);
263   void Clear();
264 
265 private:
266   typedef std::vector<Value> collection;
267 
268   collection m_values;
269 };
270 
271 } // namespace lldb_private
272 
273 #endif // liblldb_Value_h_
274