1 //===-- RegisterContextMemory.cpp -----------------------------------------===//
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 "lldb/Target/Process.h"
12 #include "lldb/Target/Thread.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/RegisterValue.h"
15 #include "lldb/Utility/Status.h"
18 using namespace lldb_private
;
20 // RegisterContextMemory constructor
21 RegisterContextMemory::RegisterContextMemory(Thread
&thread
,
22 uint32_t concrete_frame_idx
,
23 DynamicRegisterInfo
®_infos
,
25 : RegisterContext(thread
, concrete_frame_idx
), m_reg_infos(reg_infos
),
26 m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr
) {
27 // Resize our vector of bools to contain one bool for every register. We will
28 // use these boolean values to know when a register value is valid in
30 const size_t num_regs
= reg_infos
.GetNumRegisters();
32 m_reg_valid
.resize(num_regs
);
34 // Make a heap based buffer that is big enough to store all registers
36 std::make_shared
<DataBufferHeap
>(reg_infos
.GetRegisterDataByteSize(), 0);
37 m_reg_data
.SetData(m_data
);
41 RegisterContextMemory::~RegisterContextMemory() = default;
43 void RegisterContextMemory::InvalidateAllRegisters() {
44 if (m_reg_data_addr
!= LLDB_INVALID_ADDRESS
)
45 SetAllRegisterValid(false);
48 void RegisterContextMemory::SetAllRegisterValid(bool b
) {
49 std::vector
<bool>::iterator pos
, end
= m_reg_valid
.end();
50 for (pos
= m_reg_valid
.begin(); pos
!= end
; ++pos
)
54 size_t RegisterContextMemory::GetRegisterCount() {
55 return m_reg_infos
.GetNumRegisters();
58 const RegisterInfo
*RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg
) {
59 return m_reg_infos
.GetRegisterInfoAtIndex(reg
);
62 size_t RegisterContextMemory::GetRegisterSetCount() {
63 return m_reg_infos
.GetNumRegisterSets();
66 const RegisterSet
*RegisterContextMemory::GetRegisterSet(size_t reg_set
) {
67 return m_reg_infos
.GetRegisterSet(reg_set
);
70 uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(
71 lldb::RegisterKind kind
, uint32_t num
) {
72 return m_reg_infos
.ConvertRegisterKindToRegisterNumber(kind
, num
);
75 bool RegisterContextMemory::ReadRegister(const RegisterInfo
*reg_info
,
76 RegisterValue
®_value
) {
77 const uint32_t reg_num
= reg_info
->kinds
[eRegisterKindLLDB
];
78 if (!m_reg_valid
[reg_num
]) {
79 if (!ReadAllRegisterValues(m_data
))
82 const bool partial_data_ok
= false;
84 .SetValueFromData(*reg_info
, m_reg_data
, reg_info
->byte_offset
,
89 bool RegisterContextMemory::WriteRegister(const RegisterInfo
*reg_info
,
90 const RegisterValue
®_value
) {
91 if (m_reg_data_addr
!= LLDB_INVALID_ADDRESS
) {
92 const uint32_t reg_num
= reg_info
->kinds
[eRegisterKindLLDB
];
93 addr_t reg_addr
= m_reg_data_addr
+ reg_info
->byte_offset
;
94 Status
error(WriteRegisterValueToMemory(reg_info
, reg_addr
,
95 reg_info
->byte_size
, reg_value
));
96 m_reg_valid
[reg_num
] = false;
97 return error
.Success();
102 bool RegisterContextMemory::ReadAllRegisterValues(
103 WritableDataBufferSP
&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);