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