mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-01 16:36:07 +00:00

Summary: NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]] This commit is the result of modernizing the LLDB codebase by using `nullptr` instread of `0` or `NULL`. See https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html for more information. This is the command I ran and I to fix and format the code base: ``` run-clang-tidy.py \ -header-filter='.*' \ -checks='-*,modernize-use-nullptr' \ -fix ~/dev/llvm-project/lldb/.* \ -format \ -style LLVM \ -p ~/llvm-builds/debug-ninja-gcc ``` NOTE: There were also changes to `llvm/utils/unittest` but I did not include them because I felt that maybe this library shall be updated in isolation somehow. NOTE: I know this is a rather large commit but it is a nobrainer in most parts. Reviewers: martong, espindola, shafik, #lldb, JDevlieghere Reviewed By: JDevlieghere Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits Tags: #lldb, #llvm Differential Revision: https://reviews.llvm.org/D61847 llvm-svn: 361484
359 lines
11 KiB
C++
359 lines
11 KiB
C++
//===-- ValueObjectRegister.cpp ---------------------------------*- C++ -*-===//
|
|
//
|
|
// 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/Core/ValueObjectRegister.h"
|
|
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/Value.h"
|
|
#include "lldb/Symbol/CompilerType.h"
|
|
#include "lldb/Symbol/TypeSystem.h"
|
|
#include "lldb/Target/ExecutionContext.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/RegisterContext.h"
|
|
#include "lldb/Target/StackFrame.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Utility/DataExtractor.h"
|
|
#include "lldb/Utility/Scalar.h"
|
|
#include "lldb/Utility/Status.h"
|
|
#include "lldb/Utility/Stream.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
#include <assert.h>
|
|
#include <memory>
|
|
|
|
namespace lldb_private {
|
|
class ExecutionContextScope;
|
|
}
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
#pragma mark ValueObjectRegisterContext
|
|
|
|
ValueObjectRegisterContext::ValueObjectRegisterContext(
|
|
ValueObject &parent, RegisterContextSP ®_ctx)
|
|
: ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
|
|
assert(reg_ctx);
|
|
m_name.SetCString("Registers");
|
|
SetValueIsValid(true);
|
|
}
|
|
|
|
ValueObjectRegisterContext::~ValueObjectRegisterContext() {}
|
|
|
|
CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() {
|
|
return CompilerType();
|
|
}
|
|
|
|
ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); }
|
|
|
|
ConstString ValueObjectRegisterContext::GetDisplayTypeName() {
|
|
return ConstString();
|
|
}
|
|
|
|
ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
|
|
return ConstString();
|
|
}
|
|
|
|
size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) {
|
|
auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
|
|
return reg_set_count <= max ? reg_set_count : max;
|
|
}
|
|
|
|
uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; }
|
|
|
|
bool ValueObjectRegisterContext::UpdateValue() {
|
|
m_error.Clear();
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
if (frame)
|
|
m_reg_ctx_sp = frame->GetRegisterContext();
|
|
else
|
|
m_reg_ctx_sp.reset();
|
|
|
|
if (m_reg_ctx_sp.get() == nullptr) {
|
|
SetValueIsValid(false);
|
|
m_error.SetErrorToGenericError();
|
|
} else
|
|
SetValueIsValid(true);
|
|
|
|
return m_error.Success();
|
|
}
|
|
|
|
ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
|
|
size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
|
|
ValueObject *new_valobj = nullptr;
|
|
|
|
const size_t num_children = GetNumChildren();
|
|
if (idx < num_children) {
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
new_valobj = new ValueObjectRegisterSet(
|
|
exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
|
|
}
|
|
|
|
return new_valobj;
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark ValueObjectRegisterSet
|
|
|
|
ValueObjectSP
|
|
ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
|
|
lldb::RegisterContextSP ®_ctx_sp,
|
|
uint32_t set_idx) {
|
|
return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
|
|
}
|
|
|
|
ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
|
|
lldb::RegisterContextSP ®_ctx,
|
|
uint32_t reg_set_idx)
|
|
: ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(nullptr),
|
|
m_reg_set_idx(reg_set_idx) {
|
|
assert(reg_ctx);
|
|
m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
|
|
if (m_reg_set) {
|
|
m_name.SetCString(m_reg_set->name);
|
|
}
|
|
}
|
|
|
|
ValueObjectRegisterSet::~ValueObjectRegisterSet() {}
|
|
|
|
CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
|
|
return CompilerType();
|
|
}
|
|
|
|
ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
|
|
|
|
ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
|
|
return ConstString();
|
|
}
|
|
|
|
size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
|
|
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
|
|
if (reg_set) {
|
|
auto reg_count = reg_set->num_registers;
|
|
return reg_count <= max ? reg_count : max;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
|
|
|
|
bool ValueObjectRegisterSet::UpdateValue() {
|
|
m_error.Clear();
|
|
SetValueDidChange(false);
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
if (frame == nullptr)
|
|
m_reg_ctx_sp.reset();
|
|
else {
|
|
m_reg_ctx_sp = frame->GetRegisterContext();
|
|
if (m_reg_ctx_sp) {
|
|
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
|
|
if (reg_set == nullptr)
|
|
m_reg_ctx_sp.reset();
|
|
else if (m_reg_set != reg_set) {
|
|
SetValueDidChange(true);
|
|
m_name.SetCString(reg_set->name);
|
|
}
|
|
}
|
|
}
|
|
if (m_reg_ctx_sp) {
|
|
SetValueIsValid(true);
|
|
} else {
|
|
SetValueIsValid(false);
|
|
m_error.SetErrorToGenericError();
|
|
m_children.Clear();
|
|
}
|
|
return m_error.Success();
|
|
}
|
|
|
|
ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
|
|
size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
|
|
ValueObject *valobj = nullptr;
|
|
if (m_reg_ctx_sp && m_reg_set) {
|
|
const size_t num_children = GetNumChildren();
|
|
if (idx < num_children)
|
|
valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
|
|
m_reg_set->registers[idx]);
|
|
}
|
|
return valobj;
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectRegisterSet::GetChildMemberWithName(ConstString name,
|
|
bool can_create) {
|
|
ValueObject *valobj = nullptr;
|
|
if (m_reg_ctx_sp && m_reg_set) {
|
|
const RegisterInfo *reg_info =
|
|
m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
|
|
if (reg_info != nullptr)
|
|
valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
|
|
reg_info->kinds[eRegisterKindLLDB]);
|
|
}
|
|
if (valobj)
|
|
return valobj->GetSP();
|
|
else
|
|
return ValueObjectSP();
|
|
}
|
|
|
|
size_t
|
|
ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) {
|
|
if (m_reg_ctx_sp && m_reg_set) {
|
|
const RegisterInfo *reg_info =
|
|
m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
|
|
if (reg_info != nullptr)
|
|
return reg_info->kinds[eRegisterKindLLDB];
|
|
}
|
|
return UINT32_MAX;
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark ValueObjectRegister
|
|
|
|
void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
|
|
const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
|
|
if (reg_info) {
|
|
m_reg_info = *reg_info;
|
|
if (reg_info->name)
|
|
m_name.SetCString(reg_info->name);
|
|
else if (reg_info->alt_name)
|
|
m_name.SetCString(reg_info->alt_name);
|
|
}
|
|
}
|
|
|
|
ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
|
|
lldb::RegisterContextSP ®_ctx_sp,
|
|
uint32_t reg_num)
|
|
: ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
|
|
m_reg_value(), m_type_name(), m_compiler_type() {
|
|
assert(reg_ctx_sp.get());
|
|
ConstructObject(reg_num);
|
|
}
|
|
|
|
ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
|
|
lldb::RegisterContextSP ®_ctx_sp,
|
|
uint32_t reg_num) {
|
|
return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
|
|
}
|
|
|
|
ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
|
|
lldb::RegisterContextSP ®_ctx,
|
|
uint32_t reg_num)
|
|
: ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
|
|
m_reg_value(), m_type_name(), m_compiler_type() {
|
|
assert(reg_ctx);
|
|
ConstructObject(reg_num);
|
|
}
|
|
|
|
ValueObjectRegister::~ValueObjectRegister() {}
|
|
|
|
CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
|
|
if (!m_compiler_type.IsValid()) {
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
Target *target = exe_ctx.GetTargetPtr();
|
|
if (target) {
|
|
Module *exe_module = target->GetExecutableModulePointer();
|
|
if (exe_module) {
|
|
TypeSystem *type_system =
|
|
exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
|
|
if (type_system)
|
|
m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
|
|
m_reg_info.encoding, m_reg_info.byte_size * 8);
|
|
}
|
|
}
|
|
}
|
|
return m_compiler_type;
|
|
}
|
|
|
|
ConstString ValueObjectRegister::GetTypeName() {
|
|
if (m_type_name.IsEmpty())
|
|
m_type_name = GetCompilerType().GetConstTypeName();
|
|
return m_type_name;
|
|
}
|
|
|
|
size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
|
|
return children_count <= max ? children_count : max;
|
|
}
|
|
|
|
uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
|
|
|
|
bool ValueObjectRegister::UpdateValue() {
|
|
m_error.Clear();
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
if (frame == nullptr) {
|
|
m_reg_ctx_sp.reset();
|
|
m_reg_value.Clear();
|
|
}
|
|
|
|
if (m_reg_ctx_sp) {
|
|
RegisterValue m_old_reg_value(m_reg_value);
|
|
if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
|
|
if (m_reg_value.GetData(m_data)) {
|
|
Process *process = exe_ctx.GetProcessPtr();
|
|
if (process)
|
|
m_data.SetAddressByteSize(process->GetAddressByteSize());
|
|
m_value.SetContext(Value::eContextTypeRegisterInfo,
|
|
(void *)&m_reg_info);
|
|
m_value.SetValueType(Value::eValueTypeHostAddress);
|
|
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
|
|
SetValueIsValid(true);
|
|
SetValueDidChange(!(m_old_reg_value == m_reg_value));
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetValueIsValid(false);
|
|
m_error.SetErrorToGenericError();
|
|
return false;
|
|
}
|
|
|
|
bool ValueObjectRegister::SetValueFromCString(const char *value_str,
|
|
Status &error) {
|
|
// The new value will be in the m_data. Copy that into our register value.
|
|
error =
|
|
m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
|
|
if (error.Success()) {
|
|
if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
|
|
SetNeedsUpdate();
|
|
return true;
|
|
} else
|
|
return false;
|
|
} else
|
|
return false;
|
|
}
|
|
|
|
bool ValueObjectRegister::SetData(DataExtractor &data, Status &error) {
|
|
error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
|
|
if (error.Success()) {
|
|
if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
|
|
SetNeedsUpdate();
|
|
return true;
|
|
} else
|
|
return false;
|
|
} else
|
|
return false;
|
|
}
|
|
|
|
bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
|
|
if (UpdateValueIfNeeded(
|
|
false)) // make sure that you are up to date before returning anything
|
|
return m_reg_value.GetScalarValue(scalar);
|
|
return false;
|
|
}
|
|
|
|
void ValueObjectRegister::GetExpressionPath(Stream &s,
|
|
bool qualify_cxx_base_classes,
|
|
GetExpressionPathFormat epformat) {
|
|
s.Printf("$%s", m_reg_info.name);
|
|
}
|