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