LLDB mainline
RegisterContextMemory.cpp
Go to the documentation of this file.
1//===-- RegisterContextMemory.cpp -----------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "lldb/Target/Process.h"
12#include "lldb/Target/Thread.h"
15#include "lldb/Utility/Status.h"
16
17using namespace lldb;
18using namespace lldb_private;
19
20// RegisterContextMemory constructor
22 uint32_t concrete_frame_idx,
23 DynamicRegisterInfoSP reg_infos_sp,
24 addr_t reg_data_addr)
25 : RegisterContext(thread, concrete_frame_idx),
26 m_reg_infos_sp(std::move(reg_infos_sp)), m_reg_valid(), m_reg_data(),
27 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
30 // m_reg_data.
31 const size_t num_regs = m_reg_infos_sp->GetNumRegisters();
32 assert(num_regs > 0);
33 m_reg_valid.resize(num_regs);
34
35 // Make a heap based buffer that is big enough to store all registers
36 m_data = std::make_shared<DataBufferHeap>(
37 m_reg_infos_sp->GetRegisterDataByteSize(), 0);
38 m_reg_data.SetData(m_data);
39}
40
41// Destructor
43
48
50 std::vector<bool>::iterator pos, end = m_reg_valid.end();
51 for (pos = m_reg_valid.begin(); pos != end; ++pos)
52 *pos = b;
53}
54
56 return m_reg_infos_sp->GetNumRegisters();
57}
58
60 return m_reg_infos_sp->GetRegisterInfoAtIndex(reg);
61}
62
64 return m_reg_infos_sp->GetNumRegisterSets();
65}
66
68 return m_reg_infos_sp->GetRegisterSet(reg_set);
69}
70
72 lldb::RegisterKind kind, uint32_t num) {
73 return m_reg_infos_sp->ConvertRegisterKindToRegisterNumber(kind, num);
74}
75
77 RegisterValue &reg_value) {
78 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
79 if (!m_reg_valid[reg_num]) {
81 return false;
82 }
83 const bool partial_data_ok = false;
84 return reg_value
85 .SetValueFromData(*reg_info, m_reg_data, reg_info->byte_offset,
86 partial_data_ok)
87 .Success();
88}
89
91 const RegisterValue &reg_value) {
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();
99 }
100 return false;
101}
102
104 WritableDataBufferSP &data_sp) {
106 ProcessSP process_sp(CalculateProcess());
107 if (process_sp) {
109 if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),
110 data_sp->GetByteSize(),
111 error) == data_sp->GetByteSize()) {
113 return true;
114 }
115 }
116 }
117 return false;
118}
119
121 const DataBufferSP &data_sp) {
123 ProcessSP process_sp(CalculateProcess());
124 if (process_sp) {
126 SetAllRegisterValid(false);
127 if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),
128 data_sp->GetByteSize(),
129 error) == data_sp->GetByteSize())
130 return true;
131 }
132 }
133 return false;
134}
135
137 const lldb::DataBufferSP &data_sp) {
138 m_reg_data.SetData(data_sp);
140}
static llvm::raw_ostream & error(Stream &strm)
void SetAllRegisterData(const lldb::DataBufferSP &data_sp)
std::vector< bool > m_reg_valid
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override
bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &reg_value) override
size_t GetRegisterCount() override
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
const lldb_private::RegisterSet * GetRegisterSet(size_t reg_set) override
lldb_private::DataExtractor m_reg_data
void InvalidateAllRegisters() override
lldb::WritableDataBufferSP m_data
size_t GetRegisterSetCount() override
RegisterContextMemory(lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb::DynamicRegisterInfoSP reg_info_sp, lldb::addr_t reg_data_addr)
bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &reg_value) override
lldb::DynamicRegisterInfoSP m_reg_infos_sp
~RegisterContextMemory() override
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
RegisterContext(Thread &thread, uint32_t concrete_frame_idx)
lldb::ProcessSP CalculateProcess() override
virtual Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
An error handling class.
Definition Status.h:118
bool Success() const
Test for success condition.
Definition Status.cpp:303
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::DynamicRegisterInfo > DynamicRegisterInfoSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
RegisterKind
Register numbering types.
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
Registers are grouped into register sets.