mirror of
https://github.com/intel/llvm.git
synced 2026-01-28 19:43:38 +08:00
Move DynamicRegisterInfo from the internal lldbPluginProcessUtility library to the public lldbTarget library. This is a prerequisite towards ABI plugin changes that are going to pass DynamicRegisterInfo parameters. Differential Revision: https://reviews.llvm.org/D110942
139 lines
4.7 KiB
C++
139 lines
4.7 KiB
C++
//===-- RegisterContextMemory.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 "RegisterContextMemory.h"
|
|
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Thread.h"
|
|
#include "lldb/Utility/DataBufferHeap.h"
|
|
#include "lldb/Utility/RegisterValue.h"
|
|
#include "lldb/Utility/Status.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// RegisterContextMemory constructor
|
|
RegisterContextMemory::RegisterContextMemory(Thread &thread,
|
|
uint32_t concrete_frame_idx,
|
|
DynamicRegisterInfo ®_infos,
|
|
addr_t reg_data_addr)
|
|
: RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos),
|
|
m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) {
|
|
// Resize our vector of bools to contain one bool for every register. We will
|
|
// use these boolean values to know when a register value is valid in
|
|
// m_reg_data.
|
|
const size_t num_regs = reg_infos.GetNumRegisters();
|
|
assert(num_regs > 0);
|
|
m_reg_valid.resize(num_regs);
|
|
|
|
// Make a heap based buffer that is big enough to store all registers
|
|
DataBufferSP reg_data_sp(
|
|
new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0));
|
|
m_reg_data.SetData(reg_data_sp);
|
|
}
|
|
|
|
// Destructor
|
|
RegisterContextMemory::~RegisterContextMemory() = default;
|
|
|
|
void RegisterContextMemory::InvalidateAllRegisters() {
|
|
if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
|
|
SetAllRegisterValid(false);
|
|
}
|
|
|
|
void RegisterContextMemory::SetAllRegisterValid(bool b) {
|
|
std::vector<bool>::iterator pos, end = m_reg_valid.end();
|
|
for (pos = m_reg_valid.begin(); pos != end; ++pos)
|
|
*pos = b;
|
|
}
|
|
|
|
size_t RegisterContextMemory::GetRegisterCount() {
|
|
return m_reg_infos.GetNumRegisters();
|
|
}
|
|
|
|
const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) {
|
|
return m_reg_infos.GetRegisterInfoAtIndex(reg);
|
|
}
|
|
|
|
size_t RegisterContextMemory::GetRegisterSetCount() {
|
|
return m_reg_infos.GetNumRegisterSets();
|
|
}
|
|
|
|
const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) {
|
|
return m_reg_infos.GetRegisterSet(reg_set);
|
|
}
|
|
|
|
uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(
|
|
lldb::RegisterKind kind, uint32_t num) {
|
|
return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num);
|
|
}
|
|
|
|
bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info,
|
|
RegisterValue ®_value) {
|
|
const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
|
|
if (!m_reg_valid[reg_num]) {
|
|
if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer()))
|
|
return false;
|
|
}
|
|
const bool partial_data_ok = false;
|
|
return reg_value
|
|
.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset,
|
|
partial_data_ok)
|
|
.Success();
|
|
}
|
|
|
|
bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info,
|
|
const RegisterValue ®_value) {
|
|
if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
|
|
const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
|
|
addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
|
|
Status error(WriteRegisterValueToMemory(reg_info, reg_addr,
|
|
reg_info->byte_size, reg_value));
|
|
m_reg_valid[reg_num] = false;
|
|
return error.Success();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) {
|
|
if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
|
|
ProcessSP process_sp(CalculateProcess());
|
|
if (process_sp) {
|
|
Status error;
|
|
if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),
|
|
data_sp->GetByteSize(),
|
|
error) == data_sp->GetByteSize()) {
|
|
SetAllRegisterValid(true);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool RegisterContextMemory::WriteAllRegisterValues(
|
|
const DataBufferSP &data_sp) {
|
|
if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
|
|
ProcessSP process_sp(CalculateProcess());
|
|
if (process_sp) {
|
|
Status error;
|
|
SetAllRegisterValid(false);
|
|
if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),
|
|
data_sp->GetByteSize(),
|
|
error) == data_sp->GetByteSize())
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void RegisterContextMemory::SetAllRegisterData(
|
|
const lldb::DataBufferSP &data_sp) {
|
|
m_reg_data.SetData(data_sp);
|
|
SetAllRegisterValid(true);
|
|
}
|