LLDB  mainline
RegisterContextDarwin_arm64.h
Go to the documentation of this file.
1 //===-- RegisterContextDarwin_arm64.h -----------------------------*- C++
2 //-*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_RegisterContextDarwin_arm64_h_
11 #define liblldb_RegisterContextDarwin_arm64_h_
12 
14 #include "lldb/lldb-private.h"
15 
16 // Break only in privileged or user mode
17 #define S_RSVD ((uint32_t)(0u << 1))
18 #define S_PRIV ((uint32_t)(1u << 1))
19 #define S_USER ((uint32_t)(2u << 1))
20 #define S_PRIV_USER ((S_PRIV) | (S_USER))
21 
22 #define WCR_ENABLE ((uint32_t)(1u))
23 
24 // Watchpoint load/store
25 #define WCR_LOAD ((uint32_t)(1u << 3))
26 #define WCR_STORE ((uint32_t)(1u << 4))
27 
29 public:
31  uint32_t concrete_frame_idx);
32 
34 
35  void InvalidateAllRegisters() override;
36 
37  size_t GetRegisterCount() override;
38 
39  const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
40 
41  size_t GetRegisterSetCount() override;
42 
43  const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
44 
45  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
46  lldb_private::RegisterValue &reg_value) override;
47 
48  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
49  const lldb_private::RegisterValue &reg_value) override;
50 
51  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
52 
53  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
54 
56  uint32_t num) override;
57 
59 
60  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
61  bool write) override;
62 
63  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
64 
65  // mirrors <mach/arm/thread_status.h> arm_thread_state64_t
66  struct GPR {
67  uint64_t x[29]; // x0-x28
68  uint64_t fp; // x29
69  uint64_t lr; // x30
70  uint64_t sp; // x31
71  uint64_t pc; // pc
72  uint32_t cpsr; // cpsr
73  };
74 
75  struct VReg {
76  llvm::AlignedCharArray<16, 16> bytes;
77  };
78 
79  // mirrors <mach/arm/thread_status.h> arm_neon_state64_t
80  struct FPU {
81  VReg v[32];
84  };
85 
86  // mirrors <mach/arm/thread_status.h> arm_exception_state64_t
87  struct EXC {
88  uint64_t far; // Virtual Fault Address
89  uint32_t esr; // Exception syndrome
90  uint32_t exception; // number of arm exception token
91  };
92 
93  // mirrors <mach/arm/thread_status.h> arm_debug_state64_t
94  struct DBG {
95  uint64_t bvr[16];
96  uint64_t bcr[16];
97  uint64_t wvr[16];
98  uint64_t wcr[16];
99  uint64_t mdscr_el1;
100  };
101 
102  static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg);
103 
104 protected:
105  enum {
106  GPRRegSet = 6, // ARM_THREAD_STATE64
107  FPURegSet = 17, // ARM_NEON_STATE64
108  EXCRegSet = 7, // ARM_EXCEPTION_STATE64
109  DBGRegSet = 15 // ARM_DEBUG_STATE64
110  };
111 
112  enum {
113  GPRWordCount = sizeof(GPR) / sizeof(uint32_t), // ARM_THREAD_STATE64_COUNT
114  FPUWordCount = sizeof(FPU) / sizeof(uint32_t), // ARM_NEON_STATE64_COUNT
116  sizeof(EXC) / sizeof(uint32_t), // ARM_EXCEPTION_STATE64_COUNT
117  DBGWordCount = sizeof(DBG) / sizeof(uint32_t) // ARM_DEBUG_STATE64_COUNT
118  };
119 
120  enum { Read = 0, Write = 1, kNumErrors = 2 };
121 
126  int gpr_errs[2]; // Read/Write errors
127  int fpu_errs[2]; // Read/Write errors
128  int exc_errs[2]; // Read/Write errors
129  int dbg_errs[2]; // Read/Write errors
130 
132  SetError(GPRRegSet, Read, -1);
133  SetError(FPURegSet, Read, -1);
134  SetError(EXCRegSet, Read, -1);
135  }
136 
137  int GetError(int flavor, uint32_t err_idx) const {
138  if (err_idx < kNumErrors) {
139  switch (flavor) {
140  // When getting all errors, just OR all values together to see if
141  // we got any kind of error.
142  case GPRRegSet:
143  return gpr_errs[err_idx];
144  case FPURegSet:
145  return fpu_errs[err_idx];
146  case EXCRegSet:
147  return exc_errs[err_idx];
148  case DBGRegSet:
149  return dbg_errs[err_idx];
150  default:
151  break;
152  }
153  }
154  return -1;
155  }
156 
157  bool SetError(int flavor, uint32_t err_idx, int err) {
158  if (err_idx < kNumErrors) {
159  switch (flavor) {
160  case GPRRegSet:
161  gpr_errs[err_idx] = err;
162  return true;
163 
164  case FPURegSet:
165  fpu_errs[err_idx] = err;
166  return true;
167 
168  case EXCRegSet:
169  exc_errs[err_idx] = err;
170  return true;
171 
172  case DBGRegSet:
173  exc_errs[err_idx] = err;
174  return true;
175 
176  default:
177  break;
178  }
179  }
180  return false;
181  }
182 
183  bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
184 
185  int ReadGPR(bool force);
186 
187  int ReadFPU(bool force);
188 
189  int ReadEXC(bool force);
190 
191  int ReadDBG(bool force);
192 
193  int WriteGPR();
194 
195  int WriteFPU();
196 
197  int WriteEXC();
198 
199  int WriteDBG();
200 
201  // Subclasses override these to do the actual reading.
202  virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; }
203 
204  virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
205 
206  virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
207 
208  virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0;
209 
210  virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
211 
212  virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
213 
214  virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
215 
216  virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
217 
218  int ReadRegisterSet(uint32_t set, bool force);
219 
220  int WriteRegisterSet(uint32_t set);
221 
222  static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
223 
224  static int GetSetForNativeRegNum(int reg_num);
225 
226  static size_t GetRegisterInfosCount();
227 
228  static const lldb_private::RegisterInfo *GetRegisterInfos();
229 };
230 
231 #endif // liblldb_RegisterContextDarwin_arm64_h_
RegisterContextDarwin_arm64(lldb_private::Thread &thread, uint32_t concrete_frame_idx)
virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc)=0
virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg)=0
virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu)=0
virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc)=0
bool ClearHardwareWatchpoint(uint32_t hw_index) override
int ReadRegisterSet(uint32_t set, bool force)
virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg)=0
bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &reg_value) override
static int GetSetForNativeRegNum(int reg_num)
virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr)
bool SetError(int flavor, uint32_t err_idx, int err)
int GetError(int flavor, uint32_t err_idx) const
const lldb_private::RegisterSet * GetRegisterSet(size_t set) override
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg)
uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override
uint64_t tid_t
Definition: lldb-types.h:86
struct _GPR GPR
llvm::AlignedCharArray< 16, 16 > bytes
virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu)=0
bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &reg_value) override
uint64_t addr_t
Definition: lldb-types.h:83
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr)=0
static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num)
bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override
static const lldb_private::RegisterInfo * GetRegisterInfos()