1 //===-- RegisterContextDarwin_arm.cpp ---------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #if defined(__APPLE__)
12 #include "RegisterContextDarwin_arm.h"
15 #include <mach/mach_types.h>
16 #include <mach/thread_act.h>
19 // Other libraries and framework includes
20 #include "lldb/Core/RegisterValue.h"
21 #include "lldb/Core/Scalar.h"
22 #include "lldb/Utility/DataBufferHeap.h"
23 #include "lldb/Utility/DataExtractor.h"
24 #include "lldb/Utility/Endian.h"
25 #include "lldb/Utility/Log.h"
26 #include "llvm/Support/Compiler.h"
28 #include "Plugins/Process/Utility/InstructionUtils.h"
30 // Support building against older versions of LLVM, this macro was added
32 #ifndef LLVM_EXTENSION
33 #define LLVM_EXTENSION
37 #include "ARM_DWARF_Registers.h"
38 #include "Utility/ARM_ehframe_Registers.h"
40 #include "llvm/ADT/STLExtras.h"
43 using namespace lldb_private;
176 #define GPR_OFFSET(idx) ((idx)*4)
177 #define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))
178 #define EXC_OFFSET(idx) \
179 ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \
180 sizeof(RegisterContextDarwin_arm::FPU))
181 #define DBG_OFFSET(reg) \
182 ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \
183 sizeof(RegisterContextDarwin_arm::GPR) + \
184 sizeof(RegisterContextDarwin_arm::FPU) + \
185 sizeof(RegisterContextDarwin_arm::EXC)))
187 #define DEFINE_DBG(reg, i) \
188 #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \
189 DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
190 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
191 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
192 LLDB_INVALID_REGNUM }, \
193 nullptr, nullptr, nullptr, 0
194 #define REG_CONTEXT_SIZE \
195 (sizeof(RegisterContextDarwin_arm::GPR) + \
196 sizeof(RegisterContextDarwin_arm::FPU) + \
197 sizeof(RegisterContextDarwin_arm::EXC))
199 static RegisterInfo g_register_infos[] = {
200 // General purpose registers
201 // NAME ALT SZ OFFSET ENCODING FORMAT
202 // EH_FRAME DWARF GENERIC
203 // PROCESS PLUGIN LLDB NATIVE
204 // ====== ======= == ============= ============= ============
205 // =============== =============== =========================
206 // ===================== =============
213 {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},
224 {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},
235 {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},
246 {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},
257 {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
268 {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
279 {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
290 {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
302 {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
313 {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
324 {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
336 {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
348 {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
360 {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
372 {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
384 {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
396 {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
409 {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
421 {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
433 {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
445 {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
457 {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
469 {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
481 {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
493 {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
505 {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
517 {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
529 {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
541 {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
553 {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
565 {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
577 {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
589 {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
601 {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
613 {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
625 {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
637 {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
649 {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
661 {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
673 {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
685 {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
697 {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
709 {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
721 {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
733 {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
745 {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
757 {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
769 {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
781 {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
793 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
794 LLDB_INVALID_REGNUM, fpu_fpscr},
806 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
807 LLDB_INVALID_REGNUM, exc_exception},
818 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
819 LLDB_INVALID_REGNUM, exc_fsr},
830 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
831 LLDB_INVALID_REGNUM, exc_far},
837 {DEFINE_DBG(bvr, 0)},
838 {DEFINE_DBG(bvr, 1)},
839 {DEFINE_DBG(bvr, 2)},
840 {DEFINE_DBG(bvr, 3)},
841 {DEFINE_DBG(bvr, 4)},
842 {DEFINE_DBG(bvr, 5)},
843 {DEFINE_DBG(bvr, 6)},
844 {DEFINE_DBG(bvr, 7)},
845 {DEFINE_DBG(bvr, 8)},
846 {DEFINE_DBG(bvr, 9)},
847 {DEFINE_DBG(bvr, 10)},
848 {DEFINE_DBG(bvr, 11)},
849 {DEFINE_DBG(bvr, 12)},
850 {DEFINE_DBG(bvr, 13)},
851 {DEFINE_DBG(bvr, 14)},
852 {DEFINE_DBG(bvr, 15)},
854 {DEFINE_DBG(bcr, 0)},
855 {DEFINE_DBG(bcr, 1)},
856 {DEFINE_DBG(bcr, 2)},
857 {DEFINE_DBG(bcr, 3)},
858 {DEFINE_DBG(bcr, 4)},
859 {DEFINE_DBG(bcr, 5)},
860 {DEFINE_DBG(bcr, 6)},
861 {DEFINE_DBG(bcr, 7)},
862 {DEFINE_DBG(bcr, 8)},
863 {DEFINE_DBG(bcr, 9)},
864 {DEFINE_DBG(bcr, 10)},
865 {DEFINE_DBG(bcr, 11)},
866 {DEFINE_DBG(bcr, 12)},
867 {DEFINE_DBG(bcr, 13)},
868 {DEFINE_DBG(bcr, 14)},
869 {DEFINE_DBG(bcr, 15)},
871 {DEFINE_DBG(wvr, 0)},
872 {DEFINE_DBG(wvr, 1)},
873 {DEFINE_DBG(wvr, 2)},
874 {DEFINE_DBG(wvr, 3)},
875 {DEFINE_DBG(wvr, 4)},
876 {DEFINE_DBG(wvr, 5)},
877 {DEFINE_DBG(wvr, 6)},
878 {DEFINE_DBG(wvr, 7)},
879 {DEFINE_DBG(wvr, 8)},
880 {DEFINE_DBG(wvr, 9)},
881 {DEFINE_DBG(wvr, 10)},
882 {DEFINE_DBG(wvr, 11)},
883 {DEFINE_DBG(wvr, 12)},
884 {DEFINE_DBG(wvr, 13)},
885 {DEFINE_DBG(wvr, 14)},
886 {DEFINE_DBG(wvr, 15)},
888 {DEFINE_DBG(wcr, 0)},
889 {DEFINE_DBG(wcr, 1)},
890 {DEFINE_DBG(wcr, 2)},
891 {DEFINE_DBG(wcr, 3)},
892 {DEFINE_DBG(wcr, 4)},
893 {DEFINE_DBG(wcr, 5)},
894 {DEFINE_DBG(wcr, 6)},
895 {DEFINE_DBG(wcr, 7)},
896 {DEFINE_DBG(wcr, 8)},
897 {DEFINE_DBG(wcr, 9)},
898 {DEFINE_DBG(wcr, 10)},
899 {DEFINE_DBG(wcr, 11)},
900 {DEFINE_DBG(wcr, 12)},
901 {DEFINE_DBG(wcr, 13)},
902 {DEFINE_DBG(wcr, 14)},
903 {DEFINE_DBG(wcr, 15)}};
905 // General purpose registers
906 static uint32_t g_gpr_regnums[] = {
907 gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,
908 gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};
910 // Floating point registers
911 static uint32_t g_fpu_regnums[] = {
912 fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6,
913 fpu_s7, fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13,
914 fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20,
915 fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25, fpu_s26, fpu_s27,
916 fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,
919 // Exception registers
921 static uint32_t g_exc_regnums[] = {
922 exc_exception, exc_fsr, exc_far,
925 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
927 RegisterContextDarwin_arm::RegisterContextDarwin_arm(
928 Thread &thread, uint32_t concrete_frame_idx)
929 : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
931 for (i = 0; i < kNumErrors; i++) {
938 RegisterContextDarwin_arm::~RegisterContextDarwin_arm() {}
940 void RegisterContextDarwin_arm::InvalidateAllRegisters() {
941 InvalidateAllRegisterStates();
944 size_t RegisterContextDarwin_arm::GetRegisterCount() {
945 assert(k_num_register_infos == k_num_registers);
946 return k_num_registers;
950 RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {
951 assert(k_num_register_infos == k_num_registers);
952 if (reg < k_num_registers)
953 return &g_register_infos[reg];
957 size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {
958 return k_num_register_infos;
961 const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {
962 return g_register_infos;
965 // Number of registers in each register set
966 const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
967 const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
968 const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
970 //----------------------------------------------------------------------
971 // Register set definitions. The first definitions at register set index
972 // of zero is for all registers, followed by other registers sets. The
973 // register information for the all register set need not be filled in.
974 //----------------------------------------------------------------------
975 static const RegisterSet g_reg_sets[] = {
977 "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
979 {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
980 {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
982 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
984 size_t RegisterContextDarwin_arm::GetRegisterSetCount() {
985 return k_num_regsets;
988 const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {
989 if (reg_set < k_num_regsets)
990 return &g_reg_sets[reg_set];
994 //----------------------------------------------------------------------
995 // Register information definitions for 32 bit i386.
996 //----------------------------------------------------------------------
997 int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {
1000 else if (reg < exc_exception)
1002 else if (reg < k_num_registers)
1007 int RegisterContextDarwin_arm::ReadGPR(bool force) {
1008 int set = GPRRegSet;
1009 if (force || !RegisterSetIsCached(set)) {
1010 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
1012 return GetError(GPRRegSet, Read);
1015 int RegisterContextDarwin_arm::ReadFPU(bool force) {
1016 int set = FPURegSet;
1017 if (force || !RegisterSetIsCached(set)) {
1018 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
1020 return GetError(FPURegSet, Read);
1023 int RegisterContextDarwin_arm::ReadEXC(bool force) {
1024 int set = EXCRegSet;
1025 if (force || !RegisterSetIsCached(set)) {
1026 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
1028 return GetError(EXCRegSet, Read);
1031 int RegisterContextDarwin_arm::ReadDBG(bool force) {
1032 int set = DBGRegSet;
1033 if (force || !RegisterSetIsCached(set)) {
1034 SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
1036 return GetError(DBGRegSet, Read);
1039 int RegisterContextDarwin_arm::WriteGPR() {
1040 int set = GPRRegSet;
1041 if (!RegisterSetIsCached(set)) {
1042 SetError(set, Write, -1);
1043 return KERN_INVALID_ARGUMENT;
1045 SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
1046 SetError(set, Read, -1);
1047 return GetError(GPRRegSet, Write);
1050 int RegisterContextDarwin_arm::WriteFPU() {
1051 int set = FPURegSet;
1052 if (!RegisterSetIsCached(set)) {
1053 SetError(set, Write, -1);
1054 return KERN_INVALID_ARGUMENT;
1056 SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
1057 SetError(set, Read, -1);
1058 return GetError(FPURegSet, Write);
1061 int RegisterContextDarwin_arm::WriteEXC() {
1062 int set = EXCRegSet;
1063 if (!RegisterSetIsCached(set)) {
1064 SetError(set, Write, -1);
1065 return KERN_INVALID_ARGUMENT;
1067 SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
1068 SetError(set, Read, -1);
1069 return GetError(EXCRegSet, Write);
1072 int RegisterContextDarwin_arm::WriteDBG() {
1073 int set = DBGRegSet;
1074 if (!RegisterSetIsCached(set)) {
1075 SetError(set, Write, -1);
1076 return KERN_INVALID_ARGUMENT;
1078 SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
1079 SetError(set, Read, -1);
1080 return GetError(DBGRegSet, Write);
1083 int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {
1086 return ReadGPR(force);
1088 return ReadGPR(force);
1090 return ReadFPU(force);
1092 return ReadEXC(force);
1094 return ReadDBG(force);
1098 return KERN_INVALID_ARGUMENT;
1101 int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
1102 // Make sure we have a valid context to set.
1103 if (RegisterSetIsCached(set)) {
1119 return KERN_INVALID_ARGUMENT;
1122 void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
1124 for (uint32_t i = 0; i < 16; i++)
1125 log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
1126 "0x%8.8x, 0x%8.8x }",
1127 i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
1131 bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,
1132 RegisterValue &value) {
1133 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1134 int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);
1139 if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1160 value.SetUInt32(gpr.r[reg - gpr_r0]);
1195 value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);
1199 value.SetUInt32(fpu.fpscr);
1203 value.SetUInt32(exc.exception);
1206 value.SetUInt32(exc.fsr);
1209 value.SetUInt32(exc.far);
1213 value.SetValueToInvalid();
1219 bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,
1220 const RegisterValue &value) {
1221 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1222 int set = GetSetForNativeRegNum(reg);
1227 if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1248 gpr.r[reg - gpr_r0] = value.GetAsUInt32();
1283 fpu.floats.s[reg] = value.GetAsUInt32();
1287 fpu.fpscr = value.GetAsUInt32();
1291 exc.exception = value.GetAsUInt32();
1294 exc.fsr = value.GetAsUInt32();
1297 exc.far = value.GetAsUInt32();
1303 return WriteRegisterSet(set) == KERN_SUCCESS;
1306 bool RegisterContextDarwin_arm::ReadAllRegisterValues(
1307 lldb::DataBufferSP &data_sp) {
1308 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
1309 if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
1310 ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
1311 uint8_t *dst = data_sp->GetBytes();
1312 ::memcpy(dst, &gpr, sizeof(gpr));
1315 ::memcpy(dst, &fpu, sizeof(fpu));
1318 ::memcpy(dst, &exc, sizeof(exc));
1324 bool RegisterContextDarwin_arm::WriteAllRegisterValues(
1325 const lldb::DataBufferSP &data_sp) {
1326 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
1327 const uint8_t *src = data_sp->GetBytes();
1328 ::memcpy(&gpr, src, sizeof(gpr));
1331 ::memcpy(&fpu, src, sizeof(fpu));
1334 ::memcpy(&exc, src, sizeof(exc));
1335 uint32_t success_count = 0;
1336 if (WriteGPR() == KERN_SUCCESS)
1338 if (WriteFPU() == KERN_SUCCESS)
1340 if (WriteEXC() == KERN_SUCCESS)
1342 return success_count == 3;
1347 uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
1348 lldb::RegisterKind kind, uint32_t reg) {
1349 if (kind == eRegisterKindGeneric) {
1351 case LLDB_REGNUM_GENERIC_PC:
1353 case LLDB_REGNUM_GENERIC_SP:
1355 case LLDB_REGNUM_GENERIC_FP:
1357 case LLDB_REGNUM_GENERIC_RA:
1359 case LLDB_REGNUM_GENERIC_FLAGS:
1364 } else if (kind == eRegisterKindDWARF) {
1469 } else if (kind == eRegisterKindEHFrame) {
1506 } else if (kind == eRegisterKindLLDB) {
1509 return LLDB_INVALID_REGNUM;
1512 uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
1513 #if defined(__arm__)
1514 // Set the init value to something that will let us know that we need to
1515 // autodetect how many breakpoints are supported dynamically...
1516 static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
1517 if (g_num_supported_hw_breakpoints == UINT32_MAX) {
1518 // Set this to zero in case we can't tell if there are any HW breakpoints
1519 g_num_supported_hw_breakpoints = 0;
1521 uint32_t register_DBGDIDR;
1523 asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1524 g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);
1525 // Zero is reserved for the BRP count, so don't increment it if it is zero
1526 if (g_num_supported_hw_breakpoints > 0)
1527 g_num_supported_hw_breakpoints++;
1528 // if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)",
1529 // register_DBGDIDR, g_num_supported_hw_breakpoints);
1531 return g_num_supported_hw_breakpoints;
1533 // TODO: figure out remote case here!
1538 uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,
1540 // Make sure our address isn't bogus
1542 return LLDB_INVALID_INDEX32;
1544 int kret = ReadDBG(false);
1546 if (kret == KERN_SUCCESS) {
1547 const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
1549 for (i = 0; i < num_hw_breakpoints; ++i) {
1550 if ((dbg.bcr[i] & BCR_ENABLE) == 0)
1551 break; // We found an available hw breakpoint slot (in i)
1554 // See if we found an available hw breakpoint slot above
1555 if (i < num_hw_breakpoints) {
1556 // Make sure bits 1:0 are clear in our address
1557 dbg.bvr[i] = addr & ~((lldb::addr_t)3);
1559 if (size == 2 || addr & 2) {
1560 uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
1562 // We have a thumb breakpoint
1563 // We have an ARM breakpoint
1564 dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
1565 byte_addr_select | // Set the correct byte address select
1566 // so we only trigger on the correct
1568 S_USER | // Which modes should this breakpoint stop in?
1569 BCR_ENABLE; // Enable this hardware breakpoint
1570 // if (log) log->Printf
1571 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1572 // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1573 // 0x%8.8x (Thumb)",
1580 } else if (size == 4) {
1581 // We have an ARM breakpoint
1583 BCR_M_IMVA_MATCH | // Stop on address mismatch
1584 BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
1585 S_USER | // Which modes should this breakpoint stop in?
1586 BCR_ENABLE; // Enable this hardware breakpoint
1587 // if (log) log->Printf
1588 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1589 // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1600 // if (log) log->Printf
1601 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()
1602 // WriteDBG() => 0x%8.8x.", kret);
1604 if (kret == KERN_SUCCESS)
1609 // if (log) log->Printf
1610 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =
1611 // %8.8p, size = %u) => all hardware breakpoint resources are
1612 // being used.", addr, size);
1616 return LLDB_INVALID_INDEX32;
1619 bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
1620 int kret = ReadDBG(false);
1622 const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
1623 if (kret == KERN_SUCCESS) {
1624 if (hw_index < num_hw_points) {
1625 dbg.bcr[hw_index] = 0;
1626 // if (log) log->Printf
1627 // ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -
1628 // BVR%u = 0x%8.8x BCR%u = 0x%8.8x",
1631 // dbg.bvr[hw_index],
1633 // dbg.bcr[hw_index]);
1637 if (kret == KERN_SUCCESS)
1644 uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
1645 #if defined(__arm__)
1646 // Set the init value to something that will let us know that we need to
1647 // autodetect how many watchpoints are supported dynamically...
1648 static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1649 if (g_num_supported_hw_watchpoints == UINT32_MAX) {
1650 // Set this to zero in case we can't tell if there are any HW breakpoints
1651 g_num_supported_hw_watchpoints = 0;
1653 uint32_t register_DBGDIDR;
1654 asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1655 g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
1656 // if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)",
1657 // register_DBGDIDR, g_num_supported_hw_watchpoints);
1659 return g_num_supported_hw_watchpoints;
1661 // TODO: figure out remote case here!
1666 uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
1670 // if (log) log->Printf
1671 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size
1672 // = %u, read = %u, write = %u)", addr, size, read, write);
1674 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1676 // Can't watch zero bytes
1678 return LLDB_INVALID_INDEX32;
1680 // We must watch for either read or write
1681 if (read == false && write == false)
1682 return LLDB_INVALID_INDEX32;
1684 // Can't watch more than 4 bytes per WVR/WCR pair
1686 return LLDB_INVALID_INDEX32;
1688 // We can only watch up to four bytes that follow a 4 byte aligned address
1689 // per watchpoint register pair. Since we have at most so we can only watch
1690 // until the next 4 byte boundary and we need to make sure we can properly
1692 uint32_t addr_word_offset = addr % 4;
1693 // if (log) log->Printf
1694 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -
1695 // addr_word_offset = 0x%8.8x", addr_word_offset);
1697 uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
1698 // if (log) log->Printf
1699 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =
1700 // 0x%8.8x", byte_mask);
1701 if (byte_mask > 0xfu)
1702 return LLDB_INVALID_INDEX32;
1704 // Read the debug state
1705 int kret = ReadDBG(false);
1707 if (kret == KERN_SUCCESS) {
1708 // Check to make sure we have the needed hardware support
1711 for (i = 0; i < num_hw_watchpoints; ++i) {
1712 if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1713 break; // We found an available hw breakpoint slot (in i)
1716 // See if we found an available hw breakpoint slot above
1717 if (i < num_hw_watchpoints) {
1718 // Make the byte_mask into a valid Byte Address Select mask
1719 uint32_t byte_address_select = byte_mask << 5;
1720 // Make sure bits 1:0 are clear in our address
1721 dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1722 dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA
1723 // that we will watch
1724 S_USER | // Stop only in user mode
1725 (read ? WCR_LOAD : 0) | // Stop on read access?
1726 (write ? WCR_STORE : 0) | // Stop on write access?
1727 WCR_ENABLE; // Enable this watchpoint;
1730 // if (log) log->Printf
1731 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()
1732 // WriteDBG() => 0x%8.8x.", kret);
1734 if (kret == KERN_SUCCESS)
1737 // if (log) log->Printf
1738 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All
1739 // hardware resources (%u) are in use.", num_hw_watchpoints);
1742 return LLDB_INVALID_INDEX32;
1745 bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
1746 int kret = ReadDBG(false);
1748 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1749 if (kret == KERN_SUCCESS) {
1750 if (hw_index < num_hw_points) {
1751 dbg.wcr[hw_index] = 0;
1752 // if (log) log->Printf
1753 // ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -
1754 // WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
1757 // dbg.wvr[hw_index],
1759 // dbg.wcr[hw_index]);
1763 if (kret == KERN_SUCCESS)