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 "Plugins/Process/Utility/DynamicRegisterInfo.h"
25 
26 #include "GDBRemoteCommunicationClient.h"
27 
28 class StringExtractor;
29 
30 namespace lldb_private {
31 namespace process_gdb_remote {
32 
33 class ThreadGDBRemote;
34 class ProcessGDBRemote;
35 
36 class GDBRemoteDynamicRegisterInfo :
37     public DynamicRegisterInfo
38 {
39 public:
40     GDBRemoteDynamicRegisterInfo () :
41         DynamicRegisterInfo()
42     {
43     }
44 
45     ~GDBRemoteDynamicRegisterInfo() override = default;
46 
47     void
48     HardcodeARMRegisters(bool from_scratch);
49 };
50 
51 class GDBRemoteRegisterContext : public RegisterContext
52 {
53 public:
54     GDBRemoteRegisterContext (ThreadGDBRemote &thread,
55                               uint32_t concrete_frame_idx,
56                               GDBRemoteDynamicRegisterInfo &reg_info,
57                               bool read_all_at_once);
58 
59     ~GDBRemoteRegisterContext() override;
60 
61     void
62     InvalidateAllRegisters () override;
63 
64     size_t
65     GetRegisterCount () override;
66 
67     const RegisterInfo *
68     GetRegisterInfoAtIndex (size_t reg) override;
69 
70     size_t
71     GetRegisterSetCount () override;
72 
73     const RegisterSet *
74     GetRegisterSet (size_t reg_set) override;
75 
76     bool
77     ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) override;
78 
79     bool
80     WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) override;
81 
82     bool
83     ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
84 
85     bool
86     WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
87 
88     bool
89     ReadAllRegisterValues (RegisterCheckpoint &reg_checkpoint) override;
90 
91     bool
92     WriteAllRegisterValues (const RegisterCheckpoint &reg_checkpoint) override;
93 
94     uint32_t
95     ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) override;
96 
97 protected:
98     friend class ThreadGDBRemote;
99 
100     bool
101     ReadRegisterBytes (const RegisterInfo *reg_info,
102                        DataExtractor &data);
103 
104     bool
105     WriteRegisterBytes (const RegisterInfo *reg_info,
106                         DataExtractor &data,
107                         uint32_t data_offset);
108 
109     bool
110     PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
111 
112     bool
113     PrivateSetRegisterValue (uint32_t reg, uint64_t val);
114 
115     void
116     SetAllRegisterValid (bool b);
117 
118     bool
119     GetRegisterIsValid (uint32_t reg) const
120     {
121 #if defined (LLDB_CONFIGURATION_DEBUG)
122         assert (reg < m_reg_valid.size());
123 #endif
124         if (reg < m_reg_valid.size())
125             return m_reg_valid[reg];
126         return false;
127     }
128 
129     void
130     SetRegisterIsValid (const RegisterInfo *reg_info, bool valid)
131     {
132         if (reg_info)
133             return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
134     }
135 
136     void
137     SetRegisterIsValid (uint32_t reg, bool valid)
138     {
139 #if defined (LLDB_CONFIGURATION_DEBUG)
140         assert (reg < m_reg_valid.size());
141 #endif
142         if (reg < m_reg_valid.size())
143             m_reg_valid[reg] = valid;
144     }
145 
146     void
147     SyncThreadState(Process *process);  // Assumes the sequence mutex has already been acquired.
148 
149     GDBRemoteDynamicRegisterInfo &m_reg_info;
150     std::vector<bool> m_reg_valid;
151     DataExtractor m_reg_data;
152     bool m_read_all_at_once;
153 
154 private:
155     // Helper function for ReadRegisterBytes().
156     bool GetPrimordialRegister(const RegisterInfo *reg_info,
157                                GDBRemoteCommunicationClient &gdb_comm);
158     // Helper function for WriteRegisterBytes().
159     bool SetPrimordialRegister(const RegisterInfo *reg_info,
160                                GDBRemoteCommunicationClient &gdb_comm);
161 
162     DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
163 };
164 
165 } // namespace process_gdb_remote
166 } // namespace lldb_private
167 
168 #endif // lldb_GDBRemoteRegisterContext_h_
169