xref: /src/contrib/llvm-project/lldb/source/Core/Value.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1cfca06d7SDimitry Andric //===-- Value.cpp ---------------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste 
9f034231aSEd Maste #include "lldb/Core/Value.h"
10f034231aSEd Maste 
1194994d37SDimitry Andric #include "lldb/Core/Address.h"
12f034231aSEd Maste #include "lldb/Core/Module.h"
1314f1b3e8SDimitry Andric #include "lldb/Symbol/CompilerType.h"
14f034231aSEd Maste #include "lldb/Symbol/ObjectFile.h"
15f034231aSEd Maste #include "lldb/Symbol/SymbolContext.h"
16f034231aSEd Maste #include "lldb/Symbol/Type.h"
17f034231aSEd Maste #include "lldb/Symbol/Variable.h"
18f034231aSEd Maste #include "lldb/Target/ExecutionContext.h"
19f034231aSEd Maste #include "lldb/Target/Process.h"
20866dcdacSEd Maste #include "lldb/Target/SectionLoadList.h"
21f034231aSEd Maste #include "lldb/Target/Target.h"
2294994d37SDimitry Andric #include "lldb/Utility/ConstString.h"
2374a628f7SDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
2474a628f7SDimitry Andric #include "lldb/Utility/DataExtractor.h"
2594994d37SDimitry Andric #include "lldb/Utility/Endian.h"
2694994d37SDimitry Andric #include "lldb/Utility/FileSpec.h"
2794994d37SDimitry Andric #include "lldb/Utility/State.h"
2874a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
2994994d37SDimitry Andric #include "lldb/lldb-defines.h"
3094994d37SDimitry Andric #include "lldb/lldb-forward.h"
3194994d37SDimitry Andric #include "lldb/lldb-types.h"
3274a628f7SDimitry Andric 
3394994d37SDimitry Andric #include <memory>
34e3b55780SDimitry Andric #include <optional>
3594994d37SDimitry Andric #include <string>
3674a628f7SDimitry Andric 
37344a3780SDimitry Andric #include <cinttypes>
38f034231aSEd Maste 
39f034231aSEd Maste using namespace lldb;
40f034231aSEd Maste using namespace lldb_private;
41f034231aSEd Maste 
Value()42344a3780SDimitry Andric Value::Value() : m_value(), m_compiler_type(), m_data_buffer() {}
43f034231aSEd Maste 
Value(const Scalar & scalar)4414f1b3e8SDimitry Andric Value::Value(const Scalar &scalar)
45145449b1SDimitry Andric     : m_value(scalar), m_compiler_type(), m_data_buffer() {}
46f034231aSEd Maste 
Value(const void * bytes,int len)4714f1b3e8SDimitry Andric Value::Value(const void *bytes, int len)
48145449b1SDimitry Andric     : m_value(), m_compiler_type(), m_value_type(ValueType::HostAddress),
4914f1b3e8SDimitry Andric       m_data_buffer() {
500cac4ca3SEd Maste   SetBytes(bytes, len);
51f034231aSEd Maste }
52f034231aSEd Maste 
Value(const Value & v)5314f1b3e8SDimitry Andric Value::Value(const Value &v)
54b60736ecSDimitry Andric     : m_value(v.m_value), m_compiler_type(v.m_compiler_type),
55b60736ecSDimitry Andric       m_context(v.m_context), m_value_type(v.m_value_type),
56b60736ecSDimitry Andric       m_context_type(v.m_context_type), m_data_buffer() {
5714f1b3e8SDimitry Andric   const uintptr_t rhs_value =
5814f1b3e8SDimitry Andric       (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
5914f1b3e8SDimitry Andric   if ((rhs_value != 0) &&
6014f1b3e8SDimitry Andric       (rhs_value == (uintptr_t)v.m_data_buffer.GetBytes())) {
61f034231aSEd Maste     m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
62f034231aSEd Maste                            v.m_data_buffer.GetByteSize());
63f034231aSEd Maste 
64f034231aSEd Maste     m_value = (uintptr_t)m_data_buffer.GetBytes();
65f034231aSEd Maste   }
66f034231aSEd Maste }
67f034231aSEd Maste 
operator =(const Value & rhs)6814f1b3e8SDimitry Andric Value &Value::operator=(const Value &rhs) {
6914f1b3e8SDimitry Andric   if (this != &rhs) {
70f034231aSEd Maste     m_value = rhs.m_value;
71e81d9d49SDimitry Andric     m_compiler_type = rhs.m_compiler_type;
72f034231aSEd Maste     m_context = rhs.m_context;
73f034231aSEd Maste     m_value_type = rhs.m_value_type;
74f034231aSEd Maste     m_context_type = rhs.m_context_type;
7514f1b3e8SDimitry Andric     const uintptr_t rhs_value =
7614f1b3e8SDimitry Andric         (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);
7714f1b3e8SDimitry Andric     if ((rhs_value != 0) &&
7814f1b3e8SDimitry Andric         (rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes())) {
79f034231aSEd Maste       m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
80f034231aSEd Maste                              rhs.m_data_buffer.GetByteSize());
81f034231aSEd Maste 
82f034231aSEd Maste       m_value = (uintptr_t)m_data_buffer.GetBytes();
83f034231aSEd Maste     }
84f034231aSEd Maste   }
85f034231aSEd Maste   return *this;
86f034231aSEd Maste }
87f034231aSEd Maste 
SetBytes(const void * bytes,int len)8814f1b3e8SDimitry Andric void Value::SetBytes(const void *bytes, int len) {
89344a3780SDimitry Andric   m_value_type = ValueType::HostAddress;
900cac4ca3SEd Maste   m_data_buffer.CopyData(bytes, len);
910cac4ca3SEd Maste   m_value = (uintptr_t)m_data_buffer.GetBytes();
920cac4ca3SEd Maste }
930cac4ca3SEd Maste 
AppendBytes(const void * bytes,int len)9414f1b3e8SDimitry Andric void Value::AppendBytes(const void *bytes, int len) {
95344a3780SDimitry Andric   m_value_type = ValueType::HostAddress;
960cac4ca3SEd Maste   m_data_buffer.AppendData(bytes, len);
970cac4ca3SEd Maste   m_value = (uintptr_t)m_data_buffer.GetBytes();
980cac4ca3SEd Maste }
990cac4ca3SEd Maste 
Dump(Stream * strm)10014f1b3e8SDimitry Andric void Value::Dump(Stream *strm) {
101b1c73532SDimitry Andric   if (!strm)
102b1c73532SDimitry Andric     return;
103b1c73532SDimitry Andric   m_value.GetValue(*strm, true);
104f034231aSEd Maste   strm->Printf(", value_type = %s, context = %p, context_type = %s",
10514f1b3e8SDimitry Andric                Value::GetValueTypeAsCString(m_value_type), m_context,
106f034231aSEd Maste                Value::GetContextTypeAsCString(m_context_type));
107f034231aSEd Maste }
108f034231aSEd Maste 
GetValueType() const10914f1b3e8SDimitry Andric Value::ValueType Value::GetValueType() const { return m_value_type; }
110f034231aSEd Maste 
GetValueAddressType() const11114f1b3e8SDimitry Andric AddressType Value::GetValueAddressType() const {
11214f1b3e8SDimitry Andric   switch (m_value_type) {
113344a3780SDimitry Andric   case ValueType::Invalid:
114344a3780SDimitry Andric   case ValueType::Scalar:
115f034231aSEd Maste     break;
116344a3780SDimitry Andric   case ValueType::LoadAddress:
11714f1b3e8SDimitry Andric     return eAddressTypeLoad;
118344a3780SDimitry Andric   case ValueType::FileAddress:
11914f1b3e8SDimitry Andric     return eAddressTypeFile;
120344a3780SDimitry Andric   case ValueType::HostAddress:
12114f1b3e8SDimitry Andric     return eAddressTypeHost;
122f034231aSEd Maste   }
123f034231aSEd Maste   return eAddressTypeInvalid;
124f034231aSEd Maste }
125f034231aSEd Maste 
GetValueTypeFromAddressType(AddressType address_type)1267fa27ce4SDimitry Andric Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
1277fa27ce4SDimitry Andric   switch (address_type) {
1287fa27ce4SDimitry Andric     case eAddressTypeFile:
1297fa27ce4SDimitry Andric       return Value::ValueType::FileAddress;
1307fa27ce4SDimitry Andric     case eAddressTypeLoad:
1317fa27ce4SDimitry Andric       return Value::ValueType::LoadAddress;
1327fa27ce4SDimitry Andric     case eAddressTypeHost:
1337fa27ce4SDimitry Andric       return Value::ValueType::HostAddress;
1347fa27ce4SDimitry Andric     case eAddressTypeInvalid:
1357fa27ce4SDimitry Andric       return Value::ValueType::Invalid;
1367fa27ce4SDimitry Andric   }
1377fa27ce4SDimitry Andric   llvm_unreachable("Unexpected address type!");
1387fa27ce4SDimitry Andric }
1397fa27ce4SDimitry Andric 
GetRegisterInfo() const14014f1b3e8SDimitry Andric RegisterInfo *Value::GetRegisterInfo() const {
141344a3780SDimitry Andric   if (m_context_type == ContextType::RegisterInfo)
142f034231aSEd Maste     return static_cast<RegisterInfo *>(m_context);
1435f29bb8aSDimitry Andric   return nullptr;
144f034231aSEd Maste }
145f034231aSEd Maste 
GetType()14614f1b3e8SDimitry Andric Type *Value::GetType() {
147344a3780SDimitry Andric   if (m_context_type == ContextType::LLDBType)
148f034231aSEd Maste     return static_cast<Type *>(m_context);
1495f29bb8aSDimitry Andric   return nullptr;
150f034231aSEd Maste }
151f034231aSEd Maste 
AppendDataToHostBuffer(const Value & rhs)15214f1b3e8SDimitry Andric size_t Value::AppendDataToHostBuffer(const Value &rhs) {
153ef5d0b5eSDimitry Andric   if (this == &rhs)
154ef5d0b5eSDimitry Andric     return 0;
155ef5d0b5eSDimitry Andric 
1560cac4ca3SEd Maste   size_t curr_size = m_data_buffer.GetByteSize();
157b76161e4SDimitry Andric   Status error;
15814f1b3e8SDimitry Andric   switch (rhs.GetValueType()) {
159344a3780SDimitry Andric   case ValueType::Invalid:
160344a3780SDimitry Andric     return 0;
161344a3780SDimitry Andric   case ValueType::Scalar: {
1620cac4ca3SEd Maste     const size_t scalar_size = rhs.m_value.GetByteSize();
16314f1b3e8SDimitry Andric     if (scalar_size > 0) {
1640cac4ca3SEd Maste       const size_t new_size = curr_size + scalar_size;
16514f1b3e8SDimitry Andric       if (ResizeData(new_size) == new_size) {
1660cac4ca3SEd Maste         rhs.m_value.GetAsMemoryData(m_data_buffer.GetBytes() + curr_size,
16714f1b3e8SDimitry Andric                                     scalar_size, endian::InlHostByteOrder(),
1680cac4ca3SEd Maste                                     error);
1690cac4ca3SEd Maste         return scalar_size;
1700cac4ca3SEd Maste       }
1710cac4ca3SEd Maste     }
17214f1b3e8SDimitry Andric   } break;
173344a3780SDimitry Andric   case ValueType::FileAddress:
174344a3780SDimitry Andric   case ValueType::LoadAddress:
175344a3780SDimitry Andric   case ValueType::HostAddress: {
1760cac4ca3SEd Maste     const uint8_t *src = rhs.GetBuffer().GetBytes();
1770cac4ca3SEd Maste     const size_t src_len = rhs.GetBuffer().GetByteSize();
17814f1b3e8SDimitry Andric     if (src && src_len > 0) {
1790cac4ca3SEd Maste       const size_t new_size = curr_size + src_len;
18014f1b3e8SDimitry Andric       if (ResizeData(new_size) == new_size) {
1810cac4ca3SEd Maste         ::memcpy(m_data_buffer.GetBytes() + curr_size, src, src_len);
1820cac4ca3SEd Maste         return src_len;
1830cac4ca3SEd Maste       }
1840cac4ca3SEd Maste     }
18514f1b3e8SDimitry Andric   } break;
1860cac4ca3SEd Maste   }
1870cac4ca3SEd Maste   return 0;
1880cac4ca3SEd Maste }
1890cac4ca3SEd Maste 
ResizeData(size_t len)19014f1b3e8SDimitry Andric size_t Value::ResizeData(size_t len) {
191344a3780SDimitry Andric   m_value_type = ValueType::HostAddress;
192f034231aSEd Maste   m_data_buffer.SetByteSize(len);
193f034231aSEd Maste   m_value = (uintptr_t)m_data_buffer.GetBytes();
1940cac4ca3SEd Maste   return m_data_buffer.GetByteSize();
195f034231aSEd Maste }
196f034231aSEd Maste 
ValueOf(ExecutionContext * exe_ctx)19714f1b3e8SDimitry Andric bool Value::ValueOf(ExecutionContext *exe_ctx) {
19814f1b3e8SDimitry Andric   switch (m_context_type) {
199344a3780SDimitry Andric   case ContextType::Invalid:
200344a3780SDimitry Andric   case ContextType::RegisterInfo: // RegisterInfo *
201344a3780SDimitry Andric   case ContextType::LLDBType:     // Type *
202f034231aSEd Maste     break;
203f034231aSEd Maste 
204344a3780SDimitry Andric   case ContextType::Variable: // Variable *
205f034231aSEd Maste     ResolveValue(exe_ctx);
206f034231aSEd Maste     return true;
207f034231aSEd Maste   }
208f034231aSEd Maste   return false;
209f034231aSEd Maste }
210f034231aSEd Maste 
GetValueByteSize(Status * error_ptr,ExecutionContext * exe_ctx)211b76161e4SDimitry Andric uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) {
21214f1b3e8SDimitry Andric   switch (m_context_type) {
213344a3780SDimitry Andric   case ContextType::RegisterInfo: // RegisterInfo *
21494994d37SDimitry Andric     if (GetRegisterInfo()) {
21594994d37SDimitry Andric       if (error_ptr)
21694994d37SDimitry Andric         error_ptr->Clear();
21794994d37SDimitry Andric       return GetRegisterInfo()->byte_size;
21894994d37SDimitry Andric     }
219f034231aSEd Maste     break;
220f034231aSEd Maste 
221344a3780SDimitry Andric   case ContextType::Invalid:
222344a3780SDimitry Andric   case ContextType::LLDBType: // Type *
223344a3780SDimitry Andric   case ContextType::Variable: // Variable *
224f034231aSEd Maste   {
22594994d37SDimitry Andric     auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
226e3b55780SDimitry Andric     if (std::optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) {
22794994d37SDimitry Andric       if (error_ptr)
228f034231aSEd Maste         error_ptr->Clear();
22994994d37SDimitry Andric       return *size;
23094994d37SDimitry Andric     }
23194994d37SDimitry Andric     break;
232f034231aSEd Maste   }
233f034231aSEd Maste   }
23494994d37SDimitry Andric   if (error_ptr && error_ptr->Success())
23594994d37SDimitry Andric     error_ptr->SetErrorString("Unable to determine byte size.");
23694994d37SDimitry Andric   return 0;
237f034231aSEd Maste }
238f034231aSEd Maste 
GetCompilerType()23914f1b3e8SDimitry Andric const CompilerType &Value::GetCompilerType() {
24014f1b3e8SDimitry Andric   if (!m_compiler_type.IsValid()) {
24114f1b3e8SDimitry Andric     switch (m_context_type) {
242344a3780SDimitry Andric     case ContextType::Invalid:
243f034231aSEd Maste       break;
244f034231aSEd Maste 
245344a3780SDimitry Andric     case ContextType::RegisterInfo:
246e81d9d49SDimitry Andric       break; // TODO: Eventually convert into a compiler type?
247f034231aSEd Maste 
248344a3780SDimitry Andric     case ContextType::LLDBType: {
249f034231aSEd Maste       Type *lldb_type = GetType();
250f034231aSEd Maste       if (lldb_type)
251e81d9d49SDimitry Andric         m_compiler_type = lldb_type->GetForwardCompilerType();
25214f1b3e8SDimitry Andric     } break;
253f034231aSEd Maste 
254344a3780SDimitry Andric     case ContextType::Variable: {
255f034231aSEd Maste       Variable *variable = GetVariable();
25614f1b3e8SDimitry Andric       if (variable) {
257f034231aSEd Maste         Type *variable_type = variable->GetType();
258f034231aSEd Maste         if (variable_type)
259e81d9d49SDimitry Andric           m_compiler_type = variable_type->GetForwardCompilerType();
260f034231aSEd Maste       }
26114f1b3e8SDimitry Andric     } break;
262f034231aSEd Maste     }
263f034231aSEd Maste   }
264f034231aSEd Maste 
265e81d9d49SDimitry Andric   return m_compiler_type;
266f034231aSEd Maste }
267f034231aSEd Maste 
SetCompilerType(const CompilerType & compiler_type)26814f1b3e8SDimitry Andric void Value::SetCompilerType(const CompilerType &compiler_type) {
269e81d9d49SDimitry Andric   m_compiler_type = compiler_type;
270f034231aSEd Maste }
271f034231aSEd Maste 
GetValueDefaultFormat()27214f1b3e8SDimitry Andric lldb::Format Value::GetValueDefaultFormat() {
27314f1b3e8SDimitry Andric   switch (m_context_type) {
274344a3780SDimitry Andric   case ContextType::RegisterInfo:
275f034231aSEd Maste     if (GetRegisterInfo())
276f034231aSEd Maste       return GetRegisterInfo()->format;
277f034231aSEd Maste     break;
278f034231aSEd Maste 
279344a3780SDimitry Andric   case ContextType::Invalid:
280344a3780SDimitry Andric   case ContextType::LLDBType:
281344a3780SDimitry Andric   case ContextType::Variable: {
282e81d9d49SDimitry Andric     const CompilerType &ast_type = GetCompilerType();
283f034231aSEd Maste     if (ast_type.IsValid())
284f034231aSEd Maste       return ast_type.GetFormat();
28514f1b3e8SDimitry Andric   } break;
286f034231aSEd Maste   }
287f034231aSEd Maste 
288f034231aSEd Maste   // Return a good default in case we can't figure anything out
289f034231aSEd Maste   return eFormatHex;
290f034231aSEd Maste }
291f034231aSEd Maste 
GetData(DataExtractor & data)29214f1b3e8SDimitry Andric bool Value::GetData(DataExtractor &data) {
29314f1b3e8SDimitry Andric   switch (m_value_type) {
294344a3780SDimitry Andric   case ValueType::Invalid:
295344a3780SDimitry Andric     return false;
296344a3780SDimitry Andric   case ValueType::Scalar:
297f034231aSEd Maste     if (m_value.GetData(data))
298f034231aSEd Maste       return true;
299f034231aSEd Maste     break;
300f034231aSEd Maste 
301344a3780SDimitry Andric   case ValueType::LoadAddress:
302344a3780SDimitry Andric   case ValueType::FileAddress:
303344a3780SDimitry Andric   case ValueType::HostAddress:
30414f1b3e8SDimitry Andric     if (m_data_buffer.GetByteSize()) {
30514f1b3e8SDimitry Andric       data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(),
30614f1b3e8SDimitry Andric                    data.GetByteOrder());
307f034231aSEd Maste       return true;
308f034231aSEd Maste     }
309f034231aSEd Maste     break;
310f034231aSEd Maste   }
311f034231aSEd Maste 
312f034231aSEd Maste   return false;
313f034231aSEd Maste }
314f034231aSEd Maste 
GetValueAsData(ExecutionContext * exe_ctx,DataExtractor & data,Module * module)315b76161e4SDimitry Andric Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
316ead24645SDimitry Andric                              Module *module) {
317f034231aSEd Maste   data.Clear();
318f034231aSEd Maste 
319b76161e4SDimitry Andric   Status error;
320f034231aSEd Maste   lldb::addr_t address = LLDB_INVALID_ADDRESS;
321f034231aSEd Maste   AddressType address_type = eAddressTypeFile;
322f034231aSEd Maste   Address file_so_addr;
323e81d9d49SDimitry Andric   const CompilerType &ast_type = GetCompilerType();
324e3b55780SDimitry Andric   std::optional<uint64_t> type_size = ast_type.GetByteSize(
325706b4fc4SDimitry Andric       exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
326706b4fc4SDimitry Andric   // Nothing to be done for a zero-sized type.
327706b4fc4SDimitry Andric   if (type_size && *type_size == 0)
328706b4fc4SDimitry Andric     return error;
329706b4fc4SDimitry Andric 
33014f1b3e8SDimitry Andric   switch (m_value_type) {
331344a3780SDimitry Andric   case ValueType::Invalid:
332344a3780SDimitry Andric     error.SetErrorString("invalid value");
333344a3780SDimitry Andric     break;
334344a3780SDimitry Andric   case ValueType::Scalar: {
335e81d9d49SDimitry Andric     data.SetByteOrder(endian::InlHostByteOrder());
336f034231aSEd Maste     if (ast_type.IsValid())
337f034231aSEd Maste       data.SetAddressByteSize(ast_type.GetPointerByteSize());
338f034231aSEd Maste     else
339f034231aSEd Maste       data.SetAddressByteSize(sizeof(void *));
340f21a844fSEd Maste 
341f21a844fSEd Maste     uint32_t limit_byte_size = UINT32_MAX;
342f21a844fSEd Maste 
343706b4fc4SDimitry Andric     if (type_size)
344706b4fc4SDimitry Andric       limit_byte_size = *type_size;
345f21a844fSEd Maste 
34614f1b3e8SDimitry Andric     if (limit_byte_size <= m_value.GetByteSize()) {
347f21a844fSEd Maste       if (m_value.GetData(data, limit_byte_size))
348f034231aSEd Maste         return error; // Success;
349f3fbd1c0SDimitry Andric     }
350f21a844fSEd Maste 
351b60736ecSDimitry Andric     error.SetErrorString("extracting data from value failed");
352f034231aSEd Maste     break;
353f21a844fSEd Maste   }
354344a3780SDimitry Andric   case ValueType::LoadAddress:
3555f29bb8aSDimitry Andric     if (exe_ctx == nullptr) {
356f034231aSEd Maste       error.SetErrorString("can't read load address (no execution context)");
35714f1b3e8SDimitry Andric     } else {
358f034231aSEd Maste       Process *process = exe_ctx->GetProcessPtr();
3595f29bb8aSDimitry Andric       if (process == nullptr || !process->IsAlive()) {
360f034231aSEd Maste         Target *target = exe_ctx->GetTargetPtr();
36114f1b3e8SDimitry Andric         if (target) {
362f73363f1SDimitry Andric           // Allow expressions to run and evaluate things when the target has
363f73363f1SDimitry Andric           // memory sections loaded. This allows you to use "target modules
364f73363f1SDimitry Andric           // load" to load your executable and any shared libraries, then
365f73363f1SDimitry Andric           // execute commands where you can look at types in data sections.
366f034231aSEd Maste           const SectionLoadList &target_sections = target->GetSectionLoadList();
36714f1b3e8SDimitry Andric           if (!target_sections.IsEmpty()) {
368f034231aSEd Maste             address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
36914f1b3e8SDimitry Andric             if (target_sections.ResolveLoadAddress(address, file_so_addr)) {
370f034231aSEd Maste               address_type = eAddressTypeLoad;
371f034231aSEd Maste               data.SetByteOrder(target->GetArchitecture().GetByteOrder());
37214f1b3e8SDimitry Andric               data.SetAddressByteSize(
37314f1b3e8SDimitry Andric                   target->GetArchitecture().GetAddressByteSize());
37414f1b3e8SDimitry Andric             } else
375f034231aSEd Maste               address = LLDB_INVALID_ADDRESS;
376f034231aSEd Maste           }
37714f1b3e8SDimitry Andric         } else {
378f034231aSEd Maste           error.SetErrorString("can't read load address (invalid process)");
379f034231aSEd Maste         }
38014f1b3e8SDimitry Andric       } else {
381f034231aSEd Maste         address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
382f034231aSEd Maste         address_type = eAddressTypeLoad;
38314f1b3e8SDimitry Andric         data.SetByteOrder(
38414f1b3e8SDimitry Andric             process->GetTarget().GetArchitecture().GetByteOrder());
38514f1b3e8SDimitry Andric         data.SetAddressByteSize(
38614f1b3e8SDimitry Andric             process->GetTarget().GetArchitecture().GetAddressByteSize());
387f034231aSEd Maste       }
388f034231aSEd Maste     }
389f034231aSEd Maste     break;
390f034231aSEd Maste 
391344a3780SDimitry Andric   case ValueType::FileAddress:
3925f29bb8aSDimitry Andric     if (exe_ctx == nullptr) {
393f034231aSEd Maste       error.SetErrorString("can't read file address (no execution context)");
3945f29bb8aSDimitry Andric     } else if (exe_ctx->GetTargetPtr() == nullptr) {
395f034231aSEd Maste       error.SetErrorString("can't read file address (invalid target)");
39614f1b3e8SDimitry Andric     } else {
397f034231aSEd Maste       address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
39814f1b3e8SDimitry Andric       if (address == LLDB_INVALID_ADDRESS) {
399f034231aSEd Maste         error.SetErrorString("invalid file address");
40014f1b3e8SDimitry Andric       } else {
4015f29bb8aSDimitry Andric         if (module == nullptr) {
402f73363f1SDimitry Andric           // The only thing we can currently lock down to a module so that we
403f73363f1SDimitry Andric           // can resolve a file address, is a variable.
404f034231aSEd Maste           Variable *variable = GetVariable();
40514f1b3e8SDimitry Andric           if (variable) {
406f034231aSEd Maste             SymbolContext var_sc;
407f034231aSEd Maste             variable->CalculateSymbolContext(&var_sc);
408f034231aSEd Maste             module = var_sc.module_sp.get();
409f034231aSEd Maste           }
410f034231aSEd Maste         }
411f034231aSEd Maste 
41214f1b3e8SDimitry Andric         if (module) {
413f034231aSEd Maste           bool resolved = false;
414f034231aSEd Maste           ObjectFile *objfile = module->GetObjectFile();
41514f1b3e8SDimitry Andric           if (objfile) {
416f034231aSEd Maste             Address so_addr(address, objfile->GetSectionList());
41714f1b3e8SDimitry Andric             addr_t load_address =
41814f1b3e8SDimitry Andric                 so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
41914f1b3e8SDimitry Andric             bool process_launched_and_stopped =
42014f1b3e8SDimitry Andric                 exe_ctx->GetProcessPtr()
42114f1b3e8SDimitry Andric                     ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(),
42214f1b3e8SDimitry Andric                                           true /* must_exist */)
423f034231aSEd Maste                     : false;
424f034231aSEd Maste             // Don't use the load address if the process has exited.
42514f1b3e8SDimitry Andric             if (load_address != LLDB_INVALID_ADDRESS &&
42614f1b3e8SDimitry Andric                 process_launched_and_stopped) {
427f034231aSEd Maste               resolved = true;
428f034231aSEd Maste               address = load_address;
429f034231aSEd Maste               address_type = eAddressTypeLoad;
43014f1b3e8SDimitry Andric               data.SetByteOrder(
43114f1b3e8SDimitry Andric                   exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
43214f1b3e8SDimitry Andric               data.SetAddressByteSize(exe_ctx->GetTargetRef()
43314f1b3e8SDimitry Andric                                           .GetArchitecture()
43414f1b3e8SDimitry Andric                                           .GetAddressByteSize());
43514f1b3e8SDimitry Andric             } else {
43614f1b3e8SDimitry Andric               if (so_addr.IsSectionOffset()) {
437f034231aSEd Maste                 resolved = true;
438f034231aSEd Maste                 file_so_addr = so_addr;
439f034231aSEd Maste                 data.SetByteOrder(objfile->GetByteOrder());
440f034231aSEd Maste                 data.SetAddressByteSize(objfile->GetAddressByteSize());
441f034231aSEd Maste               }
442f034231aSEd Maste             }
443f034231aSEd Maste           }
44414f1b3e8SDimitry Andric           if (!resolved) {
445f034231aSEd Maste             Variable *variable = GetVariable();
446f034231aSEd Maste 
44714f1b3e8SDimitry Andric             if (module) {
448f034231aSEd Maste               if (variable)
44914f1b3e8SDimitry Andric                 error.SetErrorStringWithFormat(
45014f1b3e8SDimitry Andric                     "unable to resolve the module for file address 0x%" PRIx64
45114f1b3e8SDimitry Andric                     " for variable '%s' in %s",
45214f1b3e8SDimitry Andric                     address, variable->GetName().AsCString(""),
453f034231aSEd Maste                     module->GetFileSpec().GetPath().c_str());
454f034231aSEd Maste               else
45514f1b3e8SDimitry Andric                 error.SetErrorStringWithFormat(
45614f1b3e8SDimitry Andric                     "unable to resolve the module for file address 0x%" PRIx64
45714f1b3e8SDimitry Andric                     " in %s",
45814f1b3e8SDimitry Andric                     address, module->GetFileSpec().GetPath().c_str());
45914f1b3e8SDimitry Andric             } else {
460f034231aSEd Maste               if (variable)
46114f1b3e8SDimitry Andric                 error.SetErrorStringWithFormat(
46214f1b3e8SDimitry Andric                     "unable to resolve the module for file address 0x%" PRIx64
46314f1b3e8SDimitry Andric                     " for variable '%s'",
46414f1b3e8SDimitry Andric                     address, variable->GetName().AsCString(""));
465f034231aSEd Maste               else
46614f1b3e8SDimitry Andric                 error.SetErrorStringWithFormat(
46714f1b3e8SDimitry Andric                     "unable to resolve the module for file address 0x%" PRIx64,
46814f1b3e8SDimitry Andric                     address);
469f034231aSEd Maste             }
470f034231aSEd Maste           }
47114f1b3e8SDimitry Andric         } else {
472f034231aSEd Maste           // Can't convert a file address to anything valid without more
473f034231aSEd Maste           // context (which Module it came from)
47414f1b3e8SDimitry Andric           error.SetErrorString(
47514f1b3e8SDimitry Andric               "can't read memory from file address without more context");
476f034231aSEd Maste         }
477f034231aSEd Maste       }
478f034231aSEd Maste     }
479f034231aSEd Maste     break;
480f034231aSEd Maste 
481344a3780SDimitry Andric   case ValueType::HostAddress:
482f034231aSEd Maste     address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
483f034231aSEd Maste     address_type = eAddressTypeHost;
48414f1b3e8SDimitry Andric     if (exe_ctx) {
485f034231aSEd Maste       Target *target = exe_ctx->GetTargetPtr();
48614f1b3e8SDimitry Andric       if (target) {
487f034231aSEd Maste         data.SetByteOrder(target->GetArchitecture().GetByteOrder());
488f034231aSEd Maste         data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
489f034231aSEd Maste         break;
490f034231aSEd Maste       }
491f034231aSEd Maste     }
492f034231aSEd Maste     // fallback to host settings
493e81d9d49SDimitry Andric     data.SetByteOrder(endian::InlHostByteOrder());
494f034231aSEd Maste     data.SetAddressByteSize(sizeof(void *));
495f034231aSEd Maste     break;
496f034231aSEd Maste   }
497f034231aSEd Maste 
498f034231aSEd Maste   // Bail if we encountered any errors
499f034231aSEd Maste   if (error.Fail())
500f034231aSEd Maste     return error;
501f034231aSEd Maste 
50214f1b3e8SDimitry Andric   if (address == LLDB_INVALID_ADDRESS) {
50314f1b3e8SDimitry Andric     error.SetErrorStringWithFormat("invalid %s address",
50414f1b3e8SDimitry Andric                                    address_type == eAddressTypeHost ? "host"
50514f1b3e8SDimitry Andric                                                                     : "load");
506f034231aSEd Maste     return error;
507f034231aSEd Maste   }
508f034231aSEd Maste 
509706b4fc4SDimitry Andric   // If we got here, we need to read the value from memory.
510e81d9d49SDimitry Andric   size_t byte_size = GetValueByteSize(&error, exe_ctx);
511f034231aSEd Maste 
512706b4fc4SDimitry Andric   // Bail if we encountered any errors getting the byte size.
513f034231aSEd Maste   if (error.Fail())
514f034231aSEd Maste     return error;
515f034231aSEd Maste 
5165f29bb8aSDimitry Andric   // No memory to read for zero-sized types.
5175f29bb8aSDimitry Andric   if (byte_size == 0)
5185f29bb8aSDimitry Andric     return error;
5195f29bb8aSDimitry Andric 
520f034231aSEd Maste   // Make sure we have enough room within "data", and if we don't make
521f034231aSEd Maste   // something large enough that does
522ead24645SDimitry Andric   if (!data.ValidOffsetForDataOfSize(0, byte_size)) {
523ead24645SDimitry Andric     auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0');
524f034231aSEd Maste     data.SetData(data_sp);
525f034231aSEd Maste   }
526f034231aSEd Maste 
527ead24645SDimitry Andric   uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
5285f29bb8aSDimitry Andric   if (dst != nullptr) {
52914f1b3e8SDimitry Andric     if (address_type == eAddressTypeHost) {
5300cac4ca3SEd Maste       // The address is an address in this process, so just copy it.
53114f1b3e8SDimitry Andric       if (address == 0) {
532b60736ecSDimitry Andric         error.SetErrorString("trying to read from host address of 0.");
5330cac4ca3SEd Maste         return error;
5340cac4ca3SEd Maste       }
535ef5d0b5eSDimitry Andric       memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
53614f1b3e8SDimitry Andric     } else if ((address_type == eAddressTypeLoad) ||
53714f1b3e8SDimitry Andric                (address_type == eAddressTypeFile)) {
53814f1b3e8SDimitry Andric       if (file_so_addr.IsValid()) {
539344a3780SDimitry Andric         const bool force_live_memory = true;
540344a3780SDimitry Andric         if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, dst, byte_size,
541344a3780SDimitry Andric                                                error, force_live_memory) !=
542344a3780SDimitry Andric             byte_size) {
54314f1b3e8SDimitry Andric           error.SetErrorStringWithFormat(
54414f1b3e8SDimitry Andric               "read memory from 0x%" PRIx64 " failed", (uint64_t)address);
545f034231aSEd Maste         }
54614f1b3e8SDimitry Andric       } else {
547f73363f1SDimitry Andric         // The execution context might have a NULL process, but it might have a
548f73363f1SDimitry Andric         // valid process in the exe_ctx->target, so use the
549f73363f1SDimitry Andric         // ExecutionContext::GetProcess accessor to ensure we get the process
550f73363f1SDimitry Andric         // if there is one.
551f034231aSEd Maste         Process *process = exe_ctx->GetProcessPtr();
552f034231aSEd Maste 
55314f1b3e8SDimitry Andric         if (process) {
55414f1b3e8SDimitry Andric           const size_t bytes_read =
55514f1b3e8SDimitry Andric               process->ReadMemory(address, dst, byte_size, error);
556f034231aSEd Maste           if (bytes_read != byte_size)
55714f1b3e8SDimitry Andric             error.SetErrorStringWithFormat(
55814f1b3e8SDimitry Andric                 "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
55914f1b3e8SDimitry Andric                 (uint64_t)address, (uint32_t)bytes_read, (uint32_t)byte_size);
56014f1b3e8SDimitry Andric         } else {
56114f1b3e8SDimitry Andric           error.SetErrorStringWithFormat("read memory from 0x%" PRIx64
56214f1b3e8SDimitry Andric                                          " failed (invalid process)",
56314f1b3e8SDimitry Andric                                          (uint64_t)address);
564f034231aSEd Maste         }
565f034231aSEd Maste       }
56614f1b3e8SDimitry Andric     } else {
56714f1b3e8SDimitry Andric       error.SetErrorStringWithFormat("unsupported AddressType value (%i)",
56814f1b3e8SDimitry Andric                                      address_type);
569f034231aSEd Maste     }
57014f1b3e8SDimitry Andric   } else {
571b60736ecSDimitry Andric     error.SetErrorString("out of memory");
572f034231aSEd Maste   }
573f034231aSEd Maste 
574f034231aSEd Maste   return error;
575f034231aSEd Maste }
576f034231aSEd Maste 
ResolveValue(ExecutionContext * exe_ctx,Module * module)577b1c73532SDimitry Andric Scalar &Value::ResolveValue(ExecutionContext *exe_ctx, Module *module) {
578e81d9d49SDimitry Andric   const CompilerType &compiler_type = GetCompilerType();
57914f1b3e8SDimitry Andric   if (compiler_type.IsValid()) {
58014f1b3e8SDimitry Andric     switch (m_value_type) {
581344a3780SDimitry Andric     case ValueType::Invalid:
582344a3780SDimitry Andric     case ValueType::Scalar: // raw scalar value
583f034231aSEd Maste       break;
584f034231aSEd Maste 
585344a3780SDimitry Andric     case ValueType::FileAddress:
586344a3780SDimitry Andric     case ValueType::LoadAddress: // load address value
587344a3780SDimitry Andric     case ValueType::HostAddress: // host address value (for memory in the process
58814f1b3e8SDimitry Andric                                 // that is using liblldb)
589f034231aSEd Maste     {
590f034231aSEd Maste       DataExtractor data;
591f034231aSEd Maste       lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
592b1c73532SDimitry Andric       Status error(GetValueAsData(exe_ctx, data, module));
59314f1b3e8SDimitry Andric       if (error.Success()) {
594f034231aSEd Maste         Scalar scalar;
595b60736ecSDimitry Andric         if (compiler_type.GetValueAsScalar(
596b60736ecSDimitry Andric                 data, 0, data.GetByteSize(), scalar,
597b60736ecSDimitry Andric                 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) {
598f034231aSEd Maste           m_value = scalar;
599344a3780SDimitry Andric           m_value_type = ValueType::Scalar;
60014f1b3e8SDimitry Andric         } else {
60114f1b3e8SDimitry Andric           if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
602f034231aSEd Maste             m_value.Clear();
603344a3780SDimitry Andric             m_value_type = ValueType::Scalar;
604f034231aSEd Maste           }
605f034231aSEd Maste         }
60614f1b3e8SDimitry Andric       } else {
60714f1b3e8SDimitry Andric         if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
608f034231aSEd Maste           m_value.Clear();
609344a3780SDimitry Andric           m_value_type = ValueType::Scalar;
610f034231aSEd Maste         }
611f034231aSEd Maste       }
61214f1b3e8SDimitry Andric     } break;
613f034231aSEd Maste     }
614f034231aSEd Maste   }
615f034231aSEd Maste   return m_value;
616f034231aSEd Maste }
617f034231aSEd Maste 
GetVariable()61814f1b3e8SDimitry Andric Variable *Value::GetVariable() {
619344a3780SDimitry Andric   if (m_context_type == ContextType::Variable)
620f034231aSEd Maste     return static_cast<Variable *>(m_context);
6215f29bb8aSDimitry Andric   return nullptr;
622f034231aSEd Maste }
623f034231aSEd Maste 
Clear()62414f1b3e8SDimitry Andric void Value::Clear() {
625f034231aSEd Maste   m_value.Clear();
626e81d9d49SDimitry Andric   m_compiler_type.Clear();
627344a3780SDimitry Andric   m_value_type = ValueType::Scalar;
6285f29bb8aSDimitry Andric   m_context = nullptr;
629344a3780SDimitry Andric   m_context_type = ContextType::Invalid;
630f034231aSEd Maste   m_data_buffer.Clear();
631f034231aSEd Maste }
632f034231aSEd Maste 
GetValueTypeAsCString(ValueType value_type)63314f1b3e8SDimitry Andric const char *Value::GetValueTypeAsCString(ValueType value_type) {
63414f1b3e8SDimitry Andric   switch (value_type) {
635344a3780SDimitry Andric   case ValueType::Invalid:
636344a3780SDimitry Andric     return "invalid";
637344a3780SDimitry Andric   case ValueType::Scalar:
63814f1b3e8SDimitry Andric     return "scalar";
639344a3780SDimitry Andric   case ValueType::FileAddress:
64014f1b3e8SDimitry Andric     return "file address";
641344a3780SDimitry Andric   case ValueType::LoadAddress:
64214f1b3e8SDimitry Andric     return "load address";
643344a3780SDimitry Andric   case ValueType::HostAddress:
64414f1b3e8SDimitry Andric     return "host address";
645f034231aSEd Maste   };
646344a3780SDimitry Andric   llvm_unreachable("enum cases exhausted.");
647f034231aSEd Maste }
648f034231aSEd Maste 
GetContextTypeAsCString(ContextType context_type)64914f1b3e8SDimitry Andric const char *Value::GetContextTypeAsCString(ContextType context_type) {
65014f1b3e8SDimitry Andric   switch (context_type) {
651344a3780SDimitry Andric   case ContextType::Invalid:
65214f1b3e8SDimitry Andric     return "invalid";
653344a3780SDimitry Andric   case ContextType::RegisterInfo:
65414f1b3e8SDimitry Andric     return "RegisterInfo *";
655344a3780SDimitry Andric   case ContextType::LLDBType:
65614f1b3e8SDimitry Andric     return "Type *";
657344a3780SDimitry Andric   case ContextType::Variable:
65814f1b3e8SDimitry Andric     return "Variable *";
659f034231aSEd Maste   };
660344a3780SDimitry Andric   llvm_unreachable("enum cases exhausted.");
661f034231aSEd Maste }
662f034231aSEd Maste 
ConvertToLoadAddress(Module * module,Target * target)663f73363f1SDimitry Andric void Value::ConvertToLoadAddress(Module *module, Target *target) {
664344a3780SDimitry Andric   if (!module || !target || (GetValueType() != ValueType::FileAddress))
665f73363f1SDimitry Andric     return;
666f73363f1SDimitry Andric 
667f73363f1SDimitry Andric   lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
668f73363f1SDimitry Andric   if (file_addr == LLDB_INVALID_ADDRESS)
669f73363f1SDimitry Andric     return;
670f73363f1SDimitry Andric 
671f73363f1SDimitry Andric   Address so_addr;
672f73363f1SDimitry Andric   if (!module->ResolveFileAddress(file_addr, so_addr))
673f73363f1SDimitry Andric     return;
674f73363f1SDimitry Andric   lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
675f73363f1SDimitry Andric   if (load_addr == LLDB_INVALID_ADDRESS)
676f73363f1SDimitry Andric     return;
677f73363f1SDimitry Andric 
678344a3780SDimitry Andric   SetValueType(Value::ValueType::LoadAddress);
679f73363f1SDimitry Andric   GetScalar() = load_addr;
680f73363f1SDimitry Andric }
681f73363f1SDimitry Andric 
PushValue(const Value & value)68214f1b3e8SDimitry Andric void ValueList::PushValue(const Value &value) { m_values.push_back(value); }
683f034231aSEd Maste 
GetSize()68414f1b3e8SDimitry Andric size_t ValueList::GetSize() { return m_values.size(); }
685f034231aSEd Maste 
GetValueAtIndex(size_t idx)68614f1b3e8SDimitry Andric Value *ValueList::GetValueAtIndex(size_t idx) {
68714f1b3e8SDimitry Andric   if (idx < GetSize()) {
688f034231aSEd Maste     return &(m_values[idx]);
68914f1b3e8SDimitry Andric   } else
6905f29bb8aSDimitry Andric     return nullptr;
691f034231aSEd Maste }
692f034231aSEd Maste 
Clear()69314f1b3e8SDimitry Andric void ValueList::Clear() { m_values.clear(); }
694