1254721Semaste//===-- Value.h -------------------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#ifndef liblldb_Value_h_
10254721Semaste#define liblldb_Value_h_
11254721Semaste
12296417Sdim#include "lldb/Symbol/CompilerType.h"
13321369Sdim#include "lldb/Utility/DataBufferHeap.h"
14344779Sdim#include "lldb/Utility/Scalar.h"
15321369Sdim#include "lldb/Utility/Status.h"
16344779Sdim#include "lldb/lldb-enumerations.h"
17344779Sdim#include "lldb/lldb-private-enumerations.h"
18344779Sdim#include "lldb/lldb-private-types.h"
19254721Semaste
20344779Sdim#include "llvm/ADT/APInt.h"
21321369Sdim
22321369Sdim#include <vector>
23321369Sdim
24344779Sdim#include <stdint.h>
25344779Sdim#include <string.h>
26321369Sdim
27254721Semastenamespace lldb_private {
28321369Sdimclass DataExtractor;
29321369Sdimclass ExecutionContext;
30321369Sdimclass Module;
31321369Sdimclass Stream;
32321369Sdimclass Type;
33321369Sdimclass Variable;
34321369Sdim}
35254721Semaste
36321369Sdimnamespace lldb_private {
37321369Sdim
38314564Sdimclass Value {
39254721Semastepublic:
40341825Sdim  // Values Less than zero are an error, greater than or equal to zero returns
41341825Sdim  // what the Scalar result is.
42314564Sdim  enum ValueType {
43314564Sdim    // m_value contains...
44314564Sdim    // ============================
45314564Sdim    eValueTypeScalar,      // raw scalar value
46314564Sdim    eValueTypeVector,      // byte array of m_vector.length with endianness of
47314564Sdim                           // m_vector.byte_order
48314564Sdim    eValueTypeFileAddress, // file address value
49314564Sdim    eValueTypeLoadAddress, // load address value
50314564Sdim    eValueTypeHostAddress  // host address value (for memory in the process that
51314564Sdim                           // is using liblldb)
52314564Sdim  };
53254721Semaste
54314564Sdim  enum ContextType // Type that describes Value::m_context
55314564Sdim  {
56314564Sdim    // m_context contains...
57314564Sdim    // ====================
58314564Sdim    eContextTypeInvalid,      // undefined
59314564Sdim    eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector
60314564Sdim                              // register)
61314564Sdim    eContextTypeLLDBType,     // lldb_private::Type *
62314564Sdim    eContextTypeVariable      // lldb_private::Variable *
63314564Sdim  };
64254721Semaste
65314564Sdim  const static size_t kMaxByteSize = 32u;
66254721Semaste
67314564Sdim  struct Vector {
68314564Sdim    // The byte array must be big enough to hold vector registers for any
69314564Sdim    // supported target.
70314564Sdim    uint8_t bytes[kMaxByteSize];
71314564Sdim    size_t length;
72314564Sdim    lldb::ByteOrder byte_order;
73254721Semaste
74314564Sdim    Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {}
75254721Semaste
76314564Sdim    Vector(const Vector &vector) { *this = vector; }
77314564Sdim    const Vector &operator=(const Vector &vector) {
78314564Sdim      SetBytes(vector.bytes, vector.length, vector.byte_order);
79314564Sdim      return *this;
80314564Sdim    }
81254721Semaste
82314564Sdim    void Clear() { length = 0; }
83254721Semaste
84314564Sdim    bool SetBytes(const void *bytes, size_t length,
85314564Sdim                  lldb::ByteOrder byte_order) {
86314564Sdim      this->length = length;
87314564Sdim      this->byte_order = byte_order;
88314564Sdim      if (length)
89314564Sdim        ::memcpy(this->bytes, bytes,
90314564Sdim                 length < kMaxByteSize ? length : kMaxByteSize);
91314564Sdim      return IsValid();
92314564Sdim    }
93254721Semaste
94314564Sdim    bool IsValid() const {
95314564Sdim      return (length > 0 && length < kMaxByteSize &&
96314564Sdim              byte_order != lldb::eByteOrderInvalid);
97314564Sdim    }
98314564Sdim    // Casts a vector, if valid, to an unsigned int of matching or largest
99341825Sdim    // supported size. Truncates to the beginning of the vector if required.
100314564Sdim    // Returns a default constructed Scalar if the Vector data is internally
101314564Sdim    // inconsistent.
102314564Sdim    llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
103314564Sdim                                  ((type128 *)bytes)->x);
104314564Sdim    Scalar GetAsScalar() const {
105314564Sdim      Scalar scalar;
106314564Sdim      if (IsValid()) {
107314564Sdim        if (length == 1)
108314564Sdim          scalar = *(const uint8_t *)bytes;
109314564Sdim        else if (length == 2)
110314564Sdim          scalar = *(const uint16_t *)bytes;
111314564Sdim        else if (length == 4)
112314564Sdim          scalar = *(const uint32_t *)bytes;
113314564Sdim        else if (length == 8)
114314564Sdim          scalar = *(const uint64_t *)bytes;
115314564Sdim        else if (length >= 16)
116314564Sdim          scalar = rhs;
117314564Sdim      }
118314564Sdim      return scalar;
119314564Sdim    }
120314564Sdim  };
121254721Semaste
122314564Sdim  Value();
123314564Sdim  Value(const Scalar &scalar);
124314564Sdim  Value(const Vector &vector);
125314564Sdim  Value(const void *bytes, int len);
126314564Sdim  Value(const Value &rhs);
127276479Sdim
128314564Sdim  void SetBytes(const void *bytes, int len);
129254721Semaste
130314564Sdim  void AppendBytes(const void *bytes, int len);
131254721Semaste
132314564Sdim  Value &operator=(const Value &rhs);
133254721Semaste
134314564Sdim  const CompilerType &GetCompilerType();
135254721Semaste
136314564Sdim  void SetCompilerType(const CompilerType &compiler_type);
137254721Semaste
138314564Sdim  ValueType GetValueType() const;
139254721Semaste
140314564Sdim  AddressType GetValueAddressType() const;
141254721Semaste
142314564Sdim  ContextType GetContextType() const { return m_context_type; }
143314564Sdim
144314564Sdim  void SetValueType(ValueType value_type) { m_value_type = value_type; }
145314564Sdim
146314564Sdim  void ClearContext() {
147314564Sdim    m_context = nullptr;
148314564Sdim    m_context_type = eContextTypeInvalid;
149314564Sdim  }
150314564Sdim
151314564Sdim  void SetContext(ContextType context_type, void *p) {
152314564Sdim    m_context_type = context_type;
153314564Sdim    m_context = p;
154314564Sdim    if (m_context_type == eContextTypeRegisterInfo) {
155314564Sdim      RegisterInfo *reg_info = GetRegisterInfo();
156314564Sdim      if (reg_info->encoding == lldb::eEncodingVector &&
157314564Sdim          m_vector.byte_order != lldb::eByteOrderInvalid)
158314564Sdim        SetValueType(eValueTypeScalar);
159254721Semaste    }
160314564Sdim  }
161254721Semaste
162314564Sdim  RegisterInfo *GetRegisterInfo() const;
163254721Semaste
164314564Sdim  Type *GetType();
165254721Semaste
166314564Sdim  Scalar &ResolveValue(ExecutionContext *exe_ctx);
167254721Semaste
168314564Sdim  const Scalar &GetScalar() const { return m_value; }
169254721Semaste
170314564Sdim  const Vector &GetVector() const { return m_vector; }
171254721Semaste
172314564Sdim  Scalar &GetScalar() { return m_value; }
173254721Semaste
174314564Sdim  Vector &GetVector() { return m_vector; }
175254721Semaste
176314564Sdim  bool SetVectorBytes(const Vector &vector) {
177314564Sdim    m_vector = vector;
178314564Sdim    return m_vector.IsValid();
179314564Sdim  }
180276479Sdim
181314564Sdim  bool SetVectorBytes(uint8_t *bytes, size_t length,
182314564Sdim                      lldb::ByteOrder byte_order) {
183314564Sdim    return m_vector.SetBytes(bytes, length, byte_order);
184314564Sdim  }
185314564Sdim
186314564Sdim  bool SetScalarFromVector() {
187314564Sdim    if (m_vector.IsValid()) {
188314564Sdim      m_value = m_vector.GetAsScalar();
189314564Sdim      return true;
190276479Sdim    }
191314564Sdim    return false;
192314564Sdim  }
193276479Sdim
194314564Sdim  size_t ResizeData(size_t len);
195254721Semaste
196314564Sdim  size_t AppendDataToHostBuffer(const Value &rhs);
197254721Semaste
198314564Sdim  DataBufferHeap &GetBuffer() { return m_data_buffer; }
199254721Semaste
200314564Sdim  const DataBufferHeap &GetBuffer() const { return m_data_buffer; }
201254721Semaste
202314564Sdim  bool ValueOf(ExecutionContext *exe_ctx);
203254721Semaste
204314564Sdim  Variable *GetVariable();
205254721Semaste
206314564Sdim  void Dump(Stream *strm);
207254721Semaste
208314564Sdim  lldb::Format GetValueDefaultFormat();
209254721Semaste
210321369Sdim  uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx);
211254721Semaste
212321369Sdim  Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
213321369Sdim                        Module *module); // Can be nullptr
214254721Semaste
215314564Sdim  static const char *GetValueTypeAsCString(ValueType context_type);
216314564Sdim
217314564Sdim  static const char *GetContextTypeAsCString(ContextType context_type);
218314564Sdim
219341825Sdim  /// Convert this value's file address to a load address, if possible.
220341825Sdim  void ConvertToLoadAddress(Module *module, Target *target);
221341825Sdim
222314564Sdim  bool GetData(DataExtractor &data);
223314564Sdim
224314564Sdim  void Clear();
225314564Sdim
226254721Semasteprotected:
227314564Sdim  Scalar m_value;
228314564Sdim  Vector m_vector;
229314564Sdim  CompilerType m_compiler_type;
230314564Sdim  void *m_context;
231314564Sdim  ValueType m_value_type;
232314564Sdim  ContextType m_context_type;
233314564Sdim  DataBufferHeap m_data_buffer;
234254721Semaste};
235254721Semaste
236314564Sdimclass ValueList {
237254721Semastepublic:
238314564Sdim  ValueList() : m_values() {}
239254721Semaste
240314564Sdim  ValueList(const ValueList &rhs);
241254721Semaste
242314564Sdim  ~ValueList() = default;
243254721Semaste
244314564Sdim  const ValueList &operator=(const ValueList &rhs);
245254721Semaste
246314564Sdim  // void InsertValue (Value *value, size_t idx);
247314564Sdim  void PushValue(const Value &value);
248254721Semaste
249314564Sdim  size_t GetSize();
250314564Sdim  Value *GetValueAtIndex(size_t idx);
251314564Sdim  void Clear();
252254721Semaste
253254721Semasteprivate:
254314564Sdim  typedef std::vector<Value> collection;
255254721Semaste
256314564Sdim  collection m_values;
257254721Semaste};
258254721Semaste
259254721Semaste} // namespace lldb_private
260254721Semaste
261296417Sdim#endif // liblldb_Value_h_
262