180814287SRaphael Isemann //===-- Value.cpp ---------------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Core/Value.h"
1030fdc8d8SChris Lattner
11672d2c12SJonas Devlieghere #include "lldb/Core/Address.h"
1230fdc8d8SChris Lattner #include "lldb/Core/Module.h"
13b9c1b51eSKate Stone #include "lldb/Symbol/CompilerType.h"
1430fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
1530fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h"
1630fdc8d8SChris Lattner #include "lldb/Symbol/Type.h"
1730fdc8d8SChris Lattner #include "lldb/Symbol/Variable.h"
1830fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
1930fdc8d8SChris Lattner #include "lldb/Target/Process.h"
20d5944cd1SGreg Clayton #include "lldb/Target/SectionLoadList.h"
21514487e8SGreg Clayton #include "lldb/Target/Target.h"
22672d2c12SJonas Devlieghere #include "lldb/Utility/ConstString.h"
23666cc0b2SZachary Turner #include "lldb/Utility/DataBufferHeap.h"
24666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
25672d2c12SJonas Devlieghere #include "lldb/Utility/Endian.h"
26672d2c12SJonas Devlieghere #include "lldb/Utility/FileSpec.h"
27d821c997SPavel Labath #include "lldb/Utility/State.h"
28bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
29672d2c12SJonas Devlieghere #include "lldb/lldb-defines.h"
30672d2c12SJonas Devlieghere #include "lldb/lldb-forward.h"
31672d2c12SJonas Devlieghere #include "lldb/lldb-types.h"
322f3df613SZachary Turner
33672d2c12SJonas Devlieghere #include <memory>
34672d2c12SJonas Devlieghere #include <string>
352f3df613SZachary Turner
3676e47d48SRaphael Isemann #include <cinttypes>
3730fdc8d8SChris Lattner
3830fdc8d8SChris Lattner using namespace lldb;
3930fdc8d8SChris Lattner using namespace lldb_private;
4030fdc8d8SChris Lattner
Value()419494c510SJonas Devlieghere Value::Value() : m_value(), m_compiler_type(), m_data_buffer() {}
4230fdc8d8SChris Lattner
Value(const Scalar & scalar)43b9c1b51eSKate Stone Value::Value(const Scalar &scalar)
44*28c878aeSShafik Yaghmour : m_value(scalar), m_compiler_type(), m_data_buffer() {}
4530fdc8d8SChris Lattner
Value(const void * bytes,int len)46b9c1b51eSKate Stone Value::Value(const void *bytes, int len)
47*28c878aeSShafik Yaghmour : m_value(), m_compiler_type(), m_value_type(ValueType::HostAddress),
48b9c1b51eSKate Stone m_data_buffer() {
492740787dSGreg Clayton SetBytes(bytes, len);
5030fdc8d8SChris Lattner }
5130fdc8d8SChris Lattner
Value(const Value & v)52b9c1b51eSKate Stone Value::Value(const Value &v)
535d645743SPavel Labath : m_value(v.m_value), m_compiler_type(v.m_compiler_type),
545d645743SPavel Labath m_context(v.m_context), m_value_type(v.m_value_type),
555d645743SPavel Labath m_context_type(v.m_context_type), m_data_buffer() {
56b9c1b51eSKate Stone const uintptr_t rhs_value =
57b9c1b51eSKate Stone (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
58b9c1b51eSKate Stone if ((rhs_value != 0) &&
59b9c1b51eSKate Stone (rhs_value == (uintptr_t)v.m_data_buffer.GetBytes())) {
6030fdc8d8SChris Lattner m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
6130fdc8d8SChris Lattner v.m_data_buffer.GetByteSize());
6230fdc8d8SChris Lattner
6330fdc8d8SChris Lattner m_value = (uintptr_t)m_data_buffer.GetBytes();
6430fdc8d8SChris Lattner }
6530fdc8d8SChris Lattner }
6630fdc8d8SChris Lattner
operator =(const Value & rhs)67b9c1b51eSKate Stone Value &Value::operator=(const Value &rhs) {
68b9c1b51eSKate Stone if (this != &rhs) {
691a65ae11SGreg Clayton m_value = rhs.m_value;
703ad353f3SBruce Mitchener m_compiler_type = rhs.m_compiler_type;
711a65ae11SGreg Clayton m_context = rhs.m_context;
7257ee3067SGreg Clayton m_value_type = rhs.m_value_type;
731a65ae11SGreg Clayton m_context_type = rhs.m_context_type;
74b9c1b51eSKate Stone const uintptr_t rhs_value =
75b9c1b51eSKate Stone (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);
76b9c1b51eSKate Stone if ((rhs_value != 0) &&
77b9c1b51eSKate Stone (rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes())) {
781a65ae11SGreg Clayton m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
791a65ae11SGreg Clayton rhs.m_data_buffer.GetByteSize());
801a65ae11SGreg Clayton
811a65ae11SGreg Clayton m_value = (uintptr_t)m_data_buffer.GetBytes();
821a65ae11SGreg Clayton }
831a65ae11SGreg Clayton }
841a65ae11SGreg Clayton return *this;
851a65ae11SGreg Clayton }
861a65ae11SGreg Clayton
SetBytes(const void * bytes,int len)87b9c1b51eSKate Stone void Value::SetBytes(const void *bytes, int len) {
88057efa99SAdrian Prantl m_value_type = ValueType::HostAddress;
892740787dSGreg Clayton m_data_buffer.CopyData(bytes, len);
902740787dSGreg Clayton m_value = (uintptr_t)m_data_buffer.GetBytes();
912740787dSGreg Clayton }
922740787dSGreg Clayton
AppendBytes(const void * bytes,int len)93b9c1b51eSKate Stone void Value::AppendBytes(const void *bytes, int len) {
94057efa99SAdrian Prantl m_value_type = ValueType::HostAddress;
952740787dSGreg Clayton m_data_buffer.AppendData(bytes, len);
962740787dSGreg Clayton m_value = (uintptr_t)m_data_buffer.GetBytes();
972740787dSGreg Clayton }
982740787dSGreg Clayton
Dump(Stream * strm)99b9c1b51eSKate Stone void Value::Dump(Stream *strm) {
10030fdc8d8SChris Lattner m_value.GetValue(strm, true);
10130fdc8d8SChris Lattner strm->Printf(", value_type = %s, context = %p, context_type = %s",
102b9c1b51eSKate Stone Value::GetValueTypeAsCString(m_value_type), m_context,
10330fdc8d8SChris Lattner Value::GetContextTypeAsCString(m_context_type));
10430fdc8d8SChris Lattner }
10530fdc8d8SChris Lattner
GetValueType() const106b9c1b51eSKate Stone Value::ValueType Value::GetValueType() const { return m_value_type; }
10730fdc8d8SChris Lattner
GetValueAddressType() const108b9c1b51eSKate Stone AddressType Value::GetValueAddressType() const {
109b9c1b51eSKate Stone switch (m_value_type) {
110057efa99SAdrian Prantl case ValueType::Invalid:
111057efa99SAdrian Prantl case ValueType::Scalar:
11230fdc8d8SChris Lattner break;
113057efa99SAdrian Prantl case ValueType::LoadAddress:
114b9c1b51eSKate Stone return eAddressTypeLoad;
115057efa99SAdrian Prantl case ValueType::FileAddress:
116b9c1b51eSKate Stone return eAddressTypeFile;
117057efa99SAdrian Prantl case ValueType::HostAddress:
118b9c1b51eSKate Stone return eAddressTypeHost;
11930fdc8d8SChris Lattner }
12030fdc8d8SChris Lattner return eAddressTypeInvalid;
12130fdc8d8SChris Lattner }
12230fdc8d8SChris Lattner
GetRegisterInfo() const123b9c1b51eSKate Stone RegisterInfo *Value::GetRegisterInfo() const {
124057efa99SAdrian Prantl if (m_context_type == ContextType::RegisterInfo)
12530fdc8d8SChris Lattner return static_cast<RegisterInfo *>(m_context);
126248a1305SKonrad Kleine return nullptr;
12730fdc8d8SChris Lattner }
12830fdc8d8SChris Lattner
GetType()129b9c1b51eSKate Stone Type *Value::GetType() {
130057efa99SAdrian Prantl if (m_context_type == ContextType::LLDBType)
13130fdc8d8SChris Lattner return static_cast<Type *>(m_context);
132248a1305SKonrad Kleine return nullptr;
13330fdc8d8SChris Lattner }
13430fdc8d8SChris Lattner
AppendDataToHostBuffer(const Value & rhs)135b9c1b51eSKate Stone size_t Value::AppendDataToHostBuffer(const Value &rhs) {
136f031e48fSDon Hinton if (this == &rhs)
137f031e48fSDon Hinton return 0;
138f031e48fSDon Hinton
139ac583610SGreg Clayton size_t curr_size = m_data_buffer.GetByteSize();
14097206d57SZachary Turner Status error;
141b9c1b51eSKate Stone switch (rhs.GetValueType()) {
142057efa99SAdrian Prantl case ValueType::Invalid:
143057efa99SAdrian Prantl return 0;
144057efa99SAdrian Prantl case ValueType::Scalar: {
145ac583610SGreg Clayton const size_t scalar_size = rhs.m_value.GetByteSize();
146b9c1b51eSKate Stone if (scalar_size > 0) {
147ac583610SGreg Clayton const size_t new_size = curr_size + scalar_size;
148b9c1b51eSKate Stone if (ResizeData(new_size) == new_size) {
149ac583610SGreg Clayton rhs.m_value.GetAsMemoryData(m_data_buffer.GetBytes() + curr_size,
150b9c1b51eSKate Stone scalar_size, endian::InlHostByteOrder(),
151ac583610SGreg Clayton error);
152ac583610SGreg Clayton return scalar_size;
153ac583610SGreg Clayton }
154ac583610SGreg Clayton }
155b9c1b51eSKate Stone } break;
156057efa99SAdrian Prantl case ValueType::FileAddress:
157057efa99SAdrian Prantl case ValueType::LoadAddress:
158057efa99SAdrian Prantl case ValueType::HostAddress: {
159ac583610SGreg Clayton const uint8_t *src = rhs.GetBuffer().GetBytes();
160ac583610SGreg Clayton const size_t src_len = rhs.GetBuffer().GetByteSize();
161b9c1b51eSKate Stone if (src && src_len > 0) {
162ac583610SGreg Clayton const size_t new_size = curr_size + src_len;
163b9c1b51eSKate Stone if (ResizeData(new_size) == new_size) {
164ac583610SGreg Clayton ::memcpy(m_data_buffer.GetBytes() + curr_size, src, src_len);
165ac583610SGreg Clayton return src_len;
166ac583610SGreg Clayton }
167ac583610SGreg Clayton }
168b9c1b51eSKate Stone } break;
169ac583610SGreg Clayton }
170ac583610SGreg Clayton return 0;
171ac583610SGreg Clayton }
172ac583610SGreg Clayton
ResizeData(size_t len)173b9c1b51eSKate Stone size_t Value::ResizeData(size_t len) {
174057efa99SAdrian Prantl m_value_type = ValueType::HostAddress;
17530fdc8d8SChris Lattner m_data_buffer.SetByteSize(len);
17630fdc8d8SChris Lattner m_value = (uintptr_t)m_data_buffer.GetBytes();
177ac583610SGreg Clayton return m_data_buffer.GetByteSize();
17830fdc8d8SChris Lattner }
17930fdc8d8SChris Lattner
ValueOf(ExecutionContext * exe_ctx)180b9c1b51eSKate Stone bool Value::ValueOf(ExecutionContext *exe_ctx) {
181b9c1b51eSKate Stone switch (m_context_type) {
182057efa99SAdrian Prantl case ContextType::Invalid:
183057efa99SAdrian Prantl case ContextType::RegisterInfo: // RegisterInfo *
184057efa99SAdrian Prantl case ContextType::LLDBType: // Type *
18530fdc8d8SChris Lattner break;
18630fdc8d8SChris Lattner
187057efa99SAdrian Prantl case ContextType::Variable: // Variable *
18857ee3067SGreg Clayton ResolveValue(exe_ctx);
18930fdc8d8SChris Lattner return true;
19030fdc8d8SChris Lattner }
19130fdc8d8SChris Lattner return false;
19230fdc8d8SChris Lattner }
19330fdc8d8SChris Lattner
GetValueByteSize(Status * error_ptr,ExecutionContext * exe_ctx)19497206d57SZachary Turner uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) {
195b9c1b51eSKate Stone switch (m_context_type) {
196057efa99SAdrian Prantl case ContextType::RegisterInfo: // RegisterInfo *
1972ee7b881SAdrian Prantl if (GetRegisterInfo()) {
1982ee7b881SAdrian Prantl if (error_ptr)
1992ee7b881SAdrian Prantl error_ptr->Clear();
2002ee7b881SAdrian Prantl return GetRegisterInfo()->byte_size;
2012ee7b881SAdrian Prantl }
20230fdc8d8SChris Lattner break;
20330fdc8d8SChris Lattner
204057efa99SAdrian Prantl case ContextType::Invalid:
205057efa99SAdrian Prantl case ContextType::LLDBType: // Type *
206057efa99SAdrian Prantl case ContextType::Variable: // Variable *
207b7c91a27SJim Ingham {
2082ee7b881SAdrian Prantl auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
2092ee7b881SAdrian Prantl if (llvm::Optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) {
2102ee7b881SAdrian Prantl if (error_ptr)
211fd9780c9SPavel Labath error_ptr->Clear();
2122ee7b881SAdrian Prantl return *size;
2132ee7b881SAdrian Prantl }
2142ee7b881SAdrian Prantl break;
215fd9780c9SPavel Labath }
216fd9780c9SPavel Labath }
2172ee7b881SAdrian Prantl if (error_ptr && error_ptr->Success())
2182ee7b881SAdrian Prantl error_ptr->SetErrorString("Unable to determine byte size.");
2192ee7b881SAdrian Prantl return 0;
22030fdc8d8SChris Lattner }
22130fdc8d8SChris Lattner
GetCompilerType()222b9c1b51eSKate Stone const CompilerType &Value::GetCompilerType() {
223b9c1b51eSKate Stone if (!m_compiler_type.IsValid()) {
224b9c1b51eSKate Stone switch (m_context_type) {
225057efa99SAdrian Prantl case ContextType::Invalid:
22630fdc8d8SChris Lattner break;
22730fdc8d8SChris Lattner
228057efa99SAdrian Prantl case ContextType::RegisterInfo:
2293ad353f3SBruce Mitchener break; // TODO: Eventually convert into a compiler type?
23030fdc8d8SChris Lattner
231057efa99SAdrian Prantl case ContextType::LLDBType: {
23257ee3067SGreg Clayton Type *lldb_type = GetType();
23357ee3067SGreg Clayton if (lldb_type)
2343ad353f3SBruce Mitchener m_compiler_type = lldb_type->GetForwardCompilerType();
235b9c1b51eSKate Stone } break;
23630fdc8d8SChris Lattner
237057efa99SAdrian Prantl case ContextType::Variable: {
23857ee3067SGreg Clayton Variable *variable = GetVariable();
239b9c1b51eSKate Stone if (variable) {
24057ee3067SGreg Clayton Type *variable_type = variable->GetType();
24157ee3067SGreg Clayton if (variable_type)
2423ad353f3SBruce Mitchener m_compiler_type = variable_type->GetForwardCompilerType();
24357ee3067SGreg Clayton }
244b9c1b51eSKate Stone } break;
24530fdc8d8SChris Lattner }
24657ee3067SGreg Clayton }
24730fdc8d8SChris Lattner
2483ad353f3SBruce Mitchener return m_compiler_type;
24957ee3067SGreg Clayton }
25057ee3067SGreg Clayton
SetCompilerType(const CompilerType & compiler_type)251b9c1b51eSKate Stone void Value::SetCompilerType(const CompilerType &compiler_type) {
2523ad353f3SBruce Mitchener m_compiler_type = compiler_type;
25330fdc8d8SChris Lattner }
25430fdc8d8SChris Lattner
GetValueDefaultFormat()255b9c1b51eSKate Stone lldb::Format Value::GetValueDefaultFormat() {
256b9c1b51eSKate Stone switch (m_context_type) {
257057efa99SAdrian Prantl case ContextType::RegisterInfo:
25830fdc8d8SChris Lattner if (GetRegisterInfo())
25930fdc8d8SChris Lattner return GetRegisterInfo()->format;
26030fdc8d8SChris Lattner break;
26130fdc8d8SChris Lattner
262057efa99SAdrian Prantl case ContextType::Invalid:
263057efa99SAdrian Prantl case ContextType::LLDBType:
264057efa99SAdrian Prantl case ContextType::Variable: {
26599558cc4SGreg Clayton const CompilerType &ast_type = GetCompilerType();
26657ee3067SGreg Clayton if (ast_type.IsValid())
26757ee3067SGreg Clayton return ast_type.GetFormat();
268b9c1b51eSKate Stone } break;
26930fdc8d8SChris Lattner }
27030fdc8d8SChris Lattner
27130fdc8d8SChris Lattner // Return a good default in case we can't figure anything out
27230fdc8d8SChris Lattner return eFormatHex;
27330fdc8d8SChris Lattner }
27430fdc8d8SChris Lattner
GetData(DataExtractor & data)275b9c1b51eSKate Stone bool Value::GetData(DataExtractor &data) {
276b9c1b51eSKate Stone switch (m_value_type) {
277057efa99SAdrian Prantl case ValueType::Invalid:
278057efa99SAdrian Prantl return false;
279057efa99SAdrian Prantl case ValueType::Scalar:
2808b2fe6dcSGreg Clayton if (m_value.GetData(data))
2818b2fe6dcSGreg Clayton return true;
2828b2fe6dcSGreg Clayton break;
2838b2fe6dcSGreg Clayton
284057efa99SAdrian Prantl case ValueType::LoadAddress:
285057efa99SAdrian Prantl case ValueType::FileAddress:
286057efa99SAdrian Prantl case ValueType::HostAddress:
287b9c1b51eSKate Stone if (m_data_buffer.GetByteSize()) {
288b9c1b51eSKate Stone data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(),
289b9c1b51eSKate Stone data.GetByteOrder());
2908b2fe6dcSGreg Clayton return true;
2918b2fe6dcSGreg Clayton }
2928b2fe6dcSGreg Clayton break;
2938b2fe6dcSGreg Clayton }
2948b2fe6dcSGreg Clayton
2958b2fe6dcSGreg Clayton return false;
2968b2fe6dcSGreg Clayton }
2978b2fe6dcSGreg Clayton
GetValueAsData(ExecutionContext * exe_ctx,DataExtractor & data,Module * module)29897206d57SZachary Turner Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
299d9cbd2acSAdrian Prantl Module *module) {
30030fdc8d8SChris Lattner data.Clear();
30130fdc8d8SChris Lattner
30297206d57SZachary Turner Status error;
30330fdc8d8SChris Lattner lldb::addr_t address = LLDB_INVALID_ADDRESS;
304e0d378b3SGreg Clayton AddressType address_type = eAddressTypeFile;
305dea8cb4fSGreg Clayton Address file_so_addr;
30699558cc4SGreg Clayton const CompilerType &ast_type = GetCompilerType();
3073606b567SAdrian Prantl llvm::Optional<uint64_t> type_size = ast_type.GetByteSize(
3083606b567SAdrian Prantl exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
3093606b567SAdrian Prantl // Nothing to be done for a zero-sized type.
3103606b567SAdrian Prantl if (type_size && *type_size == 0)
3113606b567SAdrian Prantl return error;
3123606b567SAdrian Prantl
313b9c1b51eSKate Stone switch (m_value_type) {
314057efa99SAdrian Prantl case ValueType::Invalid:
315057efa99SAdrian Prantl error.SetErrorString("invalid value");
316057efa99SAdrian Prantl break;
317057efa99SAdrian Prantl case ValueType::Scalar: {
3189ccb970fSBruce Mitchener data.SetByteOrder(endian::InlHostByteOrder());
31957ee3067SGreg Clayton if (ast_type.IsValid())
32057ee3067SGreg Clayton data.SetAddressByteSize(ast_type.GetPointerByteSize());
321f6ea93fbSJim Ingham else
32230fdc8d8SChris Lattner data.SetAddressByteSize(sizeof(void *));
323c707f32fSSean Callanan
324c707f32fSSean Callanan uint32_t limit_byte_size = UINT32_MAX;
325c707f32fSSean Callanan
3263606b567SAdrian Prantl if (type_size)
3273606b567SAdrian Prantl limit_byte_size = *type_size;
328c707f32fSSean Callanan
329b9c1b51eSKate Stone if (limit_byte_size <= m_value.GetByteSize()) {
330c707f32fSSean Callanan if (m_value.GetData(data, limit_byte_size))
33130fdc8d8SChris Lattner return error; // Success;
332391075c3SEnrico Granata }
333c707f32fSSean Callanan
33489533764SJonas Devlieghere error.SetErrorString("extracting data from value failed");
33530fdc8d8SChris Lattner break;
336c707f32fSSean Callanan }
337057efa99SAdrian Prantl case ValueType::LoadAddress:
338248a1305SKonrad Kleine if (exe_ctx == nullptr) {
339dea8cb4fSGreg Clayton error.SetErrorString("can't read load address (no execution context)");
340b9c1b51eSKate Stone } else {
341c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr();
342248a1305SKonrad Kleine if (process == nullptr || !process->IsAlive()) {
343c0e8a85eSGreg Clayton Target *target = exe_ctx->GetTargetPtr();
344b9c1b51eSKate Stone if (target) {
34505097246SAdrian Prantl // Allow expressions to run and evaluate things when the target has
34605097246SAdrian Prantl // memory sections loaded. This allows you to use "target modules
34705097246SAdrian Prantl // load" to load your executable and any shared libraries, then
34805097246SAdrian Prantl // execute commands where you can look at types in data sections.
349c0e8a85eSGreg Clayton const SectionLoadList &target_sections = target->GetSectionLoadList();
350b9c1b51eSKate Stone if (!target_sections.IsEmpty()) {
351c0e8a85eSGreg Clayton address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
352b9c1b51eSKate Stone if (target_sections.ResolveLoadAddress(address, file_so_addr)) {
353c0e8a85eSGreg Clayton address_type = eAddressTypeLoad;
354c0e8a85eSGreg Clayton data.SetByteOrder(target->GetArchitecture().GetByteOrder());
355b9c1b51eSKate Stone data.SetAddressByteSize(
356b9c1b51eSKate Stone target->GetArchitecture().GetAddressByteSize());
357b9c1b51eSKate Stone } else
358c0e8a85eSGreg Clayton address = LLDB_INVALID_ADDRESS;
359c0e8a85eSGreg Clayton }
360b9c1b51eSKate Stone } else {
361dea8cb4fSGreg Clayton error.SetErrorString("can't read load address (invalid process)");
36230fdc8d8SChris Lattner }
363b9c1b51eSKate Stone } else {
36430fdc8d8SChris Lattner address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
36530fdc8d8SChris Lattner address_type = eAddressTypeLoad;
366b9c1b51eSKate Stone data.SetByteOrder(
367b9c1b51eSKate Stone process->GetTarget().GetArchitecture().GetByteOrder());
368b9c1b51eSKate Stone data.SetAddressByteSize(
369b9c1b51eSKate Stone process->GetTarget().GetArchitecture().GetAddressByteSize());
370644247c1SGreg Clayton }
37130fdc8d8SChris Lattner }
37230fdc8d8SChris Lattner break;
37330fdc8d8SChris Lattner
374057efa99SAdrian Prantl case ValueType::FileAddress:
375248a1305SKonrad Kleine if (exe_ctx == nullptr) {
376dea8cb4fSGreg Clayton error.SetErrorString("can't read file address (no execution context)");
377248a1305SKonrad Kleine } else if (exe_ctx->GetTargetPtr() == nullptr) {
378dea8cb4fSGreg Clayton error.SetErrorString("can't read file address (invalid target)");
379b9c1b51eSKate Stone } else {
380644247c1SGreg Clayton address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
381b9c1b51eSKate Stone if (address == LLDB_INVALID_ADDRESS) {
382644247c1SGreg Clayton error.SetErrorString("invalid file address");
383b9c1b51eSKate Stone } else {
384248a1305SKonrad Kleine if (module == nullptr) {
38505097246SAdrian Prantl // The only thing we can currently lock down to a module so that we
38605097246SAdrian Prantl // can resolve a file address, is a variable.
38730fdc8d8SChris Lattner Variable *variable = GetVariable();
388b9c1b51eSKate Stone if (variable) {
38930fdc8d8SChris Lattner SymbolContext var_sc;
39030fdc8d8SChris Lattner variable->CalculateSymbolContext(&var_sc);
391644247c1SGreg Clayton module = var_sc.module_sp.get();
392644247c1SGreg Clayton }
393644247c1SGreg Clayton }
394644247c1SGreg Clayton
395b9c1b51eSKate Stone if (module) {
396644247c1SGreg Clayton bool resolved = false;
397644247c1SGreg Clayton ObjectFile *objfile = module->GetObjectFile();
398b9c1b51eSKate Stone if (objfile) {
399dea8cb4fSGreg Clayton Address so_addr(address, objfile->GetSectionList());
400b9c1b51eSKate Stone addr_t load_address =
401b9c1b51eSKate Stone so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
402b9c1b51eSKate Stone bool process_launched_and_stopped =
403b9c1b51eSKate Stone exe_ctx->GetProcessPtr()
404b9c1b51eSKate Stone ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(),
405b9c1b51eSKate Stone true /* must_exist */)
40604ef9492SJohnny Chen : false;
407fd72fbefSJohnny Chen // Don't use the load address if the process has exited.
408b9c1b51eSKate Stone if (load_address != LLDB_INVALID_ADDRESS &&
409b9c1b51eSKate Stone process_launched_and_stopped) {
410dea8cb4fSGreg Clayton resolved = true;
411dea8cb4fSGreg Clayton address = load_address;
41230fdc8d8SChris Lattner address_type = eAddressTypeLoad;
413b9c1b51eSKate Stone data.SetByteOrder(
414b9c1b51eSKate Stone exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
415b9c1b51eSKate Stone data.SetAddressByteSize(exe_ctx->GetTargetRef()
416b9c1b51eSKate Stone .GetArchitecture()
417b9c1b51eSKate Stone .GetAddressByteSize());
418b9c1b51eSKate Stone } else {
419b9c1b51eSKate Stone if (so_addr.IsSectionOffset()) {
420dea8cb4fSGreg Clayton resolved = true;
421dea8cb4fSGreg Clayton file_so_addr = so_addr;
422ad3843c9SGreg Clayton data.SetByteOrder(objfile->GetByteOrder());
423ad3843c9SGreg Clayton data.SetAddressByteSize(objfile->GetAddressByteSize());
424ad3843c9SGreg Clayton }
42530fdc8d8SChris Lattner }
42630fdc8d8SChris Lattner }
427b9c1b51eSKate Stone if (!resolved) {
428644247c1SGreg Clayton Variable *variable = GetVariable();
429644247c1SGreg Clayton
430b9c1b51eSKate Stone if (module) {
431644247c1SGreg Clayton if (variable)
432b9c1b51eSKate Stone error.SetErrorStringWithFormat(
433b9c1b51eSKate Stone "unable to resolve the module for file address 0x%" PRIx64
434b9c1b51eSKate Stone " for variable '%s' in %s",
435b9c1b51eSKate Stone address, variable->GetName().AsCString(""),
436b5ad4ec7SGreg Clayton module->GetFileSpec().GetPath().c_str());
437dea8cb4fSGreg Clayton else
438b9c1b51eSKate Stone error.SetErrorStringWithFormat(
439b9c1b51eSKate Stone "unable to resolve the module for file address 0x%" PRIx64
440b9c1b51eSKate Stone " in %s",
441b9c1b51eSKate Stone address, module->GetFileSpec().GetPath().c_str());
442b9c1b51eSKate Stone } else {
443644247c1SGreg Clayton if (variable)
444b9c1b51eSKate Stone error.SetErrorStringWithFormat(
445b9c1b51eSKate Stone "unable to resolve the module for file address 0x%" PRIx64
446b9c1b51eSKate Stone " for variable '%s'",
447b9c1b51eSKate Stone address, variable->GetName().AsCString(""));
448644247c1SGreg Clayton else
449b9c1b51eSKate Stone error.SetErrorStringWithFormat(
450b9c1b51eSKate Stone "unable to resolve the module for file address 0x%" PRIx64,
451b9c1b51eSKate Stone address);
452644247c1SGreg Clayton }
45330fdc8d8SChris Lattner }
454b9c1b51eSKate Stone } else {
45530fdc8d8SChris Lattner // Can't convert a file address to anything valid without more
45630fdc8d8SChris Lattner // context (which Module it came from)
457b9c1b51eSKate Stone error.SetErrorString(
458b9c1b51eSKate Stone "can't read memory from file address without more context");
45930fdc8d8SChris Lattner }
46030fdc8d8SChris Lattner }
461644247c1SGreg Clayton }
46230fdc8d8SChris Lattner break;
46330fdc8d8SChris Lattner
464057efa99SAdrian Prantl case ValueType::HostAddress:
46530fdc8d8SChris Lattner address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
466b046e032SEnrico Granata address_type = eAddressTypeHost;
467b9c1b51eSKate Stone if (exe_ctx) {
468b046e032SEnrico Granata Target *target = exe_ctx->GetTargetPtr();
469b9c1b51eSKate Stone if (target) {
470b046e032SEnrico Granata data.SetByteOrder(target->GetArchitecture().GetByteOrder());
471b046e032SEnrico Granata data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
472b046e032SEnrico Granata break;
473b046e032SEnrico Granata }
474b046e032SEnrico Granata }
475b046e032SEnrico Granata // fallback to host settings
4769ccb970fSBruce Mitchener data.SetByteOrder(endian::InlHostByteOrder());
47730fdc8d8SChris Lattner data.SetAddressByteSize(sizeof(void *));
47830fdc8d8SChris Lattner break;
47930fdc8d8SChris Lattner }
48030fdc8d8SChris Lattner
48130fdc8d8SChris Lattner // Bail if we encountered any errors
48230fdc8d8SChris Lattner if (error.Fail())
48330fdc8d8SChris Lattner return error;
48430fdc8d8SChris Lattner
485b9c1b51eSKate Stone if (address == LLDB_INVALID_ADDRESS) {
486b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid %s address",
487b9c1b51eSKate Stone address_type == eAddressTypeHost ? "host"
488b9c1b51eSKate Stone : "load");
48930fdc8d8SChris Lattner return error;
49030fdc8d8SChris Lattner }
49130fdc8d8SChris Lattner
49280bf88d8SRaphael Isemann // If we got here, we need to read the value from memory.
49395438038SEnrico Granata size_t byte_size = GetValueByteSize(&error, exe_ctx);
49430fdc8d8SChris Lattner
49580bf88d8SRaphael Isemann // Bail if we encountered any errors getting the byte size.
49630fdc8d8SChris Lattner if (error.Fail())
49730fdc8d8SChris Lattner return error;
49830fdc8d8SChris Lattner
4992ee7b881SAdrian Prantl // No memory to read for zero-sized types.
5002ee7b881SAdrian Prantl if (byte_size == 0)
5012ee7b881SAdrian Prantl return error;
5022ee7b881SAdrian Prantl
50330fdc8d8SChris Lattner // Make sure we have enough room within "data", and if we don't make
50430fdc8d8SChris Lattner // something large enough that does
505d9cbd2acSAdrian Prantl if (!data.ValidOffsetForDataOfSize(0, byte_size)) {
506d9cbd2acSAdrian Prantl auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0');
50730fdc8d8SChris Lattner data.SetData(data_sp);
50830fdc8d8SChris Lattner }
50930fdc8d8SChris Lattner
510d9cbd2acSAdrian Prantl uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
511248a1305SKonrad Kleine if (dst != nullptr) {
512b9c1b51eSKate Stone if (address_type == eAddressTypeHost) {
513e1c34bf3SJim Ingham // The address is an address in this process, so just copy it.
514b9c1b51eSKate Stone if (address == 0) {
51589533764SJonas Devlieghere error.SetErrorString("trying to read from host address of 0.");
516e1c34bf3SJim Ingham return error;
517e1c34bf3SJim Ingham }
518eac00c3bSPavel Labath memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
519b9c1b51eSKate Stone } else if ((address_type == eAddressTypeLoad) ||
520b9c1b51eSKate Stone (address_type == eAddressTypeFile)) {
521b9c1b51eSKate Stone if (file_so_addr.IsValid()) {
522e9fe788dSJason Molenda const bool force_live_memory = true;
523e9fe788dSJason Molenda if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, dst, byte_size,
524e9fe788dSJason Molenda error, force_live_memory) !=
525e9fe788dSJason Molenda byte_size) {
526b9c1b51eSKate Stone error.SetErrorStringWithFormat(
527b9c1b51eSKate Stone "read memory from 0x%" PRIx64 " failed", (uint64_t)address);
528dea8cb4fSGreg Clayton }
529b9c1b51eSKate Stone } else {
53005097246SAdrian Prantl // The execution context might have a NULL process, but it might have a
53105097246SAdrian Prantl // valid process in the exe_ctx->target, so use the
53205097246SAdrian Prantl // ExecutionContext::GetProcess accessor to ensure we get the process
53305097246SAdrian Prantl // if there is one.
534c14ee32dSGreg Clayton Process *process = exe_ctx->GetProcessPtr();
535644247c1SGreg Clayton
536b9c1b51eSKate Stone if (process) {
537b9c1b51eSKate Stone const size_t bytes_read =
538b9c1b51eSKate Stone process->ReadMemory(address, dst, byte_size, error);
539644247c1SGreg Clayton if (bytes_read != byte_size)
540b9c1b51eSKate Stone error.SetErrorStringWithFormat(
541b9c1b51eSKate Stone "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
542b9c1b51eSKate Stone (uint64_t)address, (uint32_t)bytes_read, (uint32_t)byte_size);
543b9c1b51eSKate Stone } else {
544b9c1b51eSKate Stone error.SetErrorStringWithFormat("read memory from 0x%" PRIx64
545b9c1b51eSKate Stone " failed (invalid process)",
546b9c1b51eSKate Stone (uint64_t)address);
54730fdc8d8SChris Lattner }
54830fdc8d8SChris Lattner }
549b9c1b51eSKate Stone } else {
550b9c1b51eSKate Stone error.SetErrorStringWithFormat("unsupported AddressType value (%i)",
551b9c1b51eSKate Stone address_type);
552dea8cb4fSGreg Clayton }
553b9c1b51eSKate Stone } else {
55489533764SJonas Devlieghere error.SetErrorString("out of memory");
55530fdc8d8SChris Lattner }
55630fdc8d8SChris Lattner
55730fdc8d8SChris Lattner return error;
55830fdc8d8SChris Lattner }
55930fdc8d8SChris Lattner
ResolveValue(ExecutionContext * exe_ctx)560b9c1b51eSKate Stone Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) {
5613ad353f3SBruce Mitchener const CompilerType &compiler_type = GetCompilerType();
562b9c1b51eSKate Stone if (compiler_type.IsValid()) {
563b9c1b51eSKate Stone switch (m_value_type) {
564057efa99SAdrian Prantl case ValueType::Invalid:
565057efa99SAdrian Prantl case ValueType::Scalar: // raw scalar value
56630fdc8d8SChris Lattner break;
56730fdc8d8SChris Lattner
568057efa99SAdrian Prantl case ValueType::FileAddress:
569057efa99SAdrian Prantl case ValueType::LoadAddress: // load address value
570057efa99SAdrian Prantl case ValueType::HostAddress: // host address value (for memory in the process
571b9c1b51eSKate Stone // that is using liblldb)
57230fdc8d8SChris Lattner {
57330fdc8d8SChris Lattner DataExtractor data;
574c0e8a85eSGreg Clayton lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
575d9cbd2acSAdrian Prantl Status error(GetValueAsData(exe_ctx, data, nullptr));
576b9c1b51eSKate Stone if (error.Success()) {
577644247c1SGreg Clayton Scalar scalar;
57802f58373SAdrian Prantl if (compiler_type.GetValueAsScalar(
57902f58373SAdrian Prantl data, 0, data.GetByteSize(), scalar,
58002f58373SAdrian Prantl exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) {
58130fdc8d8SChris Lattner m_value = scalar;
582057efa99SAdrian Prantl m_value_type = ValueType::Scalar;
583b9c1b51eSKate Stone } else {
584b9c1b51eSKate Stone if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
58530fdc8d8SChris Lattner m_value.Clear();
586057efa99SAdrian Prantl m_value_type = ValueType::Scalar;
58730fdc8d8SChris Lattner }
58830fdc8d8SChris Lattner }
589b9c1b51eSKate Stone } else {
590b9c1b51eSKate Stone if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
59130fdc8d8SChris Lattner m_value.Clear();
592057efa99SAdrian Prantl m_value_type = ValueType::Scalar;
59330fdc8d8SChris Lattner }
59430fdc8d8SChris Lattner }
595b9c1b51eSKate Stone } break;
59630fdc8d8SChris Lattner }
59730fdc8d8SChris Lattner }
59830fdc8d8SChris Lattner return m_value;
59930fdc8d8SChris Lattner }
60030fdc8d8SChris Lattner
GetVariable()601b9c1b51eSKate Stone Variable *Value::GetVariable() {
602057efa99SAdrian Prantl if (m_context_type == ContextType::Variable)
60330fdc8d8SChris Lattner return static_cast<Variable *>(m_context);
604248a1305SKonrad Kleine return nullptr;
60530fdc8d8SChris Lattner }
60630fdc8d8SChris Lattner
Clear()607b9c1b51eSKate Stone void Value::Clear() {
60857ee3067SGreg Clayton m_value.Clear();
6093ad353f3SBruce Mitchener m_compiler_type.Clear();
610057efa99SAdrian Prantl m_value_type = ValueType::Scalar;
611248a1305SKonrad Kleine m_context = nullptr;
612057efa99SAdrian Prantl m_context_type = ContextType::Invalid;
61357ee3067SGreg Clayton m_data_buffer.Clear();
61457ee3067SGreg Clayton }
61557ee3067SGreg Clayton
GetValueTypeAsCString(ValueType value_type)616b9c1b51eSKate Stone const char *Value::GetValueTypeAsCString(ValueType value_type) {
617b9c1b51eSKate Stone switch (value_type) {
618057efa99SAdrian Prantl case ValueType::Invalid:
619057efa99SAdrian Prantl return "invalid";
620057efa99SAdrian Prantl case ValueType::Scalar:
621b9c1b51eSKate Stone return "scalar";
622057efa99SAdrian Prantl case ValueType::FileAddress:
623b9c1b51eSKate Stone return "file address";
624057efa99SAdrian Prantl case ValueType::LoadAddress:
625b9c1b51eSKate Stone return "load address";
626057efa99SAdrian Prantl case ValueType::HostAddress:
627b9c1b51eSKate Stone return "host address";
62830fdc8d8SChris Lattner };
629057efa99SAdrian Prantl llvm_unreachable("enum cases exhausted.");
63030fdc8d8SChris Lattner }
63130fdc8d8SChris Lattner
GetContextTypeAsCString(ContextType context_type)632b9c1b51eSKate Stone const char *Value::GetContextTypeAsCString(ContextType context_type) {
633b9c1b51eSKate Stone switch (context_type) {
634057efa99SAdrian Prantl case ContextType::Invalid:
635b9c1b51eSKate Stone return "invalid";
636057efa99SAdrian Prantl case ContextType::RegisterInfo:
637b9c1b51eSKate Stone return "RegisterInfo *";
638057efa99SAdrian Prantl case ContextType::LLDBType:
639b9c1b51eSKate Stone return "Type *";
640057efa99SAdrian Prantl case ContextType::Variable:
641b9c1b51eSKate Stone return "Variable *";
64230fdc8d8SChris Lattner };
643057efa99SAdrian Prantl llvm_unreachable("enum cases exhausted.");
64430fdc8d8SChris Lattner }
64530fdc8d8SChris Lattner
ConvertToLoadAddress(Module * module,Target * target)646b51804e0SAdrian Prantl void Value::ConvertToLoadAddress(Module *module, Target *target) {
647057efa99SAdrian Prantl if (!module || !target || (GetValueType() != ValueType::FileAddress))
648b51804e0SAdrian Prantl return;
649b51804e0SAdrian Prantl
650b51804e0SAdrian Prantl lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
651b51804e0SAdrian Prantl if (file_addr == LLDB_INVALID_ADDRESS)
652b51804e0SAdrian Prantl return;
653b51804e0SAdrian Prantl
654b51804e0SAdrian Prantl Address so_addr;
655b51804e0SAdrian Prantl if (!module->ResolveFileAddress(file_addr, so_addr))
656b51804e0SAdrian Prantl return;
657b51804e0SAdrian Prantl lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
658b51804e0SAdrian Prantl if (load_addr == LLDB_INVALID_ADDRESS)
659b51804e0SAdrian Prantl return;
660b51804e0SAdrian Prantl
661057efa99SAdrian Prantl SetValueType(Value::ValueType::LoadAddress);
662b51804e0SAdrian Prantl GetScalar() = load_addr;
663b51804e0SAdrian Prantl }
664b51804e0SAdrian Prantl
PushValue(const Value & value)665b9c1b51eSKate Stone void ValueList::PushValue(const Value &value) { m_values.push_back(value); }
66630fdc8d8SChris Lattner
GetSize()667b9c1b51eSKate Stone size_t ValueList::GetSize() { return m_values.size(); }
66830fdc8d8SChris Lattner
GetValueAtIndex(size_t idx)669b9c1b51eSKate Stone Value *ValueList::GetValueAtIndex(size_t idx) {
670b9c1b51eSKate Stone if (idx < GetSize()) {
67130fdc8d8SChris Lattner return &(m_values[idx]);
672b9c1b51eSKate Stone } else
673248a1305SKonrad Kleine return nullptr;
67430fdc8d8SChris Lattner }
67530fdc8d8SChris Lattner
Clear()676b9c1b51eSKate Stone void ValueList::Clear() { m_values.clear(); }
677