]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / 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
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 //----------------------------------------------------------------------
57 RegisterContextMemory::~RegisterContextMemory()
58 {
59 }
60
61 void
62 RegisterContextMemory::InvalidateAllRegisters ()
63 {
64     if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
65         SetAllRegisterValid (false);
66 }
67
68 void
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
77 RegisterContextMemory::GetRegisterCount ()
78 {
79     return m_reg_infos.GetNumRegisters ();
80 }
81
82 const RegisterInfo *
83 RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
84 {
85     return m_reg_infos.GetRegisterInfoAtIndex (reg);
86 }
87
88 size_t
89 RegisterContextMemory::GetRegisterSetCount ()
90 {
91     return m_reg_infos.GetNumRegisterSets ();
92 }
93
94 const RegisterSet *
95 RegisterContextMemory::GetRegisterSet (size_t reg_set)
96 {
97     return m_reg_infos.GetRegisterSet (reg_set);
98 }
99
100 uint32_t
101 RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
102 {
103     return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num);
104 }
105
106 bool
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
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
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
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
170 RegisterContextMemory::SetAllRegisterData  (const lldb::DataBufferSP &data_sp)
171 {
172     m_reg_data.SetData(data_sp);
173     SetAllRegisterValid (true);    
174 }