GDBRemoteRegisterContext.h revision f4124deeb9532044a38c0774ced872f2709347da
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
25
26class ThreadGDBRemote;
27class ProcessGDBRemote;
28class StringExtractor;
29
30class GDBRemoteDynamicRegisterInfo
31{
32public:
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 = 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        m_regs.push_back (reg_info);
61        uint32_t set = GetRegisterSetIndexByName (set_name, true);
62        assert (set < m_sets.size());
63        assert (set < m_set_reg_nums.size());
64        assert (set < m_set_names.size());
65        m_set_reg_nums[set].push_back(reg_num);
66        size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
67        if (m_reg_data_byte_size < end_reg_offset)
68            m_reg_data_byte_size = end_reg_offset;
69    }
70
71    void
72    Finalize ()
73    {
74        for (uint32_t set = 0; set < m_sets.size(); ++set)
75        {
76            assert (m_sets.size() == m_set_reg_nums.size());
77            m_sets[set].num_registers = m_set_reg_nums[set].size();
78            m_sets[set].registers = &m_set_reg_nums[set][0];
79        }
80    }
81
82    size_t
83    GetNumRegisters() const
84    {
85        return m_regs.size();
86    }
87
88    size_t
89    GetNumRegisterSets() const
90    {
91        return m_sets.size();
92    }
93
94    size_t
95    GetRegisterDataByteSize() const
96    {
97        return m_reg_data_byte_size;
98    }
99
100    const lldb_private::RegisterInfo *
101    GetRegisterInfoAtIndex (uint32_t i) const
102    {
103        if (i < m_regs.size())
104            return &m_regs[i];
105        return NULL;
106    }
107
108    const lldb_private::RegisterSet *
109    GetRegisterSet (uint32_t i) const
110    {
111        if (i < m_sets.size())
112            return &m_sets[i];
113        return NULL;
114    }
115
116    uint32_t
117    GetRegisterSetIndexByName (lldb_private::ConstString &set_name, bool can_create)
118    {
119        name_collection::iterator pos, end = m_set_names.end();
120        for (pos = m_set_names.begin(); pos != end; ++pos)
121        {
122            if (*pos == set_name)
123                return std::distance (m_set_names.begin(), pos);
124        }
125
126        m_set_names.push_back(set_name);
127        m_set_reg_nums.resize(m_set_reg_nums.size()+1);
128        lldb_private::RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
129        m_sets.push_back (new_set);
130        return m_sets.size() - 1;
131    }
132
133    uint32_t
134    ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
135    {
136        reg_collection::const_iterator pos, end = m_regs.end();
137        for (pos = m_regs.begin(); pos != end; ++pos)
138        {
139            if (pos->kinds[kind] == num)
140                return std::distance (m_regs.begin(), pos);
141        }
142
143        return LLDB_INVALID_REGNUM;
144    }
145    void
146    Clear()
147    {
148        m_regs.clear();
149        m_sets.clear();
150        m_set_reg_nums.clear();
151        m_reg_names.clear();
152        m_reg_alt_names.clear();
153        m_set_names.clear();
154    }
155
156    void
157    HardcodeARMRegisters();
158
159protected:
160    //------------------------------------------------------------------
161    // Classes that inherit from GDBRemoteRegisterContext can see and modify these
162    //------------------------------------------------------------------
163    typedef std::vector <lldb_private::RegisterInfo> reg_collection;
164    typedef std::vector <lldb_private::RegisterSet> set_collection;
165    typedef std::vector <uint32_t> reg_num_collection;
166    typedef std::vector <reg_num_collection> set_reg_num_collection;
167    typedef std::vector <lldb_private::ConstString> name_collection;
168
169    reg_collection m_regs;
170    set_collection m_sets;
171    set_reg_num_collection m_set_reg_nums;
172    name_collection m_reg_names;
173    name_collection m_reg_alt_names;
174    name_collection m_set_names;
175    size_t m_reg_data_byte_size;   // The number of bytes required to store all registers
176};
177
178class GDBRemoteRegisterContext : public lldb_private::RegisterContext
179{
180public:
181    //------------------------------------------------------------------
182    // Constructors and Destructors
183    //------------------------------------------------------------------
184    GDBRemoteRegisterContext (ThreadGDBRemote &thread,
185                              uint32_t concrete_frame_idx,
186                              GDBRemoteDynamicRegisterInfo &reg_info,
187                              bool read_all_at_once);
188
189    virtual
190    ~GDBRemoteRegisterContext ();
191
192    //------------------------------------------------------------------
193    // Subclasses must override these functions
194    //------------------------------------------------------------------
195    virtual void
196    InvalidateAllRegisters ();
197
198    virtual size_t
199    GetRegisterCount ();
200
201    virtual const lldb_private::RegisterInfo *
202    GetRegisterInfoAtIndex (uint32_t reg);
203
204    virtual size_t
205    GetRegisterSetCount ();
206
207    virtual const lldb_private::RegisterSet *
208    GetRegisterSet (uint32_t reg_set);
209
210    virtual bool
211    ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
212
213    virtual bool
214    WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
215
216    virtual bool
217    ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
218
219    virtual bool
220    WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
221
222    virtual uint32_t
223    ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
224
225protected:
226    friend class ThreadGDBRemote;
227
228    bool
229    ReadRegisterBytes (const lldb_private::RegisterInfo *reg_info,
230                       lldb_private::DataExtractor &data);
231
232    bool
233    WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info,
234                        lldb_private::DataExtractor &data,
235                        uint32_t data_offset);
236
237    bool
238    PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
239
240    void
241    SetAllRegisterValid (bool b);
242
243    GDBRemoteDynamicRegisterInfo &m_reg_info;
244    std::vector<bool> m_reg_valid;
245    lldb_private::DataExtractor m_reg_data;
246    bool m_read_all_at_once;
247
248private:
249    //------------------------------------------------------------------
250    // For GDBRemoteRegisterContext only
251    //------------------------------------------------------------------
252    DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
253};
254
255#endif  // lldb_GDBRemoteRegisterContext_h_
256