333 lines · cpp
1//===-- ValueObjectConstResult.cpp ----------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/ValueObject/ValueObjectConstResult.h"10 11#include "lldb/Symbol/CompilerType.h"12#include "lldb/Target/ExecutionContext.h"13#include "lldb/Target/ExecutionContextScope.h"14#include "lldb/Target/Process.h"15#include "lldb/Utility/DataBuffer.h"16#include "lldb/Utility/DataBufferHeap.h"17#include "lldb/Utility/DataExtractor.h"18#include "lldb/Utility/Scalar.h"19#include "lldb/ValueObject/ValueObjectDynamicValue.h"20#include <optional>21 22namespace lldb_private {23class Module;24}25 26using namespace lldb;27using namespace lldb_private;28 29ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,30 ByteOrder byte_order,31 uint32_t addr_byte_size,32 lldb::addr_t address) {33 auto manager_sp = ValueObjectManager::Create();34 return (new ValueObjectConstResult(exe_scope, *manager_sp, byte_order,35 addr_byte_size, address))36 ->GetSP();37}38 39ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,40 ValueObjectManager &manager,41 ByteOrder byte_order,42 uint32_t addr_byte_size,43 lldb::addr_t address)44 : ValueObject(exe_scope, manager), m_impl(this, address) {45 SetIsConstant();46 SetValueIsValid(true);47 m_data.SetByteOrder(byte_order);48 m_data.SetAddressByteSize(addr_byte_size);49 SetAddressTypeOfChildren(eAddressTypeLoad);50}51 52ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,53 const CompilerType &compiler_type,54 ConstString name,55 const DataExtractor &data,56 lldb::addr_t address) {57 auto manager_sp = ValueObjectManager::Create();58 return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type,59 name, data, address))60 ->GetSP();61}62 63ValueObjectConstResult::ValueObjectConstResult(64 ExecutionContextScope *exe_scope, ValueObjectManager &manager,65 const CompilerType &compiler_type, ConstString name,66 const DataExtractor &data, lldb::addr_t address)67 : ValueObject(exe_scope, manager), m_impl(this, address) {68 m_data = data;69 70 if (!m_data.GetSharedDataBuffer()) {71 DataBufferSP shared_data_buffer(72 new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));73 m_data.SetData(shared_data_buffer);74 }75 76 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();77 m_value.SetValueType(Value::ValueType::HostAddress);78 m_value.SetCompilerType(compiler_type);79 m_name = name;80 SetIsConstant();81 SetValueIsValid(true);82 SetAddressTypeOfChildren(eAddressTypeLoad);83}84 85ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,86 const CompilerType &compiler_type,87 ConstString name,88 const lldb::DataBufferSP &data_sp,89 lldb::ByteOrder data_byte_order,90 uint32_t data_addr_size,91 lldb::addr_t address) {92 auto manager_sp = ValueObjectManager::Create();93 return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type,94 name, data_sp, data_byte_order,95 data_addr_size, address))96 ->GetSP();97}98 99ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,100 Value &value, ConstString name,101 Module *module) {102 auto manager_sp = ValueObjectManager::Create();103 return (new ValueObjectConstResult(exe_scope, *manager_sp, value, name,104 module))105 ->GetSP();106}107 108ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,109 const CompilerType &compiler_type,110 Scalar &scalar, ConstString name,111 Module *module) {112 auto manager_sp = ValueObjectManager::Create();113 return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type,114 scalar, name, module))115 ->GetSP();116}117 118ValueObjectConstResult::ValueObjectConstResult(119 ExecutionContextScope *exe_scope, ValueObjectManager &manager,120 const CompilerType &compiler_type, ConstString name,121 const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order,122 uint32_t data_addr_size, lldb::addr_t address)123 : ValueObject(exe_scope, manager), m_impl(this, address) {124 m_data.SetByteOrder(data_byte_order);125 m_data.SetAddressByteSize(data_addr_size);126 m_data.SetData(data_sp);127 m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();128 m_value.SetValueType(Value::ValueType::HostAddress);129 m_value.SetCompilerType(compiler_type);130 m_name = name;131 SetIsConstant();132 SetValueIsValid(true);133 SetAddressTypeOfChildren(eAddressTypeLoad);134}135 136ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,137 const CompilerType &compiler_type,138 ConstString name,139 lldb::addr_t address,140 AddressType address_type,141 uint32_t addr_byte_size) {142 auto manager_sp = ValueObjectManager::Create();143 return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type,144 name, address, address_type,145 addr_byte_size))146 ->GetSP();147}148 149ValueObjectConstResult::ValueObjectConstResult(150 ExecutionContextScope *exe_scope, ValueObjectManager &manager,151 const CompilerType &compiler_type, ConstString name, lldb::addr_t address,152 AddressType address_type, uint32_t addr_byte_size)153 : ValueObject(exe_scope, manager), m_type_name(), m_impl(this, address) {154 m_value.GetScalar() = address;155 m_data.SetAddressByteSize(addr_byte_size);156 m_value.GetScalar().GetData(m_data, addr_byte_size);157 // m_value.SetValueType(Value::ValueType::HostAddress);158 switch (address_type) {159 case eAddressTypeInvalid:160 m_value.SetValueType(Value::ValueType::Scalar);161 break;162 case eAddressTypeFile:163 m_value.SetValueType(Value::ValueType::FileAddress);164 break;165 case eAddressTypeLoad:166 m_value.SetValueType(Value::ValueType::LoadAddress);167 break;168 case eAddressTypeHost:169 m_value.SetValueType(Value::ValueType::HostAddress);170 break;171 }172 m_value.SetCompilerType(compiler_type);173 m_name = name;174 SetIsConstant();175 SetValueIsValid(true);176 SetAddressTypeOfChildren(eAddressTypeLoad);177}178 179ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,180 Status &&error) {181 auto manager_sp = ValueObjectManager::Create();182 return (new ValueObjectConstResult(exe_scope, *manager_sp, std::move(error)))183 ->GetSP();184}185 186ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,187 ValueObjectManager &manager,188 Status &&error)189 : ValueObject(exe_scope, manager), m_impl(this) {190 m_error = std::move(error);191 SetIsConstant();192}193 194ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,195 ValueObjectManager &manager,196 const Value &value,197 ConstString name, Module *module)198 : ValueObject(exe_scope, manager), m_impl(this) {199 m_value = value;200 m_name = name;201 ExecutionContext exe_ctx;202 exe_scope->CalculateExecutionContext(exe_ctx);203 m_error = m_value.GetValueAsData(&exe_ctx, m_data, module);204}205 206ValueObjectConstResult::ValueObjectConstResult(207 ExecutionContextScope *exe_scope, ValueObjectManager &manager,208 const CompilerType &compiler_type, const Scalar &scalar, ConstString name,209 Module *module)210 : ValueObject(exe_scope, manager), m_impl(this) {211 m_value = Value(scalar);212 m_value.SetCompilerType(compiler_type);213 m_value.SetValueType(Value::ValueType::Scalar);214 m_name = name;215 ExecutionContext exe_ctx;216 exe_scope->CalculateExecutionContext(exe_ctx);217 m_error = m_value.GetValueAsData(&exe_ctx, m_data, module);218 SetIsConstant();219 SetValueIsValid(true);220 SetAddressTypeOfChildren(eAddressTypeLoad);221}222 223ValueObjectConstResult::~ValueObjectConstResult() = default;224 225CompilerType ValueObjectConstResult::GetCompilerTypeImpl() {226 return m_value.GetCompilerType();227}228 229lldb::ValueType ValueObjectConstResult::GetValueType() const {230 return eValueTypeConstResult;231}232 233llvm::Expected<uint64_t> ValueObjectConstResult::GetByteSize() {234 ExecutionContext exe_ctx(GetExecutionContextRef());235 if (!m_byte_size) {236 auto size_or_err =237 GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());238 if (!size_or_err)239 return size_or_err;240 SetByteSize(*size_or_err);241 }242 if (m_byte_size)243 return *m_byte_size;244 return llvm::createStringError("unknown size of const result");245}246 247void ValueObjectConstResult::SetByteSize(size_t size) { m_byte_size = size; }248 249llvm::Expected<uint32_t>250ValueObjectConstResult::CalculateNumChildren(uint32_t max) {251 ExecutionContext exe_ctx(GetExecutionContextRef());252 auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);253 if (!children_count)254 return children_count;255 return *children_count <= max ? *children_count : max;256}257 258ConstString ValueObjectConstResult::GetTypeName() {259 if (m_type_name.IsEmpty())260 m_type_name = GetCompilerType().GetTypeName();261 return m_type_name;262}263 264ConstString ValueObjectConstResult::GetDisplayTypeName() {265 return GetCompilerType().GetDisplayTypeName();266}267 268bool ValueObjectConstResult::UpdateValue() {269 // Const value is always valid270 SetValueIsValid(true);271 return true;272}273 274bool ValueObjectConstResult::IsInScope() {275 // A const result value is always in scope since it serializes all276 // information needed to contain the constant value.277 return true;278}279 280lldb::ValueObjectSP ValueObjectConstResult::Dereference(Status &error) {281 return m_impl.Dereference(error);282}283 284lldb::ValueObjectSP ValueObjectConstResult::GetSyntheticChildAtOffset(285 uint32_t offset, const CompilerType &type, bool can_create,286 ConstString name_const_str) {287 return m_impl.GetSyntheticChildAtOffset(offset, type, can_create,288 name_const_str);289}290 291lldb::ValueObjectSP ValueObjectConstResult::AddressOf(Status &error) {292 return m_impl.AddressOf(error);293}294 295ValueObject::AddrAndType296ValueObjectConstResult::GetAddressOf(bool scalar_is_load_address) {297 return m_impl.GetAddressOf(scalar_is_load_address);298}299 300size_t ValueObjectConstResult::GetPointeeData(DataExtractor &data,301 uint32_t item_idx,302 uint32_t item_count) {303 return m_impl.GetPointeeData(data, item_idx, item_count);304}305 306lldb::ValueObjectSP307ValueObjectConstResult::GetDynamicValue(lldb::DynamicValueType use_dynamic) {308 // Always recalculate dynamic values for const results as the memory that309 // they might point to might have changed at any time.310 if (use_dynamic != eNoDynamicValues) {311 if (!IsDynamic()) {312 ExecutionContext exe_ctx(GetExecutionContextRef());313 Process *process = exe_ctx.GetProcessPtr();314 if (process && process->IsPossibleDynamicValue(*this))315 m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);316 }317 if (m_dynamic_value && m_dynamic_value->GetError().Success())318 return m_dynamic_value->GetSP();319 }320 return ValueObjectSP();321}322 323lldb::ValueObjectSP324ValueObjectConstResult::DoCast(const CompilerType &compiler_type) {325 return m_impl.Cast(compiler_type);326}327 328lldb::LanguageType ValueObjectConstResult::GetPreferredDisplayLanguage() {329 if (m_preferred_display_language != lldb::eLanguageTypeUnknown)330 return m_preferred_display_language;331 return GetCompilerTypeImpl().GetMinimumLanguage();332}333