1 //===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "RegisterContextMemory.h"
14 // Other libraries and framework includes
16 #include "DynamicRegisterInfo.h"
17 #include "lldb/Core/DataBufferHeap.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/RegisterValue.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/Thread.h"
24 using namespace lldb_private;
26 //----------------------------------------------------------------------
27 // RegisterContextMemory constructor
28 //----------------------------------------------------------------------
29 RegisterContextMemory::RegisterContextMemory(Thread &thread,
30 uint32_t concrete_frame_idx,
31 DynamicRegisterInfo ®_infos,
33 : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos),
34 m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) {
35 // Resize our vector of bools to contain one bool for every register.
36 // We will use these boolean values to know when a register value
37 // is valid in m_reg_data.
38 const size_t num_regs = reg_infos.GetNumRegisters();
40 m_reg_valid.resize(num_regs);
42 // Make a heap based buffer that is big enough to store all registers
43 DataBufferSP reg_data_sp(
44 new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0));
45 m_reg_data.SetData(reg_data_sp);
48 //----------------------------------------------------------------------
50 //----------------------------------------------------------------------
51 RegisterContextMemory::~RegisterContextMemory() {}
53 void RegisterContextMemory::InvalidateAllRegisters() {
54 if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
55 SetAllRegisterValid(false);
58 void RegisterContextMemory::SetAllRegisterValid(bool b) {
59 std::vector<bool>::iterator pos, end = m_reg_valid.end();
60 for (pos = m_reg_valid.begin(); pos != end; ++pos)
64 size_t RegisterContextMemory::GetRegisterCount() {
65 return m_reg_infos.GetNumRegisters();
68 const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) {
69 return m_reg_infos.GetRegisterInfoAtIndex(reg);
72 size_t RegisterContextMemory::GetRegisterSetCount() {
73 return m_reg_infos.GetNumRegisterSets();
76 const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) {
77 return m_reg_infos.GetRegisterSet(reg_set);
80 uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(
81 lldb::RegisterKind kind, uint32_t num) {
82 return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num);
85 bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info,
86 RegisterValue ®_value) {
87 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
88 if (!m_reg_valid[reg_num]) {
89 if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer()))
92 const bool partial_data_ok = false;
94 .SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset,
99 bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info,
100 const RegisterValue ®_value) {
101 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
102 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
103 addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
104 Error error(WriteRegisterValueToMemory(reg_info, reg_addr,
105 reg_info->byte_size, reg_value));
106 m_reg_valid[reg_num] = false;
107 return error.Success();
112 bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) {
113 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
114 ProcessSP process_sp(CalculateProcess());
117 if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),
118 data_sp->GetByteSize(),
119 error) == data_sp->GetByteSize()) {
120 SetAllRegisterValid(true);
128 bool RegisterContextMemory::WriteAllRegisterValues(
129 const DataBufferSP &data_sp) {
130 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
131 ProcessSP process_sp(CalculateProcess());
134 SetAllRegisterValid(false);
135 if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),
136 data_sp->GetByteSize(),
137 error) == data_sp->GetByteSize())
144 void RegisterContextMemory::SetAllRegisterData(
145 const lldb::DataBufferSP &data_sp) {
146 m_reg_data.SetData(data_sp);
147 SetAllRegisterValid(true);