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
23class StringExtractor;
24
25namespace lldb_private {
26namespace process_gdb_remote {
27
28class ThreadGDBRemote;
29class ProcessGDBRemote;
30
31class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
32public:
33  GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}
34
35  ~GDBRemoteDynamicRegisterInfo() override = default;
36
37  void HardcodeARMRegisters(bool from_scratch);
38};
39
40class GDBRemoteRegisterContext : public RegisterContext {
41public:
42  GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
43                           GDBRemoteDynamicRegisterInfo &reg_info,
44                           bool read_all_at_once, bool write_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
76protected:
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  bool m_write_all_at_once;
118
119private:
120  // Helper function for ReadRegisterBytes().
121  bool GetPrimordialRegister(const RegisterInfo *reg_info,
122                             GDBRemoteCommunicationClient &gdb_comm);
123  // Helper function for WriteRegisterBytes().
124  bool SetPrimordialRegister(const RegisterInfo *reg_info,
125                             GDBRemoteCommunicationClient &gdb_comm);
126
127  DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext);
128};
129
130} // namespace process_gdb_remote
131} // namespace lldb_private
132
133#endif // lldb_GDBRemoteRegisterContext_h_
134