1 //===-- RegisterContextDarwin_x86_64.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 11 // C Includes 12 #include <inttypes.h> // PRIx64 13 #include <stdarg.h> 14 #include <stddef.h> // offsetof 15 16 // C++ Includes 17 // Other libraries and framework includes 18 #include "lldb/Core/DataBufferHeap.h" 19 #include "lldb/Core/DataExtractor.h" 20 #include "lldb/Core/Log.h" 21 #include "lldb/Core/RegisterValue.h" 22 #include "lldb/Core/Scalar.h" 23 #include "lldb/Host/Endian.h" 24 #include "llvm/ADT/STLExtras.h" 25 #include "llvm/Support/Compiler.h" 26 27 // Support building against older versions of LLVM, this macro was added 28 // recently. 29 #ifndef LLVM_EXTENSION 30 #define LLVM_EXTENSION 31 #endif 32 33 // Project includes 34 #include "RegisterContextDarwin_x86_64.h" 35 36 using namespace lldb; 37 using namespace lldb_private; 38 39 enum 40 { 41 gpr_rax = 0, 42 gpr_rbx, 43 gpr_rcx, 44 gpr_rdx, 45 gpr_rdi, 46 gpr_rsi, 47 gpr_rbp, 48 gpr_rsp, 49 gpr_r8, 50 gpr_r9, 51 gpr_r10, 52 gpr_r11, 53 gpr_r12, 54 gpr_r13, 55 gpr_r14, 56 gpr_r15, 57 gpr_rip, 58 gpr_rflags, 59 gpr_cs, 60 gpr_fs, 61 gpr_gs, 62 63 fpu_fcw, 64 fpu_fsw, 65 fpu_ftw, 66 fpu_fop, 67 fpu_ip, 68 fpu_cs, 69 fpu_dp, 70 fpu_ds, 71 fpu_mxcsr, 72 fpu_mxcsrmask, 73 fpu_stmm0, 74 fpu_stmm1, 75 fpu_stmm2, 76 fpu_stmm3, 77 fpu_stmm4, 78 fpu_stmm5, 79 fpu_stmm6, 80 fpu_stmm7, 81 fpu_xmm0, 82 fpu_xmm1, 83 fpu_xmm2, 84 fpu_xmm3, 85 fpu_xmm4, 86 fpu_xmm5, 87 fpu_xmm6, 88 fpu_xmm7, 89 fpu_xmm8, 90 fpu_xmm9, 91 fpu_xmm10, 92 fpu_xmm11, 93 fpu_xmm12, 94 fpu_xmm13, 95 fpu_xmm14, 96 fpu_xmm15, 97 98 exc_trapno, 99 exc_err, 100 exc_faultvaddr, 101 102 k_num_registers, 103 104 // Aliases 105 fpu_fctrl = fpu_fcw, 106 fpu_fstat = fpu_fsw, 107 fpu_ftag = fpu_ftw, 108 fpu_fiseg = fpu_cs, 109 fpu_fioff = fpu_ip, 110 fpu_foseg = fpu_ds, 111 fpu_fooff = fpu_dp 112 }; 113 114 enum ehframe_dwarf_regnums 115 { 116 ehframe_dwarf_gpr_rax = 0, 117 ehframe_dwarf_gpr_rdx, 118 ehframe_dwarf_gpr_rcx, 119 ehframe_dwarf_gpr_rbx, 120 ehframe_dwarf_gpr_rsi, 121 ehframe_dwarf_gpr_rdi, 122 ehframe_dwarf_gpr_rbp, 123 ehframe_dwarf_gpr_rsp, 124 ehframe_dwarf_gpr_r8, 125 ehframe_dwarf_gpr_r9, 126 ehframe_dwarf_gpr_r10, 127 ehframe_dwarf_gpr_r11, 128 ehframe_dwarf_gpr_r12, 129 ehframe_dwarf_gpr_r13, 130 ehframe_dwarf_gpr_r14, 131 ehframe_dwarf_gpr_r15, 132 ehframe_dwarf_gpr_rip, 133 ehframe_dwarf_fpu_xmm0, 134 ehframe_dwarf_fpu_xmm1, 135 ehframe_dwarf_fpu_xmm2, 136 ehframe_dwarf_fpu_xmm3, 137 ehframe_dwarf_fpu_xmm4, 138 ehframe_dwarf_fpu_xmm5, 139 ehframe_dwarf_fpu_xmm6, 140 ehframe_dwarf_fpu_xmm7, 141 ehframe_dwarf_fpu_xmm8, 142 ehframe_dwarf_fpu_xmm9, 143 ehframe_dwarf_fpu_xmm10, 144 ehframe_dwarf_fpu_xmm11, 145 ehframe_dwarf_fpu_xmm12, 146 ehframe_dwarf_fpu_xmm13, 147 ehframe_dwarf_fpu_xmm14, 148 ehframe_dwarf_fpu_xmm15, 149 ehframe_dwarf_fpu_stmm0, 150 ehframe_dwarf_fpu_stmm1, 151 ehframe_dwarf_fpu_stmm2, 152 ehframe_dwarf_fpu_stmm3, 153 ehframe_dwarf_fpu_stmm4, 154 ehframe_dwarf_fpu_stmm5, 155 ehframe_dwarf_fpu_stmm6, 156 ehframe_dwarf_fpu_stmm7 157 158 }; 159 160 #define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::GPR, reg)) 161 #define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::FPU, reg) + sizeof (RegisterContextDarwin_x86_64::GPR)) 162 #define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::EXC, reg) + sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU)) 163 164 // These macros will auto define the register name, alt name, register size, 165 // register offset, encoding, format and native register. This ensures that 166 // the register state structures are defined correctly and have the correct 167 // sizes and offsets. 168 #define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex 169 #define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex 170 #define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { ehframe_dwarf_fpu_##reg##i, ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_##reg##i }, NULL, NULL 171 #define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex 172 173 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU) + sizeof (RegisterContextDarwin_x86_64::EXC)) 174 175 // General purpose registers for 64 bit 176 static RegisterInfo g_register_infos[] = 177 { 178 // Macro auto defines most stuff EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS 179 // =============================== ====================== =================== ========================== ==================== =================== ========== =============== 180 { DEFINE_GPR (rax , NULL) , { ehframe_dwarf_gpr_rax , ehframe_dwarf_gpr_rax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rax }, NULL, NULL}, 181 { DEFINE_GPR (rbx , NULL) , { ehframe_dwarf_gpr_rbx , ehframe_dwarf_gpr_rbx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rbx }, NULL, NULL}, 182 { DEFINE_GPR (rcx , NULL) , { ehframe_dwarf_gpr_rcx , ehframe_dwarf_gpr_rcx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rcx }, NULL, NULL}, 183 { DEFINE_GPR (rdx , NULL) , { ehframe_dwarf_gpr_rdx , ehframe_dwarf_gpr_rdx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rdx }, NULL, NULL}, 184 { DEFINE_GPR (rdi , NULL) , { ehframe_dwarf_gpr_rdi , ehframe_dwarf_gpr_rdi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rdi }, NULL, NULL}, 185 { DEFINE_GPR (rsi , NULL) , { ehframe_dwarf_gpr_rsi , ehframe_dwarf_gpr_rsi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rsi }, NULL, NULL}, 186 { DEFINE_GPR (rbp , "fp") , { ehframe_dwarf_gpr_rbp , ehframe_dwarf_gpr_rbp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, gpr_rbp }, NULL, NULL}, 187 { DEFINE_GPR (rsp , "sp") , { ehframe_dwarf_gpr_rsp , ehframe_dwarf_gpr_rsp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, gpr_rsp }, NULL, NULL}, 188 { DEFINE_GPR (r8 , NULL) , { ehframe_dwarf_gpr_r8 , ehframe_dwarf_gpr_r8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r8 }, NULL, NULL}, 189 { DEFINE_GPR (r9 , NULL) , { ehframe_dwarf_gpr_r9 , ehframe_dwarf_gpr_r9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r9 }, NULL, NULL}, 190 { DEFINE_GPR (r10 , NULL) , { ehframe_dwarf_gpr_r10 , ehframe_dwarf_gpr_r10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r10 }, NULL, NULL}, 191 { DEFINE_GPR (r11 , NULL) , { ehframe_dwarf_gpr_r11 , ehframe_dwarf_gpr_r11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r11 }, NULL, NULL}, 192 { DEFINE_GPR (r12 , NULL) , { ehframe_dwarf_gpr_r12 , ehframe_dwarf_gpr_r12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r12 }, NULL, NULL}, 193 { DEFINE_GPR (r13 , NULL) , { ehframe_dwarf_gpr_r13 , ehframe_dwarf_gpr_r13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r13 }, NULL, NULL}, 194 { DEFINE_GPR (r14 , NULL) , { ehframe_dwarf_gpr_r14 , ehframe_dwarf_gpr_r14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r14 }, NULL, NULL}, 195 { DEFINE_GPR (r15 , NULL) , { ehframe_dwarf_gpr_r15 , ehframe_dwarf_gpr_r15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r15 }, NULL, NULL}, 196 { DEFINE_GPR (rip , "pc") , { ehframe_dwarf_gpr_rip , ehframe_dwarf_gpr_rip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, gpr_rip }, NULL, NULL}, 197 { DEFINE_GPR (rflags, "flags") , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_rflags }, NULL, NULL}, 198 { DEFINE_GPR (cs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_cs }, NULL, NULL}, 199 { DEFINE_GPR (fs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_fs }, NULL, NULL}, 200 { DEFINE_GPR (gs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_gs }, NULL, NULL}, 201 202 { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fcw }, NULL, NULL}, 203 { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fsw }, NULL, NULL}, 204 { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ftw }, NULL, NULL}, 205 { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fop }, NULL, NULL}, 206 { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ip }, NULL, NULL}, 207 { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_cs }, NULL, NULL}, 208 { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_dp }, NULL, NULL}, 209 { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ds }, NULL, NULL}, 210 { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsr }, NULL, NULL}, 211 { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask }, NULL, NULL}, 212 { DEFINE_FPU_VECT(stmm,0) }, 213 { DEFINE_FPU_VECT(stmm,1) }, 214 { DEFINE_FPU_VECT(stmm,2) }, 215 { DEFINE_FPU_VECT(stmm,3) }, 216 { DEFINE_FPU_VECT(stmm,4) }, 217 { DEFINE_FPU_VECT(stmm,5) }, 218 { DEFINE_FPU_VECT(stmm,6) }, 219 { DEFINE_FPU_VECT(stmm,7) }, 220 { DEFINE_FPU_VECT(xmm,0) }, 221 { DEFINE_FPU_VECT(xmm,1) }, 222 { DEFINE_FPU_VECT(xmm,2) }, 223 { DEFINE_FPU_VECT(xmm,3) }, 224 { DEFINE_FPU_VECT(xmm,4) }, 225 { DEFINE_FPU_VECT(xmm,5) }, 226 { DEFINE_FPU_VECT(xmm,6) }, 227 { DEFINE_FPU_VECT(xmm,7) }, 228 { DEFINE_FPU_VECT(xmm,8) }, 229 { DEFINE_FPU_VECT(xmm,9) }, 230 { DEFINE_FPU_VECT(xmm,10) }, 231 { DEFINE_FPU_VECT(xmm,11) }, 232 { DEFINE_FPU_VECT(xmm,12) }, 233 { DEFINE_FPU_VECT(xmm,13) }, 234 { DEFINE_FPU_VECT(xmm,14) }, 235 { DEFINE_FPU_VECT(xmm,15) }, 236 237 { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL}, 238 { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL}, 239 { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL} 240 }; 241 242 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 243 244 RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64 (Thread &thread, uint32_t concrete_frame_idx) : 245 RegisterContext (thread, concrete_frame_idx), 246 gpr(), 247 fpu(), 248 exc() 249 { 250 uint32_t i; 251 for (i=0; i<kNumErrors; i++) 252 { 253 gpr_errs[i] = -1; 254 fpu_errs[i] = -1; 255 exc_errs[i] = -1; 256 } 257 } 258 259 RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() 260 { 261 } 262 263 264 void 265 RegisterContextDarwin_x86_64::InvalidateAllRegisters () 266 { 267 InvalidateAllRegisterStates(); 268 } 269 270 271 size_t 272 RegisterContextDarwin_x86_64::GetRegisterCount () 273 { 274 assert(k_num_register_infos == k_num_registers); 275 return k_num_registers; 276 } 277 278 279 const RegisterInfo * 280 RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (size_t reg) 281 { 282 assert(k_num_register_infos == k_num_registers); 283 if (reg < k_num_registers) 284 return &g_register_infos[reg]; 285 return NULL; 286 } 287 288 289 size_t 290 RegisterContextDarwin_x86_64::GetRegisterInfosCount () 291 { 292 return k_num_register_infos; 293 } 294 295 const lldb_private::RegisterInfo * 296 RegisterContextDarwin_x86_64::GetRegisterInfos () 297 { 298 return g_register_infos; 299 } 300 301 302 303 static uint32_t g_gpr_regnums[] = 304 { 305 gpr_rax, 306 gpr_rbx, 307 gpr_rcx, 308 gpr_rdx, 309 gpr_rdi, 310 gpr_rsi, 311 gpr_rbp, 312 gpr_rsp, 313 gpr_r8, 314 gpr_r9, 315 gpr_r10, 316 gpr_r11, 317 gpr_r12, 318 gpr_r13, 319 gpr_r14, 320 gpr_r15, 321 gpr_rip, 322 gpr_rflags, 323 gpr_cs, 324 gpr_fs, 325 gpr_gs 326 }; 327 328 static uint32_t g_fpu_regnums[] = 329 { 330 fpu_fcw, 331 fpu_fsw, 332 fpu_ftw, 333 fpu_fop, 334 fpu_ip, 335 fpu_cs, 336 fpu_dp, 337 fpu_ds, 338 fpu_mxcsr, 339 fpu_mxcsrmask, 340 fpu_stmm0, 341 fpu_stmm1, 342 fpu_stmm2, 343 fpu_stmm3, 344 fpu_stmm4, 345 fpu_stmm5, 346 fpu_stmm6, 347 fpu_stmm7, 348 fpu_xmm0, 349 fpu_xmm1, 350 fpu_xmm2, 351 fpu_xmm3, 352 fpu_xmm4, 353 fpu_xmm5, 354 fpu_xmm6, 355 fpu_xmm7, 356 fpu_xmm8, 357 fpu_xmm9, 358 fpu_xmm10, 359 fpu_xmm11, 360 fpu_xmm12, 361 fpu_xmm13, 362 fpu_xmm14, 363 fpu_xmm15 364 }; 365 366 static uint32_t 367 g_exc_regnums[] = 368 { 369 exc_trapno, 370 exc_err, 371 exc_faultvaddr 372 }; 373 374 // Number of registers in each register set 375 const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums); 376 const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums); 377 const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums); 378 379 //---------------------------------------------------------------------- 380 // Register set definitions. The first definitions at register set index 381 // of zero is for all registers, followed by other registers sets. The 382 // register information for the all register set need not be filled in. 383 //---------------------------------------------------------------------- 384 static const RegisterSet g_reg_sets[] = 385 { 386 { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, }, 387 { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }, 388 { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums } 389 }; 390 391 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets); 392 393 394 size_t 395 RegisterContextDarwin_x86_64::GetRegisterSetCount () 396 { 397 return k_num_regsets; 398 } 399 400 const RegisterSet * 401 RegisterContextDarwin_x86_64::GetRegisterSet (size_t reg_set) 402 { 403 if (reg_set < k_num_regsets) 404 return &g_reg_sets[reg_set]; 405 return NULL; 406 } 407 408 int 409 RegisterContextDarwin_x86_64::GetSetForNativeRegNum (int reg_num) 410 { 411 if (reg_num < fpu_fcw) 412 return GPRRegSet; 413 else if (reg_num < exc_trapno) 414 return FPURegSet; 415 else if (reg_num < k_num_registers) 416 return EXCRegSet; 417 return -1; 418 } 419 420 void 421 RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) 422 { 423 if (log) 424 { 425 if (format) 426 { 427 va_list args; 428 va_start (args, format); 429 log->VAPrintf (format, args); 430 va_end (args); 431 } 432 for (uint32_t i=0; i<k_num_gpr_registers; i++) 433 { 434 uint32_t reg = gpr_rax + i; 435 log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name, (&gpr.rax)[reg]); 436 } 437 } 438 } 439 440 int 441 RegisterContextDarwin_x86_64::ReadGPR (bool force) 442 { 443 int set = GPRRegSet; 444 if (force || !RegisterSetIsCached(set)) 445 { 446 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); 447 } 448 return GetError(GPRRegSet, Read); 449 } 450 451 int 452 RegisterContextDarwin_x86_64::ReadFPU (bool force) 453 { 454 int set = FPURegSet; 455 if (force || !RegisterSetIsCached(set)) 456 { 457 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); 458 } 459 return GetError(FPURegSet, Read); 460 } 461 462 int 463 RegisterContextDarwin_x86_64::ReadEXC (bool force) 464 { 465 int set = EXCRegSet; 466 if (force || !RegisterSetIsCached(set)) 467 { 468 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); 469 } 470 return GetError(EXCRegSet, Read); 471 } 472 473 int 474 RegisterContextDarwin_x86_64::WriteGPR () 475 { 476 int set = GPRRegSet; 477 if (!RegisterSetIsCached(set)) 478 { 479 SetError (set, Write, -1); 480 return -1; 481 } 482 SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr)); 483 SetError (set, Read, -1); 484 return GetError (set, Write); 485 } 486 487 int 488 RegisterContextDarwin_x86_64::WriteFPU () 489 { 490 int set = FPURegSet; 491 if (!RegisterSetIsCached(set)) 492 { 493 SetError (set, Write, -1); 494 return -1; 495 } 496 SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu)); 497 SetError (set, Read, -1); 498 return GetError (set, Write); 499 } 500 501 int 502 RegisterContextDarwin_x86_64::WriteEXC () 503 { 504 int set = EXCRegSet; 505 if (!RegisterSetIsCached(set)) 506 { 507 SetError (set, Write, -1); 508 return -1; 509 } 510 SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc)); 511 SetError (set, Read, -1); 512 return GetError (set, Write); 513 } 514 515 int 516 RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) 517 { 518 switch (set) 519 { 520 case GPRRegSet: return ReadGPR (force); 521 case FPURegSet: return ReadFPU (force); 522 case EXCRegSet: return ReadEXC (force); 523 default: break; 524 } 525 return -1; 526 } 527 528 int 529 RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) 530 { 531 // Make sure we have a valid context to set. 532 switch (set) 533 { 534 case GPRRegSet: return WriteGPR (); 535 case FPURegSet: return WriteFPU (); 536 case EXCRegSet: return WriteEXC (); 537 default: break; 538 } 539 return -1; 540 } 541 542 543 bool 544 RegisterContextDarwin_x86_64::ReadRegister (const RegisterInfo *reg_info, 545 RegisterValue &value) 546 { 547 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 548 int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg); 549 if (set == -1) 550 return false; 551 552 if (ReadRegisterSet(set, false) != 0) 553 return false; 554 555 switch (reg) 556 { 557 case gpr_rax: 558 case gpr_rbx: 559 case gpr_rcx: 560 case gpr_rdx: 561 case gpr_rdi: 562 case gpr_rsi: 563 case gpr_rbp: 564 case gpr_rsp: 565 case gpr_r8: 566 case gpr_r9: 567 case gpr_r10: 568 case gpr_r11: 569 case gpr_r12: 570 case gpr_r13: 571 case gpr_r14: 572 case gpr_r15: 573 case gpr_rip: 574 case gpr_rflags: 575 case gpr_cs: 576 case gpr_fs: 577 case gpr_gs: 578 value = (&gpr.rax)[reg - gpr_rax]; 579 break; 580 581 case fpu_fcw: 582 value = fpu.fcw; 583 break; 584 585 case fpu_fsw: 586 value = fpu.fsw; 587 break; 588 589 case fpu_ftw: 590 value = fpu.ftw; 591 break; 592 593 case fpu_fop: 594 value = fpu.fop; 595 break; 596 597 case fpu_ip: 598 value = fpu.ip; 599 break; 600 601 case fpu_cs: 602 value = fpu.cs; 603 break; 604 605 case fpu_dp: 606 value = fpu.dp; 607 break; 608 609 case fpu_ds: 610 value = fpu.ds; 611 break; 612 613 case fpu_mxcsr: 614 value = fpu.mxcsr; 615 break; 616 617 case fpu_mxcsrmask: 618 value = fpu.mxcsrmask; 619 break; 620 621 case fpu_stmm0: 622 case fpu_stmm1: 623 case fpu_stmm2: 624 case fpu_stmm3: 625 case fpu_stmm4: 626 case fpu_stmm5: 627 case fpu_stmm6: 628 case fpu_stmm7: 629 value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, endian::InlHostByteOrder()); 630 break; 631 632 case fpu_xmm0: 633 case fpu_xmm1: 634 case fpu_xmm2: 635 case fpu_xmm3: 636 case fpu_xmm4: 637 case fpu_xmm5: 638 case fpu_xmm6: 639 case fpu_xmm7: 640 case fpu_xmm8: 641 case fpu_xmm9: 642 case fpu_xmm10: 643 case fpu_xmm11: 644 case fpu_xmm12: 645 case fpu_xmm13: 646 case fpu_xmm14: 647 case fpu_xmm15: 648 value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, endian::InlHostByteOrder()); 649 break; 650 651 case exc_trapno: 652 value = exc.trapno; 653 break; 654 655 case exc_err: 656 value = exc.err; 657 break; 658 659 case exc_faultvaddr: 660 value = exc.faultvaddr; 661 break; 662 663 default: 664 return false; 665 } 666 return true; 667 } 668 669 670 bool 671 RegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info, 672 const RegisterValue &value) 673 { 674 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 675 int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg); 676 677 if (set == -1) 678 return false; 679 680 if (ReadRegisterSet(set, false) != 0) 681 return false; 682 683 switch (reg) 684 { 685 case gpr_rax: 686 case gpr_rbx: 687 case gpr_rcx: 688 case gpr_rdx: 689 case gpr_rdi: 690 case gpr_rsi: 691 case gpr_rbp: 692 case gpr_rsp: 693 case gpr_r8: 694 case gpr_r9: 695 case gpr_r10: 696 case gpr_r11: 697 case gpr_r12: 698 case gpr_r13: 699 case gpr_r14: 700 case gpr_r15: 701 case gpr_rip: 702 case gpr_rflags: 703 case gpr_cs: 704 case gpr_fs: 705 case gpr_gs: 706 (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64(); 707 break; 708 709 case fpu_fcw: 710 fpu.fcw = value.GetAsUInt16(); 711 break; 712 713 case fpu_fsw: 714 fpu.fsw = value.GetAsUInt16(); 715 break; 716 717 case fpu_ftw: 718 fpu.ftw = value.GetAsUInt8(); 719 break; 720 721 case fpu_fop: 722 fpu.fop = value.GetAsUInt16(); 723 break; 724 725 case fpu_ip: 726 fpu.ip = value.GetAsUInt32(); 727 break; 728 729 case fpu_cs: 730 fpu.cs = value.GetAsUInt16(); 731 break; 732 733 case fpu_dp: 734 fpu.dp = value.GetAsUInt32(); 735 break; 736 737 case fpu_ds: 738 fpu.ds = value.GetAsUInt16(); 739 break; 740 741 case fpu_mxcsr: 742 fpu.mxcsr = value.GetAsUInt32(); 743 break; 744 745 case fpu_mxcsrmask: 746 fpu.mxcsrmask = value.GetAsUInt32(); 747 break; 748 749 case fpu_stmm0: 750 case fpu_stmm1: 751 case fpu_stmm2: 752 case fpu_stmm3: 753 case fpu_stmm4: 754 case fpu_stmm5: 755 case fpu_stmm6: 756 case fpu_stmm7: 757 ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); 758 break; 759 760 case fpu_xmm0: 761 case fpu_xmm1: 762 case fpu_xmm2: 763 case fpu_xmm3: 764 case fpu_xmm4: 765 case fpu_xmm5: 766 case fpu_xmm6: 767 case fpu_xmm7: 768 case fpu_xmm8: 769 case fpu_xmm9: 770 case fpu_xmm10: 771 case fpu_xmm11: 772 case fpu_xmm12: 773 case fpu_xmm13: 774 case fpu_xmm14: 775 case fpu_xmm15: 776 ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); 777 return false; 778 779 case exc_trapno: 780 exc.trapno = value.GetAsUInt32(); 781 break; 782 783 case exc_err: 784 exc.err = value.GetAsUInt32(); 785 break; 786 787 case exc_faultvaddr: 788 exc.faultvaddr = value.GetAsUInt64(); 789 break; 790 791 default: 792 return false; 793 } 794 return WriteRegisterSet(set) == 0; 795 } 796 797 bool 798 RegisterContextDarwin_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 799 { 800 data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); 801 if (data_sp && 802 ReadGPR (false) == 0 && 803 ReadFPU (false) == 0 && 804 ReadEXC (false) == 0) 805 { 806 uint8_t *dst = data_sp->GetBytes(); 807 ::memcpy (dst, &gpr, sizeof(gpr)); 808 dst += sizeof(gpr); 809 810 ::memcpy (dst, &fpu, sizeof(fpu)); 811 dst += sizeof(gpr); 812 813 ::memcpy (dst, &exc, sizeof(exc)); 814 return true; 815 } 816 return false; 817 } 818 819 bool 820 RegisterContextDarwin_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 821 { 822 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) 823 { 824 const uint8_t *src = data_sp->GetBytes(); 825 ::memcpy (&gpr, src, sizeof(gpr)); 826 src += sizeof(gpr); 827 828 ::memcpy (&fpu, src, sizeof(fpu)); 829 src += sizeof(gpr); 830 831 ::memcpy (&exc, src, sizeof(exc)); 832 uint32_t success_count = 0; 833 if (WriteGPR() == 0) 834 ++success_count; 835 if (WriteFPU() == 0) 836 ++success_count; 837 if (WriteEXC() == 0) 838 ++success_count; 839 return success_count == 3; 840 } 841 return false; 842 } 843 844 845 uint32_t 846 RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg) 847 { 848 if (kind == eRegisterKindGeneric) 849 { 850 switch (reg) 851 { 852 case LLDB_REGNUM_GENERIC_PC: return gpr_rip; 853 case LLDB_REGNUM_GENERIC_SP: return gpr_rsp; 854 case LLDB_REGNUM_GENERIC_FP: return gpr_rbp; 855 case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags; 856 case LLDB_REGNUM_GENERIC_RA: 857 default: 858 break; 859 } 860 } 861 else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) 862 { 863 switch (reg) 864 { 865 case ehframe_dwarf_gpr_rax: return gpr_rax; 866 case ehframe_dwarf_gpr_rdx: return gpr_rdx; 867 case ehframe_dwarf_gpr_rcx: return gpr_rcx; 868 case ehframe_dwarf_gpr_rbx: return gpr_rbx; 869 case ehframe_dwarf_gpr_rsi: return gpr_rsi; 870 case ehframe_dwarf_gpr_rdi: return gpr_rdi; 871 case ehframe_dwarf_gpr_rbp: return gpr_rbp; 872 case ehframe_dwarf_gpr_rsp: return gpr_rsp; 873 case ehframe_dwarf_gpr_r8: return gpr_r8; 874 case ehframe_dwarf_gpr_r9: return gpr_r9; 875 case ehframe_dwarf_gpr_r10: return gpr_r10; 876 case ehframe_dwarf_gpr_r11: return gpr_r11; 877 case ehframe_dwarf_gpr_r12: return gpr_r12; 878 case ehframe_dwarf_gpr_r13: return gpr_r13; 879 case ehframe_dwarf_gpr_r14: return gpr_r14; 880 case ehframe_dwarf_gpr_r15: return gpr_r15; 881 case ehframe_dwarf_gpr_rip: return gpr_rip; 882 case ehframe_dwarf_fpu_xmm0: return fpu_xmm0; 883 case ehframe_dwarf_fpu_xmm1: return fpu_xmm1; 884 case ehframe_dwarf_fpu_xmm2: return fpu_xmm2; 885 case ehframe_dwarf_fpu_xmm3: return fpu_xmm3; 886 case ehframe_dwarf_fpu_xmm4: return fpu_xmm4; 887 case ehframe_dwarf_fpu_xmm5: return fpu_xmm5; 888 case ehframe_dwarf_fpu_xmm6: return fpu_xmm6; 889 case ehframe_dwarf_fpu_xmm7: return fpu_xmm7; 890 case ehframe_dwarf_fpu_xmm8: return fpu_xmm8; 891 case ehframe_dwarf_fpu_xmm9: return fpu_xmm9; 892 case ehframe_dwarf_fpu_xmm10: return fpu_xmm10; 893 case ehframe_dwarf_fpu_xmm11: return fpu_xmm11; 894 case ehframe_dwarf_fpu_xmm12: return fpu_xmm12; 895 case ehframe_dwarf_fpu_xmm13: return fpu_xmm13; 896 case ehframe_dwarf_fpu_xmm14: return fpu_xmm14; 897 case ehframe_dwarf_fpu_xmm15: return fpu_xmm15; 898 case ehframe_dwarf_fpu_stmm0: return fpu_stmm0; 899 case ehframe_dwarf_fpu_stmm1: return fpu_stmm1; 900 case ehframe_dwarf_fpu_stmm2: return fpu_stmm2; 901 case ehframe_dwarf_fpu_stmm3: return fpu_stmm3; 902 case ehframe_dwarf_fpu_stmm4: return fpu_stmm4; 903 case ehframe_dwarf_fpu_stmm5: return fpu_stmm5; 904 case ehframe_dwarf_fpu_stmm6: return fpu_stmm6; 905 case ehframe_dwarf_fpu_stmm7: return fpu_stmm7; 906 default: 907 break; 908 } 909 } 910 else if (kind == eRegisterKindLLDB) 911 { 912 return reg; 913 } 914 return LLDB_INVALID_REGNUM; 915 } 916 917 bool 918 RegisterContextDarwin_x86_64::HardwareSingleStep (bool enable) 919 { 920 if (ReadGPR(true) != 0) 921 return false; 922 923 const uint64_t trace_bit = 0x100ull; 924 if (enable) 925 { 926 927 if (gpr.rflags & trace_bit) 928 return true; // trace bit is already set, there is nothing to do 929 else 930 gpr.rflags |= trace_bit; 931 } 932 else 933 { 934 if (gpr.rflags & trace_bit) 935 gpr.rflags &= ~trace_bit; 936 else 937 return true; // trace bit is clear, there is nothing to do 938 } 939 940 return WriteGPR() == 0; 941 } 942 943