Some checks failed
Release Asset Audit / Release Asset Audit (push) Has been cancelled
Release Asset Audit / Notify Audit Failed (push) Has been cancelled
Github Actions CodeQL / Github Actions CodeQL (push) Has been cancelled
Post-Commit Static Analyzer / post-commit-analyzer (push) Has been cancelled
Also move the equivalent helper function from ValueObjectConstResult to ValueObject.h where it more properly belongs. This patch is necessary if one were to use ValueObjectMemory for a synthetic child. There aren't any current uses of this sort in lldb, though there are on the swift fork.
340 lines
13 KiB
C++
340 lines
13 KiB
C++
//===-- ValueObjectConstResult.cpp ----------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/ValueObject/ValueObjectConstResult.h"
|
|
|
|
#include "lldb/Symbol/CompilerType.h"
|
|
#include "lldb/Target/ExecutionContext.h"
|
|
#include "lldb/Target/ExecutionContextScope.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Utility/DataBuffer.h"
|
|
#include "lldb/Utility/DataBufferHeap.h"
|
|
#include "lldb/Utility/DataExtractor.h"
|
|
#include "lldb/Utility/Scalar.h"
|
|
#include "lldb/ValueObject/ValueObjectDynamicValue.h"
|
|
#include <optional>
|
|
|
|
namespace lldb_private {
|
|
class Module;
|
|
}
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
|
|
ByteOrder byte_order,
|
|
uint32_t addr_byte_size,
|
|
lldb::addr_t address,
|
|
ValueObjectManager *manager) {
|
|
ValueObjectManagerSP manager_sp = CreateManagerIfEmpty(manager);
|
|
|
|
return (new ValueObjectConstResult(exe_scope, *manager, byte_order,
|
|
addr_byte_size, address))
|
|
->GetSP();
|
|
}
|
|
|
|
ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
|
|
ValueObjectManager &manager,
|
|
ByteOrder byte_order,
|
|
uint32_t addr_byte_size,
|
|
lldb::addr_t address)
|
|
: ValueObject(exe_scope, manager), m_impl(this, address) {
|
|
SetIsConstant();
|
|
SetValueIsValid(true);
|
|
m_data.SetByteOrder(byte_order);
|
|
m_data.SetAddressByteSize(addr_byte_size);
|
|
SetAddressTypeOfChildren(eAddressTypeLoad);
|
|
}
|
|
|
|
ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
|
|
const CompilerType &compiler_type,
|
|
ConstString name,
|
|
const DataExtractor &data,
|
|
lldb::addr_t address,
|
|
ValueObjectManager *manager) {
|
|
std::shared_ptr<ValueObjectManager> manager_sp =
|
|
CreateManagerIfEmpty(manager);
|
|
return (new ValueObjectConstResult(exe_scope, *manager, compiler_type, name,
|
|
data, address))
|
|
->GetSP();
|
|
}
|
|
|
|
ValueObjectConstResult::ValueObjectConstResult(
|
|
ExecutionContextScope *exe_scope, ValueObjectManager &manager,
|
|
const CompilerType &compiler_type, ConstString name,
|
|
const DataExtractor &data, lldb::addr_t address)
|
|
: ValueObject(exe_scope, manager), m_impl(this, address) {
|
|
m_data = data;
|
|
|
|
if (!m_data.GetSharedDataBuffer()) {
|
|
DataBufferSP shared_data_buffer(
|
|
new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
|
|
m_data.SetData(shared_data_buffer);
|
|
}
|
|
|
|
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
|
|
m_value.SetValueType(Value::ValueType::HostAddress);
|
|
m_value.SetCompilerType(compiler_type);
|
|
m_name = name;
|
|
SetIsConstant();
|
|
SetValueIsValid(true);
|
|
SetAddressTypeOfChildren(eAddressTypeLoad);
|
|
}
|
|
|
|
ValueObjectSP ValueObjectConstResult::Create(
|
|
ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
|
|
ConstString name, const lldb::DataBufferSP &data_sp,
|
|
lldb::ByteOrder data_byte_order, uint32_t data_addr_size,
|
|
lldb::addr_t address, ValueObjectManager *manager) {
|
|
std::shared_ptr<ValueObjectManager> manager_sp =
|
|
CreateManagerIfEmpty(manager);
|
|
return (new ValueObjectConstResult(exe_scope, *manager, compiler_type, name,
|
|
data_sp, data_byte_order, data_addr_size,
|
|
address))
|
|
->GetSP();
|
|
}
|
|
|
|
ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
|
|
Value &value, ConstString name,
|
|
Module *module,
|
|
ValueObjectManager *manager) {
|
|
std::shared_ptr<ValueObjectManager> manager_sp =
|
|
CreateManagerIfEmpty(manager);
|
|
return (new ValueObjectConstResult(exe_scope, *manager, value, name, module))
|
|
->GetSP();
|
|
}
|
|
|
|
ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
|
|
const CompilerType &compiler_type,
|
|
Scalar &scalar, ConstString name,
|
|
Module *module,
|
|
ValueObjectManager *manager) {
|
|
std::shared_ptr<ValueObjectManager> manager_sp =
|
|
CreateManagerIfEmpty(manager);
|
|
return (new ValueObjectConstResult(exe_scope, *manager, compiler_type, scalar,
|
|
name, module))
|
|
->GetSP();
|
|
}
|
|
|
|
ValueObjectConstResult::ValueObjectConstResult(
|
|
ExecutionContextScope *exe_scope, ValueObjectManager &manager,
|
|
const CompilerType &compiler_type, ConstString name,
|
|
const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order,
|
|
uint32_t data_addr_size, lldb::addr_t address)
|
|
: ValueObject(exe_scope, manager), m_impl(this, address) {
|
|
m_data.SetByteOrder(data_byte_order);
|
|
m_data.SetAddressByteSize(data_addr_size);
|
|
m_data.SetData(data_sp);
|
|
m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();
|
|
m_value.SetValueType(Value::ValueType::HostAddress);
|
|
m_value.SetCompilerType(compiler_type);
|
|
m_name = name;
|
|
SetIsConstant();
|
|
SetValueIsValid(true);
|
|
SetAddressTypeOfChildren(eAddressTypeLoad);
|
|
}
|
|
|
|
ValueObjectSP ValueObjectConstResult::Create(
|
|
ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
|
|
ConstString name, lldb::addr_t address, AddressType address_type,
|
|
uint32_t addr_byte_size, ValueObjectManager *manager) {
|
|
std::shared_ptr<ValueObjectManager> manager_sp =
|
|
CreateManagerIfEmpty(manager);
|
|
return (new ValueObjectConstResult(exe_scope, *manager, compiler_type, name,
|
|
address, address_type, addr_byte_size))
|
|
->GetSP();
|
|
}
|
|
|
|
ValueObjectConstResult::ValueObjectConstResult(
|
|
ExecutionContextScope *exe_scope, ValueObjectManager &manager,
|
|
const CompilerType &compiler_type, ConstString name, lldb::addr_t address,
|
|
AddressType address_type, uint32_t addr_byte_size)
|
|
: ValueObject(exe_scope, manager), m_type_name(), m_impl(this, address) {
|
|
m_value.GetScalar() = address;
|
|
m_data.SetAddressByteSize(addr_byte_size);
|
|
m_value.GetScalar().GetData(m_data, addr_byte_size);
|
|
// m_value.SetValueType(Value::ValueType::HostAddress);
|
|
switch (address_type) {
|
|
case eAddressTypeInvalid:
|
|
m_value.SetValueType(Value::ValueType::Scalar);
|
|
break;
|
|
case eAddressTypeFile:
|
|
m_value.SetValueType(Value::ValueType::FileAddress);
|
|
break;
|
|
case eAddressTypeLoad:
|
|
m_value.SetValueType(Value::ValueType::LoadAddress);
|
|
break;
|
|
case eAddressTypeHost:
|
|
m_value.SetValueType(Value::ValueType::HostAddress);
|
|
break;
|
|
}
|
|
m_value.SetCompilerType(compiler_type);
|
|
m_name = name;
|
|
SetIsConstant();
|
|
SetValueIsValid(true);
|
|
SetAddressTypeOfChildren(eAddressTypeLoad);
|
|
}
|
|
|
|
ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
|
|
Status &&error,
|
|
ValueObjectManager *manager) {
|
|
|
|
std::shared_ptr<ValueObjectManager> manager_sp =
|
|
CreateManagerIfEmpty(manager);
|
|
return (new ValueObjectConstResult(exe_scope, *manager, std::move(error)))
|
|
->GetSP();
|
|
}
|
|
|
|
ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
|
|
ValueObjectManager &manager,
|
|
Status &&error)
|
|
: ValueObject(exe_scope, manager), m_impl(this) {
|
|
m_error = std::move(error);
|
|
SetIsConstant();
|
|
}
|
|
|
|
ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
|
|
ValueObjectManager &manager,
|
|
const Value &value,
|
|
ConstString name, Module *module)
|
|
: ValueObject(exe_scope, manager), m_impl(this) {
|
|
m_value = value;
|
|
m_name = name;
|
|
ExecutionContext exe_ctx;
|
|
exe_scope->CalculateExecutionContext(exe_ctx);
|
|
m_error = m_value.GetValueAsData(&exe_ctx, m_data, module);
|
|
}
|
|
|
|
ValueObjectConstResult::ValueObjectConstResult(
|
|
ExecutionContextScope *exe_scope, ValueObjectManager &manager,
|
|
const CompilerType &compiler_type, const Scalar &scalar, ConstString name,
|
|
Module *module)
|
|
: ValueObject(exe_scope, manager), m_impl(this) {
|
|
m_value = Value(scalar);
|
|
m_value.SetCompilerType(compiler_type);
|
|
m_value.SetValueType(Value::ValueType::Scalar);
|
|
m_name = name;
|
|
ExecutionContext exe_ctx;
|
|
exe_scope->CalculateExecutionContext(exe_ctx);
|
|
m_error = m_value.GetValueAsData(&exe_ctx, m_data, module);
|
|
SetIsConstant();
|
|
SetValueIsValid(true);
|
|
SetAddressTypeOfChildren(eAddressTypeLoad);
|
|
}
|
|
|
|
ValueObjectConstResult::~ValueObjectConstResult() = default;
|
|
|
|
CompilerType ValueObjectConstResult::GetCompilerTypeImpl() {
|
|
return m_value.GetCompilerType();
|
|
}
|
|
|
|
lldb::ValueType ValueObjectConstResult::GetValueType() const {
|
|
return eValueTypeConstResult;
|
|
}
|
|
|
|
llvm::Expected<uint64_t> ValueObjectConstResult::GetByteSize() {
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
if (!m_byte_size) {
|
|
auto size_or_err =
|
|
GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
|
|
if (!size_or_err)
|
|
return size_or_err;
|
|
SetByteSize(*size_or_err);
|
|
}
|
|
if (m_byte_size)
|
|
return *m_byte_size;
|
|
return llvm::createStringError("unknown size of const result");
|
|
}
|
|
|
|
void ValueObjectConstResult::SetByteSize(size_t size) { m_byte_size = size; }
|
|
|
|
llvm::Expected<uint32_t>
|
|
ValueObjectConstResult::CalculateNumChildren(uint32_t max) {
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
|
|
if (!children_count)
|
|
return children_count;
|
|
return *children_count <= max ? *children_count : max;
|
|
}
|
|
|
|
ConstString ValueObjectConstResult::GetTypeName() {
|
|
if (m_type_name.IsEmpty())
|
|
m_type_name = GetCompilerType().GetTypeName();
|
|
return m_type_name;
|
|
}
|
|
|
|
ConstString ValueObjectConstResult::GetDisplayTypeName() {
|
|
return GetCompilerType().GetDisplayTypeName();
|
|
}
|
|
|
|
bool ValueObjectConstResult::UpdateValue() {
|
|
// Const value is always valid
|
|
SetValueIsValid(true);
|
|
return true;
|
|
}
|
|
|
|
bool ValueObjectConstResult::IsInScope() {
|
|
// A const result value is always in scope since it serializes all
|
|
// information needed to contain the constant value.
|
|
return true;
|
|
}
|
|
|
|
lldb::ValueObjectSP ValueObjectConstResult::Dereference(Status &error) {
|
|
return m_impl.Dereference(error);
|
|
}
|
|
|
|
lldb::ValueObjectSP ValueObjectConstResult::GetSyntheticChildAtOffset(
|
|
uint32_t offset, const CompilerType &type, bool can_create,
|
|
ConstString name_const_str) {
|
|
return m_impl.GetSyntheticChildAtOffset(offset, type, can_create,
|
|
name_const_str);
|
|
}
|
|
|
|
lldb::ValueObjectSP ValueObjectConstResult::AddressOf(Status &error) {
|
|
return m_impl.AddressOf(error);
|
|
}
|
|
|
|
ValueObject::AddrAndType
|
|
ValueObjectConstResult::GetAddressOf(bool scalar_is_load_address) {
|
|
return m_impl.GetAddressOf(scalar_is_load_address);
|
|
}
|
|
|
|
size_t ValueObjectConstResult::GetPointeeData(DataExtractor &data,
|
|
uint32_t item_idx,
|
|
uint32_t item_count) {
|
|
return m_impl.GetPointeeData(data, item_idx, item_count);
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectConstResult::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
|
|
// Always recalculate dynamic values for const results as the memory that
|
|
// they might point to might have changed at any time.
|
|
if (use_dynamic != eNoDynamicValues) {
|
|
if (!IsDynamic()) {
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
Process *process = exe_ctx.GetProcessPtr();
|
|
if (process && process->IsPossibleDynamicValue(*this))
|
|
m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
|
|
}
|
|
if (m_dynamic_value && m_dynamic_value->GetError().Success())
|
|
return m_dynamic_value->GetSP();
|
|
}
|
|
return ValueObjectSP();
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectConstResult::DoCast(const CompilerType &compiler_type) {
|
|
return m_impl.Cast(compiler_type);
|
|
}
|
|
|
|
lldb::LanguageType ValueObjectConstResult::GetPreferredDisplayLanguage() {
|
|
if (m_preferred_display_language != lldb::eLanguageTypeUnknown)
|
|
return m_preferred_display_language;
|
|
return GetCompilerTypeImpl().GetMinimumLanguage();
|
|
}
|