]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
Merge ^/head r294169 through r294598.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / RegisterContextDarwin_arm64.cpp
1 //===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #if defined(__APPLE__)
11
12 #include "RegisterContextDarwin_arm64.h"
13
14 // C Includes
15 #include <mach/mach_types.h>
16 #include <mach/thread_act.h>
17 #include <sys/sysctl.h>
18
19 // C++ Includes
20 // Other libraries and framework includes
21 #include "lldb/Core/DataBufferHeap.h"
22 #include "lldb/Core/DataExtractor.h"
23 #include "lldb/Core/Log.h"
24 #include "lldb/Core/RegisterValue.h"
25 #include "lldb/Core/Scalar.h"
26 #include "lldb/Host/Endian.h"
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/Compiler.h"
29
30 #include "Plugins/Process/Utility/InstructionUtils.h"
31
32 // Support building against older versions of LLVM, this macro was added
33 // recently.
34 #ifndef LLVM_EXTENSION
35 #define LLVM_EXTENSION
36 #endif
37
38 // Project includes
39 #include "ARM64_DWARF_Registers.h"
40
41 using namespace lldb;
42 using namespace lldb_private;
43
44
45 #define GPR_OFFSET(idx) ((idx) * 8)
46 #define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::GPR, reg))
47
48 #define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextDarwin_arm64::GPR))
49 #define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::FPU, reg))
50
51 #define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::EXC, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU))
52 #define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::DBG, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
53
54 #define DEFINE_DBG(reg, i)  #reg, NULL, sizeof(((RegisterContextDarwin_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL
55 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
56
57 //-----------------------------------------------------------------------------
58 // Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
59 //-----------------------------------------------------------------------------
60 #define DECLARE_REGISTER_INFOS_ARM64_STRUCT
61 #include "RegisterInfos_arm64.h"
62 #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
63
64 // General purpose registers
65 static uint32_t
66 g_gpr_regnums[] =
67 {
68     gpr_x0,
69     gpr_x1,
70     gpr_x2,
71     gpr_x3,
72     gpr_x4,
73     gpr_x5,
74     gpr_x6,
75     gpr_x7,
76     gpr_x8,
77     gpr_x9,
78     gpr_x10,
79     gpr_x11,
80     gpr_x12,
81     gpr_x13,
82     gpr_x14,
83     gpr_x15,
84     gpr_x16,
85     gpr_x17,
86     gpr_x18,
87     gpr_x19,
88     gpr_x20,
89     gpr_x21,
90     gpr_x22,
91     gpr_x23,
92     gpr_x24,
93     gpr_x25,
94     gpr_x26,
95     gpr_x27,
96     gpr_x28,
97     gpr_fp,
98     gpr_lr,
99     gpr_sp,
100     gpr_pc,
101     gpr_cpsr
102 };
103
104 // Floating point registers
105 static uint32_t
106 g_fpu_regnums[] =
107 {
108     fpu_v0,
109     fpu_v1,
110     fpu_v2,
111     fpu_v3,
112     fpu_v4,
113     fpu_v5,
114     fpu_v6,
115     fpu_v7,
116     fpu_v8,
117     fpu_v9,
118     fpu_v10,
119     fpu_v11,
120     fpu_v12,
121     fpu_v13,
122     fpu_v14,
123     fpu_v15,
124     fpu_v16,
125     fpu_v17,
126     fpu_v18,
127     fpu_v19,
128     fpu_v20,
129     fpu_v21,
130     fpu_v22,
131     fpu_v23,
132     fpu_v24,
133     fpu_v25,
134     fpu_v26,
135     fpu_v27,
136     fpu_v28,
137     fpu_v29,
138     fpu_v30,
139     fpu_v31,
140     fpu_fpsr,
141     fpu_fpcr
142 };
143
144 // Exception registers
145
146 static uint32_t
147 g_exc_regnums[] =
148 {
149     exc_far,
150     exc_esr,
151     exc_exception
152 };
153
154 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos_arm64);
155
156 RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(Thread &thread, uint32_t concrete_frame_idx) :
157     RegisterContext(thread, concrete_frame_idx),
158     gpr(),
159     fpu(),
160     exc()
161 {
162     uint32_t i;
163     for (i=0; i<kNumErrors; i++)
164     {
165         gpr_errs[i] = -1;
166         fpu_errs[i] = -1;
167         exc_errs[i] = -1;
168     }
169 }
170
171 RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64()
172 {
173 }
174
175
176 void
177 RegisterContextDarwin_arm64::InvalidateAllRegisters ()
178 {
179     InvalidateAllRegisterStates();
180 }
181
182
183 size_t
184 RegisterContextDarwin_arm64::GetRegisterCount ()
185 {
186     assert(k_num_register_infos == k_num_registers);
187     return k_num_registers;
188 }
189
190 const RegisterInfo *
191 RegisterContextDarwin_arm64::GetRegisterInfoAtIndex (size_t reg)
192 {
193     assert(k_num_register_infos == k_num_registers);
194     if (reg < k_num_registers)
195         return &g_register_infos_arm64[reg];
196     return NULL;
197 }
198
199 size_t
200 RegisterContextDarwin_arm64::GetRegisterInfosCount ()
201 {
202     return k_num_register_infos;
203 }
204
205 const RegisterInfo *
206 RegisterContextDarwin_arm64::GetRegisterInfos ()
207 {
208     return g_register_infos_arm64;
209 }
210
211
212 // Number of registers in each register set
213 const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
214 const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
215 const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
216
217 //----------------------------------------------------------------------
218 // Register set definitions. The first definitions at register set index
219 // of zero is for all registers, followed by other registers sets. The
220 // register information for the all register set need not be filled in.
221 //----------------------------------------------------------------------
222 static const RegisterSet g_reg_sets[] =
223 {
224     { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
225     { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
226     { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
227 };
228
229 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
230
231
232 size_t
233 RegisterContextDarwin_arm64::GetRegisterSetCount ()
234 {
235     return k_num_regsets;
236 }
237
238 const RegisterSet *
239 RegisterContextDarwin_arm64::GetRegisterSet (size_t reg_set)
240 {
241     if (reg_set < k_num_regsets)
242         return &g_reg_sets[reg_set];
243     return NULL;
244 }
245
246
247 //----------------------------------------------------------------------
248 // Register information definitions for arm64
249 //----------------------------------------------------------------------
250 int
251 RegisterContextDarwin_arm64::GetSetForNativeRegNum (int reg)
252 {
253     if (reg < fpu_v0)
254         return GPRRegSet;
255     else if (reg < exc_far)
256         return FPURegSet;
257     else if (reg < k_num_registers)
258         return EXCRegSet;
259     return -1;
260 }
261
262 int
263 RegisterContextDarwin_arm64::ReadGPR (bool force)
264 {
265     int set = GPRRegSet;
266     if (force || !RegisterSetIsCached(set))
267     {
268         SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
269     }
270     return GetError(GPRRegSet, Read);
271 }
272
273 int
274 RegisterContextDarwin_arm64::ReadFPU (bool force)
275 {
276     int set = FPURegSet;
277     if (force || !RegisterSetIsCached(set))
278     {
279         SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
280     }
281     return GetError(FPURegSet, Read);
282 }
283
284 int
285 RegisterContextDarwin_arm64::ReadEXC (bool force)
286 {
287     int set = EXCRegSet;
288     if (force || !RegisterSetIsCached(set))
289     {
290         SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
291     }
292     return GetError(EXCRegSet, Read);
293 }
294
295 int
296 RegisterContextDarwin_arm64::ReadDBG (bool force)
297 {
298     int set = DBGRegSet;
299     if (force || !RegisterSetIsCached(set))
300     {
301         SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
302     }
303     return GetError(DBGRegSet, Read);
304 }
305
306 int
307 RegisterContextDarwin_arm64::WriteGPR ()
308 {
309     int set = GPRRegSet;
310     if (!RegisterSetIsCached(set))
311     {
312         SetError (set, Write, -1);
313         return KERN_INVALID_ARGUMENT;
314     }
315     SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
316     SetError (set, Read, -1);
317     return GetError(GPRRegSet, Write);
318 }
319
320 int
321 RegisterContextDarwin_arm64::WriteFPU ()
322 {
323     int set = FPURegSet;
324     if (!RegisterSetIsCached(set))
325     {
326         SetError (set, Write, -1);
327         return KERN_INVALID_ARGUMENT;
328     }
329     SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
330     SetError (set, Read, -1);
331     return GetError(FPURegSet, Write);
332 }
333
334 int
335 RegisterContextDarwin_arm64::WriteEXC ()
336 {
337     int set = EXCRegSet;
338     if (!RegisterSetIsCached(set))
339     {
340         SetError (set, Write, -1);
341         return KERN_INVALID_ARGUMENT;
342     }
343     SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
344     SetError (set, Read, -1);
345     return GetError(EXCRegSet, Write);
346 }
347
348 int
349 RegisterContextDarwin_arm64::WriteDBG ()
350 {
351     int set = DBGRegSet;
352     if (!RegisterSetIsCached(set))
353     {
354         SetError (set, Write, -1);
355         return KERN_INVALID_ARGUMENT;
356     }
357     SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
358     SetError (set, Read, -1);
359     return GetError(DBGRegSet, Write);
360 }
361
362
363 int
364 RegisterContextDarwin_arm64::ReadRegisterSet (uint32_t set, bool force)
365 {
366     switch (set)
367     {
368     case GPRRegSet:    return ReadGPR(force);
369     case FPURegSet:    return ReadFPU(force);
370     case EXCRegSet:    return ReadEXC(force);
371     case DBGRegSet:    return ReadDBG(force);
372     default: break;
373     }
374     return KERN_INVALID_ARGUMENT;
375 }
376
377 int
378 RegisterContextDarwin_arm64::WriteRegisterSet (uint32_t set)
379 {
380     // Make sure we have a valid context to set.
381     if (RegisterSetIsCached(set))
382     {
383         switch (set)
384         {
385         case GPRRegSet:    return WriteGPR();
386         case FPURegSet:    return WriteFPU();
387         case EXCRegSet:    return WriteEXC();
388         case DBGRegSet:    return WriteDBG();
389         default: break;
390         }
391     }
392     return KERN_INVALID_ARGUMENT;
393 }
394
395 void
396 RegisterContextDarwin_arm64::LogDBGRegisters (Log *log, const DBG& dbg)
397 {
398     if (log)
399     {
400         for (uint32_t i=0; i<16; i++)
401             log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u = { 0x%8.8llx, 0x%8.8llx }",
402                 i, i, dbg.bvr[i], dbg.bcr[i],
403                 i, i, dbg.wvr[i], dbg.wcr[i]);
404     }
405 }
406
407
408 bool
409 RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
410 {
411     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
412     int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum (reg);
413
414     if (set == -1)
415         return false;
416
417     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
418         return false;
419
420     switch (reg)
421     {
422     case gpr_x0:
423     case gpr_x1:
424     case gpr_x2:
425     case gpr_x3:
426     case gpr_x4:
427     case gpr_x5:
428     case gpr_x6:
429     case gpr_x7:
430     case gpr_x8:
431     case gpr_x9:
432     case gpr_x10:
433     case gpr_x11:
434     case gpr_x12:
435     case gpr_x13:
436     case gpr_x14:
437     case gpr_x15:
438     case gpr_x16:
439     case gpr_x17:
440     case gpr_x18:
441     case gpr_x19:
442     case gpr_x20:
443     case gpr_x21:
444     case gpr_x22:
445     case gpr_x23:
446     case gpr_x24:
447     case gpr_x25:
448     case gpr_x26:
449     case gpr_x27:
450     case gpr_x28:
451     case gpr_fp:
452     case gpr_sp:
453     case gpr_lr:
454     case gpr_pc:
455     case gpr_cpsr:
456         value.SetUInt64 (gpr.x[reg - gpr_x0]);
457         break;
458
459     case fpu_v0:
460     case fpu_v1:
461     case fpu_v2:
462     case fpu_v3:
463     case fpu_v4:
464     case fpu_v5:
465     case fpu_v6:
466     case fpu_v7:
467     case fpu_v8:
468     case fpu_v9:
469     case fpu_v10:
470     case fpu_v11:
471     case fpu_v12:
472     case fpu_v13:
473     case fpu_v14:
474     case fpu_v15:
475     case fpu_v16:
476     case fpu_v17:
477     case fpu_v18:
478     case fpu_v19:
479     case fpu_v20:
480     case fpu_v21:
481     case fpu_v22:
482     case fpu_v23:
483     case fpu_v24:
484     case fpu_v25:
485     case fpu_v26:
486     case fpu_v27:
487     case fpu_v28:
488     case fpu_v29:
489     case fpu_v30:
490     case fpu_v31:
491         value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, endian::InlHostByteOrder());
492         break;
493
494     case fpu_fpsr:
495         value.SetUInt32 (fpu.fpsr);
496         break;
497
498     case fpu_fpcr:
499         value.SetUInt32 (fpu.fpcr);
500         break;
501
502     case exc_exception:
503         value.SetUInt32 (exc.exception);
504         break;
505     case exc_esr:
506         value.SetUInt32 (exc.esr);
507         break;
508     case exc_far:
509         value.SetUInt64 (exc.far);
510         break;
511
512     default:
513         value.SetValueToInvalid();
514         return false;
515
516     }
517     return true;
518 }
519
520
521 bool
522 RegisterContextDarwin_arm64::WriteRegister (const RegisterInfo *reg_info,
523                                         const RegisterValue &value)
524 {
525     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
526     int set = GetSetForNativeRegNum (reg);
527
528     if (set == -1)
529         return false;
530
531     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
532         return false;
533
534     switch (reg)
535     {
536     case gpr_x0:
537     case gpr_x1:
538     case gpr_x2:
539     case gpr_x3:
540     case gpr_x4:
541     case gpr_x5:
542     case gpr_x6:
543     case gpr_x7:
544     case gpr_x8:
545     case gpr_x9:
546     case gpr_x10:
547     case gpr_x11:
548     case gpr_x12:
549     case gpr_x13:
550     case gpr_x14:
551     case gpr_x15:
552     case gpr_x16:
553     case gpr_x17:
554     case gpr_x18:
555     case gpr_x19:
556     case gpr_x20:
557     case gpr_x21:
558     case gpr_x22:
559     case gpr_x23:
560     case gpr_x24:
561     case gpr_x25:
562     case gpr_x26:
563     case gpr_x27:
564     case gpr_x28:
565     case gpr_fp:
566     case gpr_sp:
567     case gpr_lr:
568     case gpr_pc:
569     case gpr_cpsr:
570             gpr.x[reg - gpr_x0] = value.GetAsUInt64();
571         break;
572
573     case fpu_v0:
574     case fpu_v1:
575     case fpu_v2:
576     case fpu_v3:
577     case fpu_v4:
578     case fpu_v5:
579     case fpu_v6:
580     case fpu_v7:
581     case fpu_v8:
582     case fpu_v9:
583     case fpu_v10:
584     case fpu_v11:
585     case fpu_v12:
586     case fpu_v13:
587     case fpu_v14:
588     case fpu_v15:
589     case fpu_v16:
590     case fpu_v17:
591     case fpu_v18:
592     case fpu_v19:
593     case fpu_v20:
594     case fpu_v21:
595     case fpu_v22:
596     case fpu_v23:
597     case fpu_v24:
598     case fpu_v25:
599     case fpu_v26:
600     case fpu_v27:
601     case fpu_v28:
602     case fpu_v29:
603     case fpu_v30:
604     case fpu_v31:
605         ::memcpy (fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
606         break;
607
608     case fpu_fpsr:
609         fpu.fpsr = value.GetAsUInt32();
610         break;
611
612     case fpu_fpcr:
613         fpu.fpcr = value.GetAsUInt32();
614         break;
615
616     case exc_exception:
617         exc.exception = value.GetAsUInt32();
618         break;
619     case exc_esr:
620         exc.esr = value.GetAsUInt32();
621         break;
622     case exc_far:
623         exc.far = value.GetAsUInt64();
624         break;
625
626     default:
627         return false;
628
629     }
630     return WriteRegisterSet(set) == KERN_SUCCESS;
631 }
632
633 bool
634 RegisterContextDarwin_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
635 {
636     data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
637     if (data_sp &&
638         ReadGPR (false) == KERN_SUCCESS &&
639         ReadFPU (false) == KERN_SUCCESS &&
640         ReadEXC (false) == KERN_SUCCESS)
641     {
642         uint8_t *dst = data_sp->GetBytes();
643         ::memcpy (dst, &gpr, sizeof(gpr));
644         dst += sizeof(gpr);
645
646         ::memcpy (dst, &fpu, sizeof(fpu));
647         dst += sizeof(gpr);
648
649         ::memcpy (dst, &exc, sizeof(exc));
650         return true;
651     }
652     return false;
653 }
654
655 bool
656 RegisterContextDarwin_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
657 {
658     if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
659     {
660         const uint8_t *src = data_sp->GetBytes();
661         ::memcpy (&gpr, src, sizeof(gpr));
662         src += sizeof(gpr);
663
664         ::memcpy (&fpu, src, sizeof(fpu));
665         src += sizeof(gpr);
666
667         ::memcpy (&exc, src, sizeof(exc));
668         uint32_t success_count = 0;
669         if (WriteGPR() == KERN_SUCCESS)
670             ++success_count;
671         if (WriteFPU() == KERN_SUCCESS)
672             ++success_count;
673         if (WriteEXC() == KERN_SUCCESS)
674             ++success_count;
675         return success_count == 3;
676     }
677     return false;
678 }
679
680 uint32_t
681 RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber (RegisterKind kind, uint32_t reg)
682 {
683     if (kind == eRegisterKindGeneric)
684     {
685         switch (reg)
686         {
687         case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
688         case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
689         case LLDB_REGNUM_GENERIC_FP: return gpr_fp;
690         case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
691         case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
692         default:
693             break;
694         }
695     }
696     else if (kind == eRegisterKindDWARF)
697     {
698         switch (reg)
699         {
700         case arm64_dwarf::x0:  return gpr_x0;
701         case arm64_dwarf::x1:  return gpr_x1;
702         case arm64_dwarf::x2:  return gpr_x2;
703         case arm64_dwarf::x3:  return gpr_x3;
704         case arm64_dwarf::x4:  return gpr_x4;
705         case arm64_dwarf::x5:  return gpr_x5;
706         case arm64_dwarf::x6:  return gpr_x6;
707         case arm64_dwarf::x7:  return gpr_x7;
708         case arm64_dwarf::x8:  return gpr_x8;
709         case arm64_dwarf::x9:  return gpr_x9;
710         case arm64_dwarf::x10: return gpr_x10;
711         case arm64_dwarf::x11: return gpr_x11;
712         case arm64_dwarf::x12: return gpr_x12;
713         case arm64_dwarf::x13: return gpr_x13;
714         case arm64_dwarf::x14: return gpr_x14;
715         case arm64_dwarf::x15: return gpr_x15;
716         case arm64_dwarf::x16: return gpr_x16;
717         case arm64_dwarf::x17: return gpr_x17;
718         case arm64_dwarf::x18: return gpr_x18;
719         case arm64_dwarf::x19: return gpr_x19;
720         case arm64_dwarf::x20: return gpr_x20;
721         case arm64_dwarf::x21: return gpr_x21;
722         case arm64_dwarf::x22: return gpr_x22;
723         case arm64_dwarf::x23: return gpr_x23;
724         case arm64_dwarf::x24: return gpr_x24;
725         case arm64_dwarf::x25: return gpr_x25;
726         case arm64_dwarf::x26: return gpr_x26;
727         case arm64_dwarf::x27: return gpr_x27;
728         case arm64_dwarf::x28: return gpr_x28;
729
730         case arm64_dwarf::fp:  return gpr_fp;
731         case arm64_dwarf::sp:  return gpr_sp;
732         case arm64_dwarf::lr:  return gpr_lr;
733         case arm64_dwarf::pc:  return gpr_pc;
734         case arm64_dwarf::cpsr: return gpr_cpsr;
735
736         case arm64_dwarf::v0:  return fpu_v0;
737         case arm64_dwarf::v1:  return fpu_v1;
738         case arm64_dwarf::v2:  return fpu_v2;
739         case arm64_dwarf::v3:  return fpu_v3;
740         case arm64_dwarf::v4:  return fpu_v4;
741         case arm64_dwarf::v5:  return fpu_v5;
742         case arm64_dwarf::v6:  return fpu_v6;
743         case arm64_dwarf::v7:  return fpu_v7;
744         case arm64_dwarf::v8:  return fpu_v8;
745         case arm64_dwarf::v9:  return fpu_v9;
746         case arm64_dwarf::v10: return fpu_v10;
747         case arm64_dwarf::v11: return fpu_v11;
748         case arm64_dwarf::v12: return fpu_v12;
749         case arm64_dwarf::v13: return fpu_v13;
750         case arm64_dwarf::v14: return fpu_v14;
751         case arm64_dwarf::v15: return fpu_v15;
752         case arm64_dwarf::v16: return fpu_v16;
753         case arm64_dwarf::v17: return fpu_v17;
754         case arm64_dwarf::v18: return fpu_v18;
755         case arm64_dwarf::v19: return fpu_v19;
756         case arm64_dwarf::v20: return fpu_v20;
757         case arm64_dwarf::v21: return fpu_v21;
758         case arm64_dwarf::v22: return fpu_v22;
759         case arm64_dwarf::v23: return fpu_v23;
760         case arm64_dwarf::v24: return fpu_v24;
761         case arm64_dwarf::v25: return fpu_v25;
762         case arm64_dwarf::v26: return fpu_v26;
763         case arm64_dwarf::v27: return fpu_v27;
764         case arm64_dwarf::v28: return fpu_v28;
765         case arm64_dwarf::v29: return fpu_v29;
766         case arm64_dwarf::v30: return fpu_v30;
767         case arm64_dwarf::v31: return fpu_v31;
768
769         default:
770             break;
771         }
772     }
773     else if (kind == eRegisterKindEHFrame)
774     {
775         switch (reg)
776         {
777         case arm64_ehframe::x0:  return gpr_x0;
778         case arm64_ehframe::x1:  return gpr_x1;
779         case arm64_ehframe::x2:  return gpr_x2;
780         case arm64_ehframe::x3:  return gpr_x3;
781         case arm64_ehframe::x4:  return gpr_x4;
782         case arm64_ehframe::x5:  return gpr_x5;
783         case arm64_ehframe::x6:  return gpr_x6;
784         case arm64_ehframe::x7:  return gpr_x7;
785         case arm64_ehframe::x8:  return gpr_x8;
786         case arm64_ehframe::x9:  return gpr_x9;
787         case arm64_ehframe::x10: return gpr_x10;
788         case arm64_ehframe::x11: return gpr_x11;
789         case arm64_ehframe::x12: return gpr_x12;
790         case arm64_ehframe::x13: return gpr_x13;
791         case arm64_ehframe::x14: return gpr_x14;
792         case arm64_ehframe::x15: return gpr_x15;
793         case arm64_ehframe::x16: return gpr_x16;
794         case arm64_ehframe::x17: return gpr_x17;
795         case arm64_ehframe::x18: return gpr_x18;
796         case arm64_ehframe::x19: return gpr_x19;
797         case arm64_ehframe::x20: return gpr_x20;
798         case arm64_ehframe::x21: return gpr_x21;
799         case arm64_ehframe::x22: return gpr_x22;
800         case arm64_ehframe::x23: return gpr_x23;
801         case arm64_ehframe::x24: return gpr_x24;
802         case arm64_ehframe::x25: return gpr_x25;
803         case arm64_ehframe::x26: return gpr_x26;
804         case arm64_ehframe::x27: return gpr_x27;
805         case arm64_ehframe::x28: return gpr_x28;
806         case arm64_ehframe::fp:   return gpr_fp;
807         case arm64_ehframe::sp:   return gpr_sp;
808         case arm64_ehframe::lr:   return gpr_lr;
809         case arm64_ehframe::pc:   return gpr_pc;
810         case arm64_ehframe::cpsr: return gpr_cpsr;
811         }
812     }
813     else if (kind == eRegisterKindLLDB)
814     {
815         return reg;
816     }
817     return LLDB_INVALID_REGNUM;
818 }
819
820
821 uint32_t
822 RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints ()
823 {
824 #if defined (__arm64__) || defined (__aarch64__)
825     // autodetect how many watchpoints are supported dynamically...
826     static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
827     if (g_num_supported_hw_watchpoints == UINT32_MAX)
828     {
829         size_t len;
830         uint32_t n = 0;
831         len = sizeof (n);
832         if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
833         {
834             g_num_supported_hw_watchpoints = n;
835         }
836     }
837     return g_num_supported_hw_watchpoints;
838 #else
839     // TODO: figure out remote case here!
840     return 2;
841 #endif
842 }
843
844
845 uint32_t
846 RegisterContextDarwin_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
847 {
848 //    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
849
850     const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
851
852     // Can't watch zero bytes
853     if (size == 0)
854         return LLDB_INVALID_INDEX32;
855
856     // We must watch for either read or write
857     if (read == false && write == false)
858         return LLDB_INVALID_INDEX32;
859
860     // Can't watch more than 4 bytes per WVR/WCR pair
861     if (size > 4)
862         return LLDB_INVALID_INDEX32;
863
864     // We can only watch up to four bytes that follow a 4 byte aligned address
865     // per watchpoint register pair. Since we have at most so we can only watch
866     // until the next 4 byte boundary and we need to make sure we can properly
867     // encode this.
868     uint32_t addr_word_offset = addr % 4;
869 //    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
870
871     uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
872 //    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
873     if (byte_mask > 0xfu)
874         return LLDB_INVALID_INDEX32;
875
876     // Read the debug state
877     int kret = ReadDBG (false);
878
879     if (kret == KERN_SUCCESS)
880     {
881         // Check to make sure we have the needed hardware support
882         uint32_t i = 0;
883
884         for (i=0; i<num_hw_watchpoints; ++i)
885         {
886             if ((dbg.wcr[i] & WCR_ENABLE) == 0)
887                 break; // We found an available hw breakpoint slot (in i)
888         }
889
890         // See if we found an available hw breakpoint slot above
891         if (i < num_hw_watchpoints)
892         {
893             // Make the byte_mask into a valid Byte Address Select mask
894             uint32_t byte_address_select = byte_mask << 5;
895             // Make sure bits 1:0 are clear in our address
896             dbg.wvr[i] = addr & ~((lldb::addr_t)3);
897             dbg.wcr[i] =  byte_address_select |       // Which bytes that follow the IMVA that we will watch
898                                     S_USER |                    // Stop only in user mode
899                                     (read ? WCR_LOAD : 0) |     // Stop on read access?
900                                     (write ? WCR_STORE : 0) |   // Stop on write access?
901                                     WCR_ENABLE;                 // Enable this watchpoint;
902
903             kret = WriteDBG();
904 //            if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
905
906             if (kret == KERN_SUCCESS)
907                 return i;
908         }
909         else
910         {
911 //            if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
912         }
913     }
914     return LLDB_INVALID_INDEX32;
915 }
916
917 bool
918 RegisterContextDarwin_arm64::ClearHardwareWatchpoint (uint32_t hw_index)
919 {
920     int kret = ReadDBG (false);
921
922     const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
923     if (kret == KERN_SUCCESS)
924     {
925         if (hw_index < num_hw_points)
926         {
927             dbg.wcr[hw_index] = 0;
928 //            if (log) log->Printf ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
929 //                    hw_index,
930 //                    hw_index,
931 //                    dbg.wvr[hw_index],
932 //                    hw_index,
933 //                    dbg.wcr[hw_index]);
934
935             kret = WriteDBG();
936
937             if (kret == KERN_SUCCESS)
938                 return true;
939         }
940     }
941     return false;
942 }
943
944 #endif