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