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