]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Process/Utility/RegisterContextMemory.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Plugins / Process / Utility / RegisterContextMemory.cpp
1 //===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "RegisterContextMemory.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project 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"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 //----------------------------------------------------------------------
27 // RegisterContextMemory constructor
28 //----------------------------------------------------------------------
29 RegisterContextMemory::RegisterContextMemory(Thread &thread,
30                                              uint32_t concrete_frame_idx,
31                                              DynamicRegisterInfo &reg_infos,
32                                              addr_t reg_data_addr)
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();
39   assert(num_regs > 0);
40   m_reg_valid.resize(num_regs);
41
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);
46 }
47
48 //----------------------------------------------------------------------
49 // Destructor
50 //----------------------------------------------------------------------
51 RegisterContextMemory::~RegisterContextMemory() {}
52
53 void RegisterContextMemory::InvalidateAllRegisters() {
54   if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
55     SetAllRegisterValid(false);
56 }
57
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)
61     *pos = b;
62 }
63
64 size_t RegisterContextMemory::GetRegisterCount() {
65   return m_reg_infos.GetNumRegisters();
66 }
67
68 const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) {
69   return m_reg_infos.GetRegisterInfoAtIndex(reg);
70 }
71
72 size_t RegisterContextMemory::GetRegisterSetCount() {
73   return m_reg_infos.GetNumRegisterSets();
74 }
75
76 const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) {
77   return m_reg_infos.GetRegisterSet(reg_set);
78 }
79
80 uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(
81     lldb::RegisterKind kind, uint32_t num) {
82   return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num);
83 }
84
85 bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info,
86                                          RegisterValue &reg_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()))
90       return false;
91   }
92   const bool partial_data_ok = false;
93   return reg_value
94       .SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset,
95                         partial_data_ok)
96       .Success();
97 }
98
99 bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info,
100                                           const RegisterValue &reg_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();
108   }
109   return false;
110 }
111
112 bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) {
113   if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
114     ProcessSP process_sp(CalculateProcess());
115     if (process_sp) {
116       Error error;
117       if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),
118                                  data_sp->GetByteSize(),
119                                  error) == data_sp->GetByteSize()) {
120         SetAllRegisterValid(true);
121         return true;
122       }
123     }
124   }
125   return false;
126 }
127
128 bool RegisterContextMemory::WriteAllRegisterValues(
129     const DataBufferSP &data_sp) {
130   if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
131     ProcessSP process_sp(CalculateProcess());
132     if (process_sp) {
133       Error error;
134       SetAllRegisterValid(false);
135       if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),
136                                   data_sp->GetByteSize(),
137                                   error) == data_sp->GetByteSize())
138         return true;
139     }
140   }
141   return false;
142 }
143
144 void RegisterContextMemory::SetAllRegisterData(
145     const lldb::DataBufferSP &data_sp) {
146   m_reg_data.SetData(data_sp);
147   SetAllRegisterValid(true);
148 }