• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //----------------------------------------------------------------------
RegisterContextMemory(Thread & thread,uint32_t concrete_frame_idx,DynamicRegisterInfo & reg_infos,addr_t reg_data_addr)29 RegisterContextMemory::RegisterContextMemory
30 (
31     Thread &thread,
32     uint32_t concrete_frame_idx,
33     DynamicRegisterInfo &reg_infos,
34     addr_t reg_data_addr
35 ) :
36     RegisterContext (thread, concrete_frame_idx),
37     m_reg_infos (reg_infos),
38     m_reg_valid (),
39     m_reg_data (),
40     m_reg_data_addr (reg_data_addr)
41 {
42     // Resize our vector of bools to contain one bool for every register.
43     // We will use these boolean values to know when a register value
44     // is valid in m_reg_data.
45     const size_t num_regs = reg_infos.GetNumRegisters();
46     assert (num_regs > 0);
47     m_reg_valid.resize (num_regs);
48 
49     // Make a heap based buffer that is big enough to store all registers
50     DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0));
51     m_reg_data.SetData (reg_data_sp);
52 }
53 
54 //----------------------------------------------------------------------
55 // Destructor
56 //----------------------------------------------------------------------
~RegisterContextMemory()57 RegisterContextMemory::~RegisterContextMemory()
58 {
59 }
60 
61 void
InvalidateAllRegisters()62 RegisterContextMemory::InvalidateAllRegisters ()
63 {
64     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
65         SetAllRegisterValid (false);
66 }
67 
68 void
SetAllRegisterValid(bool b)69 RegisterContextMemory::SetAllRegisterValid (bool b)
70 {
71     std::vector<bool>::iterator pos, end = m_reg_valid.end();
72     for (pos = m_reg_valid.begin(); pos != end; ++pos)
73         *pos = b;
74 }
75 
76 size_t
GetRegisterCount()77 RegisterContextMemory::GetRegisterCount ()
78 {
79     return m_reg_infos.GetNumRegisters ();
80 }
81 
82 const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)83 RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
84 {
85     return m_reg_infos.GetRegisterInfoAtIndex (reg);
86 }
87 
88 size_t
GetRegisterSetCount()89 RegisterContextMemory::GetRegisterSetCount ()
90 {
91     return m_reg_infos.GetNumRegisterSets ();
92 }
93 
94 const RegisterSet *
GetRegisterSet(size_t reg_set)95 RegisterContextMemory::GetRegisterSet (size_t reg_set)
96 {
97     return m_reg_infos.GetRegisterSet (reg_set);
98 }
99 
100 uint32_t
ConvertRegisterKindToRegisterNumber(uint32_t kind,uint32_t num)101 RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
102 {
103     return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num);
104 }
105 
106 bool
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)107 RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
108 {
109     const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
110     if (!m_reg_valid[reg_num])
111     {
112         if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ()))
113             return false;
114     }
115     const bool partial_data_ok = false;
116     return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success();
117 }
118 
119 bool
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & reg_value)120 RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
121 {
122     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
123     {
124         const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
125         addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
126         Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value));
127         m_reg_valid[reg_num] = false;
128         return error.Success();
129     }
130     return false;
131 }
132 
133 bool
ReadAllRegisterValues(DataBufferSP & data_sp)134 RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp)
135 {
136     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
137     {
138         ProcessSP process_sp (CalculateProcess());
139         if (process_sp)
140         {
141             Error error;
142             if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
143             {
144                 SetAllRegisterValid (true);
145                 return true;
146             }
147         }
148     }
149     return false;
150 }
151 
152 bool
WriteAllRegisterValues(const DataBufferSP & data_sp)153 RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
154 {
155     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
156     {
157         ProcessSP process_sp (CalculateProcess());
158         if (process_sp)
159         {
160             Error error;
161             SetAllRegisterValid (false);
162             if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
163                 return true;
164         }
165     }
166     return false;
167 }
168 
169 void
SetAllRegisterData(const lldb::DataBufferSP & data_sp)170 RegisterContextMemory::SetAllRegisterData  (const lldb::DataBufferSP &data_sp)
171 {
172     m_reg_data.SetData(data_sp);
173     SetAllRegisterValid (true);
174 }
175