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