1 //===-- GDBRemoteRegisterContext.h ------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef lldb_GDBRemoteRegisterContext_h_
10 #define lldb_GDBRemoteRegisterContext_h_
11 
12 #include <vector>
13 
14 #include "Plugins/Process/Utility/DynamicRegisterInfo.h"
15 #include "lldb/Target/RegisterContext.h"
16 #include "lldb/Utility/ConstString.h"
17 #include "lldb/Utility/DataExtractor.h"
18 #include "lldb/lldb-enumerations.h"
19 #include "lldb/lldb-private.h"
20 
21 #include "GDBRemoteCommunicationClient.h"
22 
23 class StringExtractor;
24 
25 namespace lldb_private {
26 namespace process_gdb_remote {
27 
28 class ThreadGDBRemote;
29 class ProcessGDBRemote;
30 
31 class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
32 public:
33   GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}
34 
35   ~GDBRemoteDynamicRegisterInfo() override = default;
36 
37   void HardcodeARMRegisters(bool from_scratch);
38 };
39 
40 class GDBRemoteRegisterContext : public RegisterContext {
41 public:
42   GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
43                            GDBRemoteDynamicRegisterInfo &reg_info,
44                            bool read_all_at_once);
45 
46   ~GDBRemoteRegisterContext() override;
47 
48   void InvalidateAllRegisters() override;
49 
50   size_t GetRegisterCount() override;
51 
52   const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
53 
54   size_t GetRegisterSetCount() override;
55 
56   const RegisterSet *GetRegisterSet(size_t reg_set) override;
57 
58   bool ReadRegister(const RegisterInfo *reg_info,
59                     RegisterValue &value) override;
60 
61   bool WriteRegister(const RegisterInfo *reg_info,
62                      const RegisterValue &value) override;
63 
64   bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
65 
66   bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
67 
68   bool ReadAllRegisterValues(RegisterCheckpoint &reg_checkpoint) override;
69 
70   bool
71   WriteAllRegisterValues(const RegisterCheckpoint &reg_checkpoint) override;
72 
73   uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
74                                                uint32_t num) override;
75 
76 protected:
77   friend class ThreadGDBRemote;
78 
79   bool ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data);
80 
81   bool WriteRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data,
82                           uint32_t data_offset);
83 
84   bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
85 
86   bool PrivateSetRegisterValue(uint32_t reg, uint64_t val);
87 
88   void SetAllRegisterValid(bool b);
89 
90   bool GetRegisterIsValid(uint32_t reg) const {
91 #if defined(LLDB_CONFIGURATION_DEBUG)
92     assert(reg < m_reg_valid.size());
93 #endif
94     if (reg < m_reg_valid.size())
95       return m_reg_valid[reg];
96     return false;
97   }
98 
99   void SetRegisterIsValid(const RegisterInfo *reg_info, bool valid) {
100     if (reg_info)
101       return SetRegisterIsValid(reg_info->kinds[lldb::eRegisterKindLLDB],
102                                 valid);
103   }
104 
105   void SetRegisterIsValid(uint32_t reg, bool valid) {
106 #if defined(LLDB_CONFIGURATION_DEBUG)
107     assert(reg < m_reg_valid.size());
108 #endif
109     if (reg < m_reg_valid.size())
110       m_reg_valid[reg] = valid;
111   }
112 
113   GDBRemoteDynamicRegisterInfo &m_reg_info;
114   std::vector<bool> m_reg_valid;
115   DataExtractor m_reg_data;
116   bool m_read_all_at_once;
117 
118 private:
119   // Helper function for ReadRegisterBytes().
120   bool GetPrimordialRegister(const RegisterInfo *reg_info,
121                              GDBRemoteCommunicationClient &gdb_comm);
122   // Helper function for WriteRegisterBytes().
123   bool SetPrimordialRegister(const RegisterInfo *reg_info,
124                              GDBRemoteCommunicationClient &gdb_comm);
125 
126   DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext);
127 };
128 
129 } // namespace process_gdb_remote
130 } // namespace lldb_private
131 
132 #endif // lldb_GDBRemoteRegisterContext_h_
133