706 lines · cpp
1//===-- Value.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/Core/Value.h"10 11#include "lldb/Core/Address.h"12#include "lldb/Core/Module.h"13#include "lldb/Symbol/CompilerType.h"14#include "lldb/Symbol/ObjectFile.h"15#include "lldb/Symbol/SymbolContext.h"16#include "lldb/Symbol/Type.h"17#include "lldb/Symbol/Variable.h"18#include "lldb/Target/ExecutionContext.h"19#include "lldb/Target/Process.h"20#include "lldb/Target/SectionLoadList.h"21#include "lldb/Target/Target.h"22#include "lldb/Utility/ConstString.h"23#include "lldb/Utility/DataBufferHeap.h"24#include "lldb/Utility/DataExtractor.h"25#include "lldb/Utility/Endian.h"26#include "lldb/Utility/FileSpec.h"27#include "lldb/Utility/LLDBLog.h"28#include "lldb/Utility/Log.h"29#include "lldb/Utility/State.h"30#include "lldb/Utility/Stream.h"31#include "lldb/lldb-defines.h"32#include "lldb/lldb-forward.h"33#include "lldb/lldb-types.h"34 35#include <memory>36#include <optional>37#include <string>38 39#include <cinttypes>40 41using namespace lldb;42using namespace lldb_private;43 44Value::Value() : m_value(), m_compiler_type(), m_data_buffer() {}45 46Value::Value(const Scalar &scalar)47 : m_value(scalar), m_compiler_type(), m_data_buffer() {}48 49Value::Value(const void *bytes, int len)50 : m_value(), m_compiler_type(), m_value_type(ValueType::HostAddress),51 m_data_buffer() {52 SetBytes(bytes, len);53}54 55Value::Value(const Value &v)56 : m_value(v.m_value), m_compiler_type(v.m_compiler_type),57 m_context(v.m_context), m_value_type(v.m_value_type),58 m_context_type(v.m_context_type), m_data_buffer() {59 const uintptr_t rhs_value =60 (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);61 if ((rhs_value != 0) &&62 (rhs_value == (uintptr_t)v.m_data_buffer.GetBytes())) {63 m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),64 v.m_data_buffer.GetByteSize());65 66 m_value = (uintptr_t)m_data_buffer.GetBytes();67 }68}69 70Value &Value::operator=(const Value &rhs) {71 if (this != &rhs) {72 m_value = rhs.m_value;73 m_compiler_type = rhs.m_compiler_type;74 m_context = rhs.m_context;75 m_value_type = rhs.m_value_type;76 m_context_type = rhs.m_context_type;77 const uintptr_t rhs_value =78 (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);79 if ((rhs_value != 0) &&80 (rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes())) {81 m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),82 rhs.m_data_buffer.GetByteSize());83 84 m_value = (uintptr_t)m_data_buffer.GetBytes();85 }86 }87 return *this;88}89 90void Value::SetBytes(const void *bytes, int len) {91 m_value_type = ValueType::HostAddress;92 m_data_buffer.CopyData(bytes, len);93 m_value = (uintptr_t)m_data_buffer.GetBytes();94}95 96void Value::AppendBytes(const void *bytes, int len) {97 m_value_type = ValueType::HostAddress;98 m_data_buffer.AppendData(bytes, len);99 m_value = (uintptr_t)m_data_buffer.GetBytes();100}101 102void Value::Dump(Stream *strm) {103 if (!strm)104 return;105 m_value.GetValue(*strm, true);106 strm->Printf(", value_type = %s, context = %p, context_type = %s",107 Value::GetValueTypeAsCString(m_value_type), m_context,108 Value::GetContextTypeAsCString(m_context_type));109}110 111Value::ValueType Value::GetValueType() const { return m_value_type; }112 113AddressType Value::GetValueAddressType() const {114 switch (m_value_type) {115 case ValueType::Invalid:116 case ValueType::Scalar:117 break;118 case ValueType::LoadAddress:119 return eAddressTypeLoad;120 case ValueType::FileAddress:121 return eAddressTypeFile;122 case ValueType::HostAddress:123 return eAddressTypeHost;124 }125 return eAddressTypeInvalid;126}127 128Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {129 switch (address_type) {130 case eAddressTypeFile:131 return Value::ValueType::FileAddress;132 case eAddressTypeLoad:133 return Value::ValueType::LoadAddress;134 case eAddressTypeHost:135 return Value::ValueType::HostAddress;136 case eAddressTypeInvalid:137 return Value::ValueType::Invalid;138 }139 llvm_unreachable("Unexpected address type!");140}141 142RegisterInfo *Value::GetRegisterInfo() const {143 if (m_context_type == ContextType::RegisterInfo)144 return static_cast<RegisterInfo *>(m_context);145 return nullptr;146}147 148Type *Value::GetType() {149 if (m_context_type == ContextType::LLDBType)150 return static_cast<Type *>(m_context);151 return nullptr;152}153 154size_t Value::AppendDataToHostBuffer(const Value &rhs) {155 if (this == &rhs)156 return 0;157 158 size_t curr_size = m_data_buffer.GetByteSize();159 Status error;160 switch (rhs.GetValueType()) {161 case ValueType::Invalid:162 return 0;163 case ValueType::Scalar: {164 const size_t scalar_size = rhs.m_value.GetByteSize();165 if (scalar_size > 0) {166 const size_t new_size = curr_size + scalar_size;167 if (ResizeData(new_size) == new_size) {168 rhs.m_value.GetAsMemoryData(m_data_buffer.GetBytes() + curr_size,169 scalar_size, endian::InlHostByteOrder(),170 error);171 return scalar_size;172 }173 }174 } break;175 case ValueType::FileAddress:176 case ValueType::LoadAddress:177 case ValueType::HostAddress: {178 const uint8_t *src = rhs.GetBuffer().GetBytes();179 const size_t src_len = rhs.GetBuffer().GetByteSize();180 if (src && src_len > 0) {181 const size_t new_size = curr_size + src_len;182 if (ResizeData(new_size) == new_size) {183 ::memcpy(m_data_buffer.GetBytes() + curr_size, src, src_len);184 return src_len;185 }186 }187 } break;188 }189 return 0;190}191 192size_t Value::ResizeData(size_t len) {193 m_value_type = ValueType::HostAddress;194 m_data_buffer.SetByteSize(len);195 m_value = (uintptr_t)m_data_buffer.GetBytes();196 return m_data_buffer.GetByteSize();197}198 199bool Value::ValueOf(ExecutionContext *exe_ctx) {200 switch (m_context_type) {201 case ContextType::Invalid:202 case ContextType::RegisterInfo: // RegisterInfo *203 case ContextType::LLDBType: // Type *204 break;205 206 case ContextType::Variable: // Variable *207 ResolveValue(exe_ctx);208 return true;209 }210 return false;211}212 213uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) {214 switch (m_context_type) {215 case ContextType::RegisterInfo: // RegisterInfo *216 if (GetRegisterInfo()) {217 if (error_ptr)218 error_ptr->Clear();219 return GetRegisterInfo()->byte_size;220 }221 break;222 223 case ContextType::Invalid:224 case ContextType::LLDBType: // Type *225 case ContextType::Variable: // Variable *226 {227 auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;228 auto size_or_err = GetCompilerType().GetByteSize(scope);229 if (!size_or_err) {230 if (error_ptr && error_ptr->Success())231 *error_ptr = Status::FromError(size_or_err.takeError());232 else233 LLDB_LOG_ERRORV(GetLog(LLDBLog::Types), size_or_err.takeError(), "{0}");234 } else {235 if (error_ptr)236 error_ptr->Clear();237 return *size_or_err;238 }239 break;240 }241 }242 if (error_ptr && error_ptr->Success())243 *error_ptr = Status::FromErrorString("Unable to determine byte size.");244 return 0;245}246 247const CompilerType &Value::GetCompilerType() {248 if (!m_compiler_type.IsValid()) {249 switch (m_context_type) {250 case ContextType::Invalid:251 break;252 253 case ContextType::RegisterInfo:254 break; // TODO: Eventually convert into a compiler type?255 256 case ContextType::LLDBType: {257 Type *lldb_type = GetType();258 if (lldb_type)259 m_compiler_type = lldb_type->GetForwardCompilerType();260 } break;261 262 case ContextType::Variable: {263 Variable *variable = GetVariable();264 if (variable) {265 Type *variable_type = variable->GetType();266 if (variable_type)267 m_compiler_type = variable_type->GetForwardCompilerType();268 }269 } break;270 }271 }272 273 return m_compiler_type;274}275 276void Value::SetCompilerType(const CompilerType &compiler_type) {277 m_compiler_type = compiler_type;278}279 280lldb::Format Value::GetValueDefaultFormat() {281 switch (m_context_type) {282 case ContextType::RegisterInfo:283 if (GetRegisterInfo())284 return GetRegisterInfo()->format;285 break;286 287 case ContextType::Invalid:288 case ContextType::LLDBType:289 case ContextType::Variable: {290 const CompilerType &ast_type = GetCompilerType();291 if (ast_type.IsValid())292 return ast_type.GetFormat();293 } break;294 }295 296 // Return a good default in case we can't figure anything out297 return eFormatHex;298}299 300bool Value::GetData(DataExtractor &data) {301 switch (m_value_type) {302 case ValueType::Invalid:303 return false;304 case ValueType::Scalar:305 if (m_value.GetData(data))306 return true;307 break;308 309 case ValueType::LoadAddress:310 case ValueType::FileAddress:311 case ValueType::HostAddress:312 if (m_data_buffer.GetByteSize()) {313 data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(),314 data.GetByteOrder());315 return true;316 }317 break;318 }319 320 return false;321}322 323Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,324 Module *module) {325 data.Clear();326 327 Status error;328 lldb::addr_t address = LLDB_INVALID_ADDRESS;329 AddressType address_type = eAddressTypeFile;330 Address file_so_addr;331 const CompilerType &ast_type = GetCompilerType();332 std::optional<uint64_t> type_size =333 llvm::expectedToOptional(ast_type.GetByteSize(334 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr));335 // Nothing to be done for a zero-sized type.336 if (type_size && *type_size == 0)337 return error;338 339 switch (m_value_type) {340 case ValueType::Invalid:341 error = Status::FromErrorString("invalid value");342 break;343 case ValueType::Scalar: {344 data.SetByteOrder(endian::InlHostByteOrder());345 if (ast_type.IsValid())346 data.SetAddressByteSize(ast_type.GetPointerByteSize());347 else348 data.SetAddressByteSize(sizeof(void *));349 350 if (!type_size)351 return Status::FromErrorString("type does not have a size");352 353 uint32_t result_byte_size = *type_size;354 if (m_value.GetData(data, result_byte_size))355 return error; // Success;356 357 error = Status::FromErrorString("extracting data from value failed");358 break;359 }360 case ValueType::LoadAddress:361 if (exe_ctx == nullptr) {362 error = Status::FromErrorString(363 "can't read load address (no execution context)");364 } else {365 Process *process = exe_ctx->GetProcessPtr();366 if (process == nullptr || !process->IsAlive()) {367 Target *target = exe_ctx->GetTargetPtr();368 if (target) {369 // Allow expressions to run and evaluate things when the target has370 // memory sections loaded. This allows you to use "target modules371 // load" to load your executable and any shared libraries, then372 // execute commands where you can look at types in data sections.373 if (target->HasLoadedSections()) {374 address = m_value.ULongLong(LLDB_INVALID_ADDRESS);375 if (target->ResolveLoadAddress(address, file_so_addr)) {376 address_type = eAddressTypeLoad;377 data.SetByteOrder(target->GetArchitecture().GetByteOrder());378 data.SetAddressByteSize(379 target->GetArchitecture().GetAddressByteSize());380 } else381 address = LLDB_INVALID_ADDRESS;382 }383 } else {384 error = Status::FromErrorString(385 "can't read load address (invalid process)");386 }387 } else {388 address = m_value.ULongLong(LLDB_INVALID_ADDRESS);389 address_type = eAddressTypeLoad;390 data.SetByteOrder(391 process->GetTarget().GetArchitecture().GetByteOrder());392 data.SetAddressByteSize(393 process->GetTarget().GetArchitecture().GetAddressByteSize());394 }395 }396 break;397 398 case ValueType::FileAddress:399 if (exe_ctx == nullptr) {400 error = Status::FromErrorString(401 "can't read file address (no execution context)");402 } else if (exe_ctx->GetTargetPtr() == nullptr) {403 error =404 Status::FromErrorString("can't read file address (invalid target)");405 } else {406 address = m_value.ULongLong(LLDB_INVALID_ADDRESS);407 if (address == LLDB_INVALID_ADDRESS) {408 error = Status::FromErrorString("invalid file address");409 } else {410 if (module == nullptr) {411 // The only thing we can currently lock down to a module so that we412 // can resolve a file address, is a variable.413 Variable *variable = GetVariable();414 if (variable) {415 SymbolContext var_sc;416 variable->CalculateSymbolContext(&var_sc);417 module = var_sc.module_sp.get();418 }419 }420 421 if (module) {422 bool resolved = false;423 ObjectFile *objfile = module->GetObjectFile();424 if (objfile) {425 Address so_addr(address, objfile->GetSectionList());426 addr_t load_address =427 so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());428 bool process_launched_and_stopped =429 exe_ctx->GetProcessPtr()430 ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(),431 true /* must_exist */)432 : false;433 // Don't use the load address if the process has exited.434 if (load_address != LLDB_INVALID_ADDRESS &&435 process_launched_and_stopped) {436 resolved = true;437 address = load_address;438 address_type = eAddressTypeLoad;439 data.SetByteOrder(440 exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());441 data.SetAddressByteSize(exe_ctx->GetTargetRef()442 .GetArchitecture()443 .GetAddressByteSize());444 } else {445 if (so_addr.IsSectionOffset()) {446 resolved = true;447 file_so_addr = so_addr;448 data.SetByteOrder(objfile->GetByteOrder());449 data.SetAddressByteSize(objfile->GetAddressByteSize());450 }451 }452 }453 if (!resolved) {454 Variable *variable = GetVariable();455 456 if (module) {457 if (variable)458 error = Status::FromErrorStringWithFormat(459 "unable to resolve the module for file address 0x%" PRIx64460 " for variable '%s' in %s",461 address, variable->GetName().AsCString(""),462 module->GetFileSpec().GetPath().c_str());463 else464 error = Status::FromErrorStringWithFormat(465 "unable to resolve the module for file address 0x%" PRIx64466 " in %s",467 address, module->GetFileSpec().GetPath().c_str());468 } else {469 if (variable)470 error = Status::FromErrorStringWithFormat(471 "unable to resolve the module for file address 0x%" PRIx64472 " for variable '%s'",473 address, variable->GetName().AsCString(""));474 else475 error = Status::FromErrorStringWithFormat(476 "unable to resolve the module for file address 0x%" PRIx64,477 address);478 }479 }480 } else {481 // Can't convert a file address to anything valid without more482 // context (which Module it came from)483 error = Status::FromErrorString(484 "can't read memory from file address without more context");485 }486 }487 }488 break;489 490 case ValueType::HostAddress:491 address = m_value.ULongLong(LLDB_INVALID_ADDRESS);492 address_type = eAddressTypeHost;493 if (exe_ctx) {494 if (Target *target = exe_ctx->GetTargetPtr()) {495 // Registers are always stored in host endian.496 data.SetByteOrder(m_context_type == ContextType::RegisterInfo497 ? endian::InlHostByteOrder()498 : target->GetArchitecture().GetByteOrder());499 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());500 break;501 }502 }503 // fallback to host settings504 data.SetByteOrder(endian::InlHostByteOrder());505 data.SetAddressByteSize(sizeof(void *));506 break;507 }508 509 // Bail if we encountered any errors510 if (error.Fail())511 return error;512 513 if (address == LLDB_INVALID_ADDRESS) {514 error = Status::FromErrorStringWithFormat(515 "invalid %s address",516 address_type == eAddressTypeHost ? "host" : "load");517 return error;518 }519 520 // If we got here, we need to read the value from memory.521 size_t byte_size = GetValueByteSize(&error, exe_ctx);522 523 // Bail if we encountered any errors getting the byte size.524 if (error.Fail())525 return error;526 527 // No memory to read for zero-sized types.528 if (byte_size == 0)529 return error;530 531 // Make sure we have enough room within "data", and if we don't make532 // something large enough that does533 if (!data.ValidOffsetForDataOfSize(0, byte_size)) {534 auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0');535 data.SetData(data_sp);536 }537 538 uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));539 if (dst != nullptr) {540 if (address_type == eAddressTypeHost) {541 // The address is an address in this process, so just copy it.542 if (address == 0) {543 error =544 Status::FromErrorString("trying to read from host address of 0.");545 return error;546 }547 memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);548 } else if ((address_type == eAddressTypeLoad) ||549 (address_type == eAddressTypeFile)) {550 if (file_so_addr.IsValid()) {551 const bool force_live_memory = true;552 if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, dst, byte_size,553 error, force_live_memory) !=554 byte_size) {555 error = Status::FromErrorStringWithFormat(556 "read memory from 0x%" PRIx64 " failed", (uint64_t)address);557 }558 } else {559 // The execution context might have a NULL process, but it might have a560 // valid process in the exe_ctx->target, so use the561 // ExecutionContext::GetProcess accessor to ensure we get the process562 // if there is one.563 Process *process = exe_ctx->GetProcessPtr();564 565 if (process) {566 const size_t bytes_read =567 process->ReadMemory(address, dst, byte_size, error);568 if (bytes_read != byte_size)569 error = Status::FromErrorStringWithFormat(570 "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",571 (uint64_t)address, (uint32_t)bytes_read, (uint32_t)byte_size);572 } else {573 error = Status::FromErrorStringWithFormat(574 "read memory from 0x%" PRIx64 " failed (invalid process)",575 (uint64_t)address);576 }577 }578 } else {579 error = Status::FromErrorStringWithFormat(580 "unsupported AddressType value (%i)", address_type);581 }582 } else {583 error = Status::FromErrorString("out of memory");584 }585 586 return error;587}588 589Scalar &Value::ResolveValue(ExecutionContext *exe_ctx, Module *module) {590 const CompilerType &compiler_type = GetCompilerType();591 if (compiler_type.IsValid()) {592 switch (m_value_type) {593 case ValueType::Invalid:594 case ValueType::Scalar: // raw scalar value595 break;596 597 case ValueType::FileAddress:598 case ValueType::LoadAddress: // load address value599 case ValueType::HostAddress: // host address value (for memory in the process600 // that is using liblldb)601 {602 DataExtractor data;603 lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);604 Status error(GetValueAsData(exe_ctx, data, module));605 if (error.Success()) {606 Scalar scalar;607 if (compiler_type.GetValueAsScalar(608 data, 0, data.GetByteSize(), scalar,609 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) {610 m_value = scalar;611 m_value_type = ValueType::Scalar;612 } else {613 if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {614 m_value.Clear();615 m_value_type = ValueType::Scalar;616 }617 }618 } else {619 if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {620 m_value.Clear();621 m_value_type = ValueType::Scalar;622 }623 }624 } break;625 }626 }627 return m_value;628}629 630Variable *Value::GetVariable() {631 if (m_context_type == ContextType::Variable)632 return static_cast<Variable *>(m_context);633 return nullptr;634}635 636void Value::Clear() {637 m_value.Clear();638 m_compiler_type.Clear();639 m_value_type = ValueType::Scalar;640 m_context = nullptr;641 m_context_type = ContextType::Invalid;642 m_data_buffer.Clear();643}644 645const char *Value::GetValueTypeAsCString(ValueType value_type) {646 switch (value_type) {647 case ValueType::Invalid:648 return "invalid";649 case ValueType::Scalar:650 return "scalar";651 case ValueType::FileAddress:652 return "file address";653 case ValueType::LoadAddress:654 return "load address";655 case ValueType::HostAddress:656 return "host address";657 };658 llvm_unreachable("enum cases exhausted.");659}660 661const char *Value::GetContextTypeAsCString(ContextType context_type) {662 switch (context_type) {663 case ContextType::Invalid:664 return "invalid";665 case ContextType::RegisterInfo:666 return "RegisterInfo *";667 case ContextType::LLDBType:668 return "Type *";669 case ContextType::Variable:670 return "Variable *";671 };672 llvm_unreachable("enum cases exhausted.");673}674 675void Value::ConvertToLoadAddress(Module *module, Target *target) {676 if (!module || !target || (GetValueType() != ValueType::FileAddress))677 return;678 679 lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS);680 if (file_addr == LLDB_INVALID_ADDRESS)681 return;682 683 Address so_addr;684 if (!module->ResolveFileAddress(file_addr, so_addr))685 return;686 lldb::addr_t load_addr = so_addr.GetLoadAddress(target);687 if (load_addr == LLDB_INVALID_ADDRESS)688 return;689 690 SetValueType(Value::ValueType::LoadAddress);691 GetScalar() = load_addr;692}693 694void ValueList::PushValue(const Value &value) { m_values.push_back(value); }695 696size_t ValueList::GetSize() { return m_values.size(); }697 698Value *ValueList::GetValueAtIndex(size_t idx) {699 if (idx < GetSize()) {700 return &(m_values[idx]);701 } else702 return nullptr;703}704 705void ValueList::Clear() { m_values.clear(); }706