]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / contrib / llvm / tools / lldb / source / Plugins / Process / gdb-remote / GDBRemoteRegisterContext.h
1 //===-- GDBRemoteRegisterContext.h ------------------------------*- 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 #ifndef lldb_GDBRemoteRegisterContext_h_
11 #define lldb_GDBRemoteRegisterContext_h_
12
13 // C Includes
14 // C++ Includes
15 #include <vector>
16
17 // Other libraries and framework includes
18 // Project 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"
25
26 class ThreadGDBRemote;
27 class ProcessGDBRemote;
28 class StringExtractor;
29
30 class GDBRemoteDynamicRegisterInfo
31 {
32 public:
33     GDBRemoteDynamicRegisterInfo () :
34         m_regs (),
35         m_sets (),
36         m_set_reg_nums (),
37         m_reg_names (),
38         m_reg_alt_names (),
39         m_set_names (),
40         m_reg_data_byte_size (0)
41     {
42     }
43
44     ~GDBRemoteDynamicRegisterInfo ()
45     {
46     }
47
48     void
49     AddRegister (lldb_private::RegisterInfo reg_info, 
50                  lldb_private::ConstString &reg_name, 
51                  lldb_private::ConstString &reg_alt_name, 
52                  lldb_private::ConstString &set_name)
53     {
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);
60         uint32_t i;
61         if (reg_info.value_regs)
62         {
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();
67         }
68         if (reg_info.invalidate_regs)
69         {
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();
74         }
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;
84     }
85
86     void
87     Finalize ()
88     {
89         for (uint32_t set = 0; set < m_sets.size(); ++set)
90         {
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];
94         }
95     }
96
97     size_t
98     GetNumRegisters() const
99     {
100         return m_regs.size();
101     }
102
103     size_t
104     GetNumRegisterSets() const
105     {
106         return m_sets.size();
107     }
108
109     size_t
110     GetRegisterDataByteSize() const
111     {
112         return m_reg_data_byte_size;
113     }
114
115     const lldb_private::RegisterInfo *
116     GetRegisterInfoAtIndex (uint32_t i) const
117     {
118         if (i < m_regs.size())
119             return &m_regs[i];
120         return NULL;
121     }
122
123     const lldb_private::RegisterSet *
124     GetRegisterSet (uint32_t i) const
125     {
126         if (i < m_sets.size())
127             return &m_sets[i];
128         return NULL;
129     }
130
131     uint32_t
132     GetRegisterSetIndexByName (lldb_private::ConstString &set_name)
133     {
134         name_collection::iterator pos, end = m_set_names.end();
135         for (pos = m_set_names.begin(); pos != end; ++pos)
136         {
137             if (*pos == set_name)
138                 return static_cast<uint32_t>(std::distance (m_set_names.begin(), pos));
139         }
140
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);
146     }
147
148     uint32_t
149     ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
150     {
151         reg_collection::const_iterator pos, end = m_regs.end();
152         for (pos = m_regs.begin(); pos != end; ++pos)
153         {
154             if (pos->kinds[kind] == num)
155                 return static_cast<uint32_t>(std::distance (m_regs.begin(), pos));
156         }
157
158         return LLDB_INVALID_REGNUM;
159     }
160     void
161     Clear()
162     {
163         m_regs.clear();
164         m_sets.clear();
165         m_set_reg_nums.clear();
166         m_reg_names.clear();
167         m_reg_alt_names.clear();
168         m_set_names.clear();
169     }
170
171     void
172     HardcodeARMRegisters(bool from_scratch);
173
174 protected:
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;
184
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
194 };
195
196 class GDBRemoteRegisterContext : public lldb_private::RegisterContext
197 {
198 public:
199     //------------------------------------------------------------------
200     // Constructors and Destructors
201     //------------------------------------------------------------------
202     GDBRemoteRegisterContext (ThreadGDBRemote &thread,
203                               uint32_t concrete_frame_idx,
204                               GDBRemoteDynamicRegisterInfo &reg_info,
205                               bool read_all_at_once);
206
207     virtual
208     ~GDBRemoteRegisterContext ();
209
210     //------------------------------------------------------------------
211     // Subclasses must override these functions
212     //------------------------------------------------------------------
213     virtual void
214     InvalidateAllRegisters ();
215
216     virtual size_t
217     GetRegisterCount ();
218
219     virtual const lldb_private::RegisterInfo *
220     GetRegisterInfoAtIndex (size_t reg);
221
222     virtual size_t
223     GetRegisterSetCount ();
224
225     virtual const lldb_private::RegisterSet *
226     GetRegisterSet (size_t reg_set);
227
228     virtual bool
229     ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
230
231     virtual bool
232     WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
233     
234     virtual bool
235     ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
236
237     virtual bool
238     WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
239
240     virtual uint32_t
241     ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
242
243 protected:
244     friend class ThreadGDBRemote;
245
246     bool
247     ReadRegisterBytes (const lldb_private::RegisterInfo *reg_info,
248                        lldb_private::DataExtractor &data);
249
250     bool
251     WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info,
252                         lldb_private::DataExtractor &data, 
253                         uint32_t data_offset);
254
255     bool
256     PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
257     
258     void
259     SetAllRegisterValid (bool b);
260
261     bool
262     GetRegisterIsValid (uint32_t reg) const
263     {
264 #if defined (LLDB_CONFIGURATION_DEBUG)
265         assert (reg < m_reg_valid.size());
266 #endif
267         if (reg < m_reg_valid.size())
268             return m_reg_valid[reg];
269         return false;
270     }
271
272     void
273     SetRegisterIsValid (const lldb_private::RegisterInfo *reg_info, bool valid)
274     {
275         if (reg_info)
276             return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
277     }
278
279     void
280     SetRegisterIsValid (uint32_t reg, bool valid)
281     {
282 #if defined (LLDB_CONFIGURATION_DEBUG)
283         assert (reg < m_reg_valid.size());
284 #endif
285         if (reg < m_reg_valid.size())
286             m_reg_valid[reg] = valid;
287     }
288
289     void
290     SyncThreadState(lldb_private::Process *process);  // Assumes the sequence mutex has already been acquired.
291     
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;
296
297 private:
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);
304
305     //------------------------------------------------------------------
306     // For GDBRemoteRegisterContext only
307     //------------------------------------------------------------------
308     DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
309 };
310
311 #endif  // lldb_GDBRemoteRegisterContext_h_