xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Core/Value.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- Value.h -------------------------------------------------*- 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 LLDB_CORE_VALUE_H
10 #define LLDB_CORE_VALUE_H
11 
12 #include "lldb/Symbol/CompilerType.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/Scalar.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/lldb-enumerations.h"
17 #include "lldb/lldb-private-enumerations.h"
18 #include "lldb/lldb-private-types.h"
19 
20 #include "llvm/ADT/APInt.h"
21 
22 #include <vector>
23 
24 #include <cstdint>
25 #include <cstring>
26 
27 namespace lldb_private {
28 class DataExtractor;
29 class ExecutionContext;
30 class Module;
31 class Stream;
32 class Type;
33 class Variable;
34 }
35 
36 namespace lldb_private {
37 
38 class Value {
39 public:
40   /// Type that describes Value::m_value.
41   enum class ValueType {
42     Invalid = -1,
43     // m_value contains:
44     /// A raw scalar value.
45     Scalar = 0,
46     /// A file address value.
47     FileAddress,
48     /// A load address value.
49     LoadAddress,
50     /// A host address value (for memory in the process that < A is
51     /// using liblldb).
52     HostAddress
53   };
54 
55   /// Type that describes Value::m_context.
56   enum class ContextType {
57     // m_context contains:
58     /// Undefined.
59     Invalid = -1,
60     /// RegisterInfo * (can be a scalar or a vector register).
61     RegisterInfo = 0,
62     /// lldb_private::Type *.
63     LLDBType,
64     /// lldb_private::Variable *.
65     Variable
66   };
67 
68   Value();
69   Value(const Scalar &scalar);
70   Value(const void *bytes, int len);
71   Value(const Value &rhs);
72 
73   void SetBytes(const void *bytes, int len);
74 
75   void AppendBytes(const void *bytes, int len);
76 
77   Value &operator=(const Value &rhs);
78 
79   const CompilerType &GetCompilerType();
80 
81   void SetCompilerType(const CompilerType &compiler_type);
82 
83   ValueType GetValueType() const;
84 
85   AddressType GetValueAddressType() const;
86 
GetContextType()87   ContextType GetContextType() const { return m_context_type; }
88 
SetValueType(ValueType value_type)89   void SetValueType(ValueType value_type) { m_value_type = value_type; }
90 
ClearContext()91   void ClearContext() {
92     m_context = nullptr;
93     m_context_type = ContextType::Invalid;
94   }
95 
SetContext(ContextType context_type,void * p)96   void SetContext(ContextType context_type, void *p) {
97     m_context_type = context_type;
98     m_context = p;
99     if (m_context_type == ContextType::RegisterInfo) {
100       RegisterInfo *reg_info = GetRegisterInfo();
101       if (reg_info->encoding == lldb::eEncodingVector)
102         SetValueType(ValueType::Scalar);
103     }
104   }
105 
106   RegisterInfo *GetRegisterInfo() const;
107 
108   Type *GetType();
109 
110   Scalar &ResolveValue(ExecutionContext *exe_ctx, Module *module = nullptr);
111 
112   /// See comment on m_scalar to understand what GetScalar returns.
GetScalar()113   const Scalar &GetScalar() const { return m_value; }
114 
115   /// See comment on m_scalar to understand what GetScalar returns.
GetScalar()116   Scalar &GetScalar() { return m_value; }
117 
118   size_t ResizeData(size_t len);
119 
120   size_t AppendDataToHostBuffer(const Value &rhs);
121 
GetBuffer()122   DataBufferHeap &GetBuffer() { return m_data_buffer; }
123 
GetBuffer()124   const DataBufferHeap &GetBuffer() const { return m_data_buffer; }
125 
126   bool ValueOf(ExecutionContext *exe_ctx);
127 
128   Variable *GetVariable();
129 
130   void Dump(Stream *strm);
131 
132   lldb::Format GetValueDefaultFormat();
133 
134   uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx);
135 
136   Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
137                         Module *module); // Can be nullptr
138 
139   static const char *GetValueTypeAsCString(ValueType context_type);
140 
141   static const char *GetContextTypeAsCString(ContextType context_type);
142 
143   /// Convert this value's file address to a load address, if possible.
144   void ConvertToLoadAddress(Module *module, Target *target);
145 
146   bool GetData(DataExtractor &data);
147 
148   void Clear();
149 
150   static ValueType GetValueTypeFromAddressType(AddressType address_type);
151 
152 protected:
153   /// Represents a value, which can be a scalar, a load address, a file address,
154   /// or a host address.
155   ///
156   /// The interpretation of `m_value` depends on `m_value_type`:
157   /// - Scalar: `m_value` contains the scalar value.
158   /// - Load Address: `m_value` contains the load address.
159   /// - File Address: `m_value` contains the file address.
160   /// - Host Address: `m_value` contains a pointer to the start of the buffer in
161   ///    host memory.
162   ///   Currently, this can point to either:
163   ///     - The `m_data_buffer` of this Value instance (e.g., in DWARF
164   ///     computations).
165   ///     - The `m_data` of a Value Object containing this Value.
166   // TODO: the GetScalar() API relies on knowledge not codified by the type
167   // system, making it hard to understand and easy to misuse.
168   // - Separate the scalar from the variable that contains the address (be it a
169   //   load, file or host address).
170   // - Rename GetScalar() to something more indicative to what the scalar is,
171   //   like GetScalarOrAddress() for example.
172   // - Split GetScalar() into two functions, GetScalar() and GetAddress(), which
173   //   verify (or assert) what m_value_type is to make sure users of the class are
174   //   querying the right thing.
175   // TODO: It's confusing to point to multiple possible buffers when the
176   // ValueType is a host address. Value should probably always own its buffer.
177   // Perhaps as a shared pointer with a copy on write system if the same buffer
178   // can be shared by multiple classes.
179   Scalar m_value;
180   CompilerType m_compiler_type;
181   void *m_context = nullptr;
182   ValueType m_value_type = ValueType::Scalar;
183   ContextType m_context_type = ContextType::Invalid;
184   DataBufferHeap m_data_buffer;
185 };
186 
187 class ValueList {
188 public:
189   ValueList() = default;
190   ~ValueList() = default;
191 
192   ValueList(const ValueList &rhs) = default;
193   ValueList &operator=(const ValueList &rhs) = default;
194 
195   // void InsertValue (Value *value, size_t idx);
196   void PushValue(const Value &value);
197 
198   size_t GetSize();
199   Value *GetValueAtIndex(size_t idx);
200   void Clear();
201 
202 private:
203   typedef std::vector<Value> collection;
204 
205   collection m_values;
206 };
207 
208 } // namespace lldb_private
209 
210 #endif // LLDB_CORE_VALUE_H
211