1 //===-- GDBRemoteRegisterContext.h ------------------------------*- 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 #ifndef lldb_GDBRemoteRegisterContext_h_
11 #define lldb_GDBRemoteRegisterContext_h_
17 // Other libraries and framework includes
19 #include "lldb/lldb-private.h"
20 #include "lldb/lldb-enumerations.h"
21 #include "lldb/Core/ConstString.h"
22 #include "lldb/Core/DataExtractor.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "GDBRemoteCommunicationClient.h"
26 class ThreadGDBRemote;
27 class ProcessGDBRemote;
28 class StringExtractor;
30 class GDBRemoteDynamicRegisterInfo
33 GDBRemoteDynamicRegisterInfo () :
40 m_reg_data_byte_size (0)
44 ~GDBRemoteDynamicRegisterInfo ()
49 AddRegister (lldb_private::RegisterInfo reg_info,
50 lldb_private::ConstString ®_name,
51 lldb_private::ConstString ®_alt_name,
52 lldb_private::ConstString &set_name)
54 const uint32_t reg_num = (uint32_t)m_regs.size();
55 m_reg_names.push_back (reg_name);
56 m_reg_alt_names.push_back (reg_alt_name);
57 reg_info.name = reg_name.AsCString();
58 assert (reg_info.name);
59 reg_info.alt_name = reg_alt_name.AsCString(NULL);
61 if (reg_info.value_regs)
63 for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
64 m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
65 m_value_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
66 reg_info.value_regs = m_value_regs_map[reg_num].data();
68 if (reg_info.invalidate_regs)
70 for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
71 m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
72 m_invalidate_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
73 reg_info.invalidate_regs = m_invalidate_regs_map[reg_num].data();
75 m_regs.push_back (reg_info);
76 uint32_t set = GetRegisterSetIndexByName (set_name);
77 assert (set < m_sets.size());
78 assert (set < m_set_reg_nums.size());
79 assert (set < m_set_names.size());
80 m_set_reg_nums[set].push_back(reg_num);
81 size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
82 if (m_reg_data_byte_size < end_reg_offset)
83 m_reg_data_byte_size = end_reg_offset;
89 for (uint32_t set = 0; set < m_sets.size(); ++set)
91 assert (m_sets.size() == m_set_reg_nums.size());
92 m_sets[set].num_registers = m_set_reg_nums[set].size();
93 m_sets[set].registers = &m_set_reg_nums[set][0];
98 GetNumRegisters() const
100 return m_regs.size();
104 GetNumRegisterSets() const
106 return m_sets.size();
110 GetRegisterDataByteSize() const
112 return m_reg_data_byte_size;
115 const lldb_private::RegisterInfo *
116 GetRegisterInfoAtIndex (uint32_t i) const
118 if (i < m_regs.size())
123 const lldb_private::RegisterSet *
124 GetRegisterSet (uint32_t i) const
126 if (i < m_sets.size())
132 GetRegisterSetIndexByName (lldb_private::ConstString &set_name)
134 name_collection::iterator pos, end = m_set_names.end();
135 for (pos = m_set_names.begin(); pos != end; ++pos)
137 if (*pos == set_name)
138 return static_cast<uint32_t>(std::distance (m_set_names.begin(), pos));
141 m_set_names.push_back(set_name);
142 m_set_reg_nums.resize(m_set_reg_nums.size()+1);
143 lldb_private::RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
144 m_sets.push_back (new_set);
145 return static_cast<uint32_t>(m_sets.size() - 1);
149 ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
151 reg_collection::const_iterator pos, end = m_regs.end();
152 for (pos = m_regs.begin(); pos != end; ++pos)
154 if (pos->kinds[kind] == num)
155 return static_cast<uint32_t>(std::distance (m_regs.begin(), pos));
158 return LLDB_INVALID_REGNUM;
165 m_set_reg_nums.clear();
167 m_reg_alt_names.clear();
172 HardcodeARMRegisters(bool from_scratch);
175 //------------------------------------------------------------------
176 // Classes that inherit from GDBRemoteRegisterContext can see and modify these
177 //------------------------------------------------------------------
178 typedef std::vector <lldb_private::RegisterInfo> reg_collection;
179 typedef std::vector <lldb_private::RegisterSet> set_collection;
180 typedef std::vector <uint32_t> reg_num_collection;
181 typedef std::vector <reg_num_collection> set_reg_num_collection;
182 typedef std::vector <lldb_private::ConstString> name_collection;
183 typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
185 reg_collection m_regs;
186 set_collection m_sets;
187 set_reg_num_collection m_set_reg_nums;
188 name_collection m_reg_names;
189 name_collection m_reg_alt_names;
190 name_collection m_set_names;
191 reg_to_regs_map m_value_regs_map;
192 reg_to_regs_map m_invalidate_regs_map;
193 size_t m_reg_data_byte_size; // The number of bytes required to store all registers
196 class GDBRemoteRegisterContext : public lldb_private::RegisterContext
199 //------------------------------------------------------------------
200 // Constructors and Destructors
201 //------------------------------------------------------------------
202 GDBRemoteRegisterContext (ThreadGDBRemote &thread,
203 uint32_t concrete_frame_idx,
204 GDBRemoteDynamicRegisterInfo ®_info,
205 bool read_all_at_once);
208 ~GDBRemoteRegisterContext ();
210 //------------------------------------------------------------------
211 // Subclasses must override these functions
212 //------------------------------------------------------------------
214 InvalidateAllRegisters ();
219 virtual const lldb_private::RegisterInfo *
220 GetRegisterInfoAtIndex (size_t reg);
223 GetRegisterSetCount ();
225 virtual const lldb_private::RegisterSet *
226 GetRegisterSet (size_t reg_set);
229 ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
232 WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
235 ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
238 WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
241 ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
244 friend class ThreadGDBRemote;
247 ReadRegisterBytes (const lldb_private::RegisterInfo *reg_info,
248 lldb_private::DataExtractor &data);
251 WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info,
252 lldb_private::DataExtractor &data,
253 uint32_t data_offset);
256 PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
259 SetAllRegisterValid (bool b);
262 GetRegisterIsValid (uint32_t reg) const
264 #if defined (LLDB_CONFIGURATION_DEBUG)
265 assert (reg < m_reg_valid.size());
267 if (reg < m_reg_valid.size())
268 return m_reg_valid[reg];
273 SetRegisterIsValid (const lldb_private::RegisterInfo *reg_info, bool valid)
276 return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
280 SetRegisterIsValid (uint32_t reg, bool valid)
282 #if defined (LLDB_CONFIGURATION_DEBUG)
283 assert (reg < m_reg_valid.size());
285 if (reg < m_reg_valid.size())
286 m_reg_valid[reg] = valid;
290 SyncThreadState(lldb_private::Process *process); // Assumes the sequence mutex has already been acquired.
292 GDBRemoteDynamicRegisterInfo &m_reg_info;
293 std::vector<bool> m_reg_valid;
294 lldb_private::DataExtractor m_reg_data;
295 bool m_read_all_at_once;
298 // Helper function for ReadRegisterBytes().
299 bool GetPrimordialRegister(const lldb_private::RegisterInfo *reg_info,
300 GDBRemoteCommunicationClient &gdb_comm);
301 // Helper function for WriteRegisterBytes().
302 bool SetPrimordialRegister(const lldb_private::RegisterInfo *reg_info,
303 GDBRemoteCommunicationClient &gdb_comm);
305 //------------------------------------------------------------------
306 // For GDBRemoteRegisterContext only
307 //------------------------------------------------------------------
308 DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
311 #endif // lldb_GDBRemoteRegisterContext_h_