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