1 //===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "RegisterContextMemory.h"
11 #include "DynamicRegisterInfo.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Utility/DataBufferHeap.h"
15 #include "lldb/Utility/RegisterValue.h"
16 #include "lldb/Utility/Status.h"
19 using namespace lldb_private;
21 // RegisterContextMemory constructor
22 RegisterContextMemory::RegisterContextMemory(Thread &thread,
23 uint32_t concrete_frame_idx,
24 DynamicRegisterInfo ®_infos,
26 : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos),
27 m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) {
28 // Resize our vector of bools to contain one bool for every register. We will
29 // use these boolean values to know when a register value is valid in
31 const size_t num_regs = reg_infos.GetNumRegisters();
33 m_reg_valid.resize(num_regs);
35 // Make a heap based buffer that is big enough to store all registers
36 DataBufferSP reg_data_sp(
37 new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0));
38 m_reg_data.SetData(reg_data_sp);
42 RegisterContextMemory::~RegisterContextMemory() {}
44 void RegisterContextMemory::InvalidateAllRegisters() {
45 if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
46 SetAllRegisterValid(false);
49 void RegisterContextMemory::SetAllRegisterValid(bool b) {
50 std::vector<bool>::iterator pos, end = m_reg_valid.end();
51 for (pos = m_reg_valid.begin(); pos != end; ++pos)
55 size_t RegisterContextMemory::GetRegisterCount() {
56 return m_reg_infos.GetNumRegisters();
59 const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) {
60 return m_reg_infos.GetRegisterInfoAtIndex(reg);
63 size_t RegisterContextMemory::GetRegisterSetCount() {
64 return m_reg_infos.GetNumRegisterSets();
67 const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) {
68 return m_reg_infos.GetRegisterSet(reg_set);
71 uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(
72 lldb::RegisterKind kind, uint32_t num) {
73 return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num);
76 bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info,
77 RegisterValue ®_value) {
78 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
79 if (!m_reg_valid[reg_num]) {
80 if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer()))
83 const bool partial_data_ok = false;
85 .SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset,
90 bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info,
91 const RegisterValue ®_value) {
92 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
93 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
94 addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
95 Status error(WriteRegisterValueToMemory(reg_info, reg_addr,
96 reg_info->byte_size, reg_value));
97 m_reg_valid[reg_num] = false;
98 return error.Success();
103 bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) {
104 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
105 ProcessSP process_sp(CalculateProcess());
108 if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),
109 data_sp->GetByteSize(),
110 error) == data_sp->GetByteSize()) {
111 SetAllRegisterValid(true);
119 bool RegisterContextMemory::WriteAllRegisterValues(
120 const DataBufferSP &data_sp) {
121 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
122 ProcessSP process_sp(CalculateProcess());
125 SetAllRegisterValid(false);
126 if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),
127 data_sp->GetByteSize(),
128 error) == data_sp->GetByteSize())
135 void RegisterContextMemory::SetAllRegisterData(
136 const lldb::DataBufferSP &data_sp) {
137 m_reg_data.SetData(data_sp);
138 SetAllRegisterValid(true);