DNBArchImplI386.cpp revision a9091cc0d3686dd93718a320057153c4aabf091a
1//===-- DNBArchImplI386.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// Created by Greg Clayton on 6/25/07. 11// 12//===----------------------------------------------------------------------===// 13 14#if defined (__i386__) || defined (__x86_64__) 15 16#include <sys/cdefs.h> 17 18#include "MacOSX/i386/DNBArchImplI386.h" 19#include "DNBLog.h" 20#include "MachThread.h" 21#include "MachProcess.h" 22 23extern "C" bool CPUHasAVX(); // Defined over in DNBArchImplX86_64.cpp 24 25#if defined (LLDB_DEBUGSERVER_RELEASE) || defined (LLDB_DEBUGSERVER_DEBUG) 26enum debugState { 27 debugStateUnknown, 28 debugStateOff, 29 debugStateOn 30}; 31 32static debugState sFPUDebugState = debugStateUnknown; 33static debugState sAVXForceState = debugStateUnknown; 34 35static bool DebugFPURegs () 36{ 37 if (sFPUDebugState == debugStateUnknown) 38 { 39 if (getenv("DNB_DEBUG_FPU_REGS")) 40 sFPUDebugState = debugStateOn; 41 else 42 sFPUDebugState = debugStateOff; 43 } 44 45 return (sFPUDebugState == debugStateOn); 46} 47 48static bool ForceAVXRegs () 49{ 50 if (sFPUDebugState == debugStateUnknown) 51 { 52 if (getenv("DNB_DEBUG_X86_FORCE_AVX_REGS")) 53 sAVXForceState = debugStateOn; 54 else 55 sAVXForceState = debugStateOff; 56 } 57 58 return (sAVXForceState == debugStateOn); 59} 60 61#define DEBUG_FPU_REGS (DebugFPURegs()) 62#define FORCE_AVX_REGS (ForceAVXRegs()) 63#else 64#define DEBUG_FPU_REGS (0) 65#define FORCE_AVX_REGS (0) 66#endif 67 68enum 69{ 70 gpr_eax = 0, 71 gpr_ebx = 1, 72 gpr_ecx = 2, 73 gpr_edx = 3, 74 gpr_edi = 4, 75 gpr_esi = 5, 76 gpr_ebp = 6, 77 gpr_esp = 7, 78 gpr_ss = 8, 79 gpr_eflags = 9, 80 gpr_eip = 10, 81 gpr_cs = 11, 82 gpr_ds = 12, 83 gpr_es = 13, 84 gpr_fs = 14, 85 gpr_gs = 15, 86 k_num_gpr_regs 87}; 88 89enum { 90 fpu_fcw, 91 fpu_fsw, 92 fpu_ftw, 93 fpu_fop, 94 fpu_ip, 95 fpu_cs, 96 fpu_dp, 97 fpu_ds, 98 fpu_mxcsr, 99 fpu_mxcsrmask, 100 fpu_stmm0, 101 fpu_stmm1, 102 fpu_stmm2, 103 fpu_stmm3, 104 fpu_stmm4, 105 fpu_stmm5, 106 fpu_stmm6, 107 fpu_stmm7, 108 fpu_xmm0, 109 fpu_xmm1, 110 fpu_xmm2, 111 fpu_xmm3, 112 fpu_xmm4, 113 fpu_xmm5, 114 fpu_xmm6, 115 fpu_xmm7, 116 fpu_ymm0, 117 fpu_ymm1, 118 fpu_ymm2, 119 fpu_ymm3, 120 fpu_ymm4, 121 fpu_ymm5, 122 fpu_ymm6, 123 fpu_ymm7, 124 k_num_fpu_regs, 125 126 // Aliases 127 fpu_fctrl = fpu_fcw, 128 fpu_fstat = fpu_fsw, 129 fpu_ftag = fpu_ftw, 130 fpu_fiseg = fpu_cs, 131 fpu_fioff = fpu_ip, 132 fpu_foseg = fpu_ds, 133 fpu_fooff = fpu_dp 134}; 135 136enum { 137 exc_trapno, 138 exc_err, 139 exc_faultvaddr, 140 k_num_exc_regs, 141}; 142 143 144enum 145{ 146 gcc_eax = 0, 147 gcc_ecx, 148 gcc_edx, 149 gcc_ebx, 150 gcc_ebp, 151 gcc_esp, 152 gcc_esi, 153 gcc_edi, 154 gcc_eip, 155 gcc_eflags 156}; 157 158enum 159{ 160 dwarf_eax = 0, 161 dwarf_ecx, 162 dwarf_edx, 163 dwarf_ebx, 164 dwarf_esp, 165 dwarf_ebp, 166 dwarf_esi, 167 dwarf_edi, 168 dwarf_eip, 169 dwarf_eflags, 170 dwarf_stmm0 = 11, 171 dwarf_stmm1, 172 dwarf_stmm2, 173 dwarf_stmm3, 174 dwarf_stmm4, 175 dwarf_stmm5, 176 dwarf_stmm6, 177 dwarf_stmm7, 178 dwarf_xmm0 = 21, 179 dwarf_xmm1, 180 dwarf_xmm2, 181 dwarf_xmm3, 182 dwarf_xmm4, 183 dwarf_xmm5, 184 dwarf_xmm6, 185 dwarf_xmm7, 186 dwarf_ymm0 = dwarf_xmm0, 187 dwarf_ymm1 = dwarf_xmm1, 188 dwarf_ymm2 = dwarf_xmm2, 189 dwarf_ymm3 = dwarf_xmm3, 190 dwarf_ymm4 = dwarf_xmm4, 191 dwarf_ymm5 = dwarf_xmm5, 192 dwarf_ymm6 = dwarf_xmm6, 193 dwarf_ymm7 = dwarf_xmm7, 194}; 195 196enum 197{ 198 gdb_eax = 0, 199 gdb_ecx = 1, 200 gdb_edx = 2, 201 gdb_ebx = 3, 202 gdb_esp = 4, 203 gdb_ebp = 5, 204 gdb_esi = 6, 205 gdb_edi = 7, 206 gdb_eip = 8, 207 gdb_eflags = 9, 208 gdb_cs = 10, 209 gdb_ss = 11, 210 gdb_ds = 12, 211 gdb_es = 13, 212 gdb_fs = 14, 213 gdb_gs = 15, 214 gdb_stmm0 = 16, 215 gdb_stmm1 = 17, 216 gdb_stmm2 = 18, 217 gdb_stmm3 = 19, 218 gdb_stmm4 = 20, 219 gdb_stmm5 = 21, 220 gdb_stmm6 = 22, 221 gdb_stmm7 = 23, 222 gdb_fctrl = 24, gdb_fcw = gdb_fctrl, 223 gdb_fstat = 25, gdb_fsw = gdb_fstat, 224 gdb_ftag = 26, gdb_ftw = gdb_ftag, 225 gdb_fiseg = 27, gdb_fpu_cs = gdb_fiseg, 226 gdb_fioff = 28, gdb_ip = gdb_fioff, 227 gdb_foseg = 29, gdb_fpu_ds = gdb_foseg, 228 gdb_fooff = 30, gdb_dp = gdb_fooff, 229 gdb_fop = 31, 230 gdb_xmm0 = 32, 231 gdb_xmm1 = 33, 232 gdb_xmm2 = 34, 233 gdb_xmm3 = 35, 234 gdb_xmm4 = 36, 235 gdb_xmm5 = 37, 236 gdb_xmm6 = 38, 237 gdb_xmm7 = 39, 238 gdb_mxcsr = 40, 239 gdb_mm0 = 41, 240 gdb_mm1 = 42, 241 gdb_mm2 = 43, 242 gdb_mm3 = 44, 243 gdb_mm4 = 45, 244 gdb_mm5 = 46, 245 gdb_mm6 = 47, 246 gdb_mm7 = 48, 247 gdb_ymm0 = gdb_xmm0, 248 gdb_ymm1 = gdb_xmm1, 249 gdb_ymm2 = gdb_xmm2, 250 gdb_ymm3 = gdb_xmm3, 251 gdb_ymm4 = gdb_xmm4, 252 gdb_ymm5 = gdb_xmm5, 253 gdb_ymm6 = gdb_xmm6, 254 gdb_ymm7 = gdb_xmm7 255}; 256 257uint64_t 258DNBArchImplI386::GetPC(uint64_t failValue) 259{ 260 // Get program counter 261 if (GetGPRState(false) == KERN_SUCCESS) 262 return m_state.context.gpr.__eip; 263 return failValue; 264} 265 266kern_return_t 267DNBArchImplI386::SetPC(uint64_t value) 268{ 269 // Get program counter 270 kern_return_t err = GetGPRState(false); 271 if (err == KERN_SUCCESS) 272 { 273 m_state.context.gpr.__eip = value; 274 err = SetGPRState(); 275 } 276 return err == KERN_SUCCESS; 277} 278 279uint64_t 280DNBArchImplI386::GetSP(uint64_t failValue) 281{ 282 // Get stack pointer 283 if (GetGPRState(false) == KERN_SUCCESS) 284 return m_state.context.gpr.__esp; 285 return failValue; 286} 287 288// Uncomment the value below to verify the values in the debugger. 289//#define DEBUG_GPR_VALUES 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED 290//#define SET_GPR(reg) m_state.context.gpr.__##reg = gpr_##reg 291 292kern_return_t 293DNBArchImplI386::GetGPRState(bool force) 294{ 295 if (force || m_state.GetError(e_regSetGPR, Read)) 296 { 297#if DEBUG_GPR_VALUES 298 SET_GPR(eax); 299 SET_GPR(ebx); 300 SET_GPR(ecx); 301 SET_GPR(edx); 302 SET_GPR(edi); 303 SET_GPR(esi); 304 SET_GPR(ebp); 305 SET_GPR(esp); 306 SET_GPR(ss); 307 SET_GPR(eflags); 308 SET_GPR(eip); 309 SET_GPR(cs); 310 SET_GPR(ds); 311 SET_GPR(es); 312 SET_GPR(fs); 313 SET_GPR(gs); 314 m_state.SetError(e_regSetGPR, Read, 0); 315#else 316 mach_msg_type_number_t count = e_regSetWordSizeGPR; 317 m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count)); 318#endif 319 } 320 return m_state.GetError(e_regSetGPR, Read); 321} 322 323// Uncomment the value below to verify the values in the debugger. 324//#define DEBUG_FPU_VALUES 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED 325 326kern_return_t 327DNBArchImplI386::GetFPUState(bool force) 328{ 329 if (force || m_state.GetError(e_regSetFPU, Read)) 330 { 331 if (DEBUG_FPU_REGS) 332 { 333 if (CPUHasAVX() || FORCE_AVX_REGS) 334 { 335 m_state.context.fpu.avx.__fpu_reserved[0] = -1; 336 m_state.context.fpu.avx.__fpu_reserved[1] = -1; 337 *(uint16_t *)&(m_state.context.fpu.avx.__fpu_fcw) = 0x1234; 338 *(uint16_t *)&(m_state.context.fpu.avx.__fpu_fsw) = 0x5678; 339 m_state.context.fpu.avx.__fpu_ftw = 1; 340 m_state.context.fpu.avx.__fpu_rsrv1 = UINT8_MAX; 341 m_state.context.fpu.avx.__fpu_fop = 2; 342 m_state.context.fpu.avx.__fpu_ip = 3; 343 m_state.context.fpu.avx.__fpu_cs = 4; 344 m_state.context.fpu.avx.__fpu_rsrv2 = 5; 345 m_state.context.fpu.avx.__fpu_dp = 6; 346 m_state.context.fpu.avx.__fpu_ds = 7; 347 m_state.context.fpu.avx.__fpu_rsrv3 = UINT16_MAX; 348 m_state.context.fpu.avx.__fpu_mxcsr = 8; 349 m_state.context.fpu.avx.__fpu_mxcsrmask = 9; 350 int i; 351 for (i=0; i<16; ++i) 352 { 353 if (i<10) 354 { 355 m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg[i] = 'a'; 356 m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg[i] = 'b'; 357 m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg[i] = 'c'; 358 m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg[i] = 'd'; 359 m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg[i] = 'e'; 360 m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg[i] = 'f'; 361 m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg[i] = 'g'; 362 m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg[i] = 'h'; 363 } 364 else 365 { 366 m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN; 367 m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN; 368 m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN; 369 m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN; 370 m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN; 371 m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN; 372 m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN; 373 m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN; 374 } 375 376 m_state.context.fpu.avx.__fpu_xmm0.__xmm_reg[i] = '0'; 377 m_state.context.fpu.avx.__fpu_xmm1.__xmm_reg[i] = '1'; 378 m_state.context.fpu.avx.__fpu_xmm2.__xmm_reg[i] = '2'; 379 m_state.context.fpu.avx.__fpu_xmm3.__xmm_reg[i] = '3'; 380 m_state.context.fpu.avx.__fpu_xmm4.__xmm_reg[i] = '4'; 381 m_state.context.fpu.avx.__fpu_xmm5.__xmm_reg[i] = '5'; 382 m_state.context.fpu.avx.__fpu_xmm6.__xmm_reg[i] = '6'; 383 m_state.context.fpu.avx.__fpu_xmm7.__xmm_reg[i] = '7'; 384 } 385 for (i=0; i<sizeof(m_state.context.fpu.avx.__fpu_rsrv4); ++i) 386 m_state.context.fpu.avx.__fpu_rsrv4[i] = INT8_MIN; 387 m_state.context.fpu.avx.__fpu_reserved1 = -1; 388 for (i=0; i<sizeof(m_state.context.fpu.avx.__avx_reserved1); ++i) 389 m_state.context.fpu.avx.__avx_reserved1[i] = INT8_MIN; 390 391 for (i = 0; i < 16; ++i) 392 { 393 m_state.context.fpu.avx.__fpu_ymmh0.__xmm_reg[i] = '0'; 394 m_state.context.fpu.avx.__fpu_ymmh1.__xmm_reg[i] = '1'; 395 m_state.context.fpu.avx.__fpu_ymmh2.__xmm_reg[i] = '2'; 396 m_state.context.fpu.avx.__fpu_ymmh3.__xmm_reg[i] = '3'; 397 m_state.context.fpu.avx.__fpu_ymmh4.__xmm_reg[i] = '4'; 398 m_state.context.fpu.avx.__fpu_ymmh5.__xmm_reg[i] = '5'; 399 m_state.context.fpu.avx.__fpu_ymmh6.__xmm_reg[i] = '6'; 400 m_state.context.fpu.avx.__fpu_ymmh7.__xmm_reg[i] = '7'; 401 } 402 } 403 else 404 { 405 m_state.context.fpu.no_avx.__fpu_reserved[0] = -1; 406 m_state.context.fpu.no_avx.__fpu_reserved[1] = -1; 407 *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fcw) = 0x1234; 408 *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fsw) = 0x5678; 409 m_state.context.fpu.no_avx.__fpu_ftw = 1; 410 m_state.context.fpu.no_avx.__fpu_rsrv1 = UINT8_MAX; 411 m_state.context.fpu.no_avx.__fpu_fop = 2; 412 m_state.context.fpu.no_avx.__fpu_ip = 3; 413 m_state.context.fpu.no_avx.__fpu_cs = 4; 414 m_state.context.fpu.no_avx.__fpu_rsrv2 = 5; 415 m_state.context.fpu.no_avx.__fpu_dp = 6; 416 m_state.context.fpu.no_avx.__fpu_ds = 7; 417 m_state.context.fpu.no_avx.__fpu_rsrv3 = UINT16_MAX; 418 m_state.context.fpu.no_avx.__fpu_mxcsr = 8; 419 m_state.context.fpu.no_avx.__fpu_mxcsrmask = 9; 420 int i; 421 for (i=0; i<16; ++i) 422 { 423 if (i<10) 424 { 425 m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = 'a'; 426 m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = 'b'; 427 m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = 'c'; 428 m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = 'd'; 429 m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = 'e'; 430 m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = 'f'; 431 m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = 'g'; 432 m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = 'h'; 433 } 434 else 435 { 436 m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN; 437 m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN; 438 m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN; 439 m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN; 440 m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN; 441 m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN; 442 m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN; 443 m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN; 444 } 445 446 m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg[i] = '0'; 447 m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg[i] = '1'; 448 m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg[i] = '2'; 449 m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg[i] = '3'; 450 m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg[i] = '4'; 451 m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg[i] = '5'; 452 m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg[i] = '6'; 453 m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg[i] = '7'; 454 } 455 for (i=0; i<sizeof(m_state.context.fpu.avx.__fpu_rsrv4); ++i) 456 m_state.context.fpu.no_avx.__fpu_rsrv4[i] = INT8_MIN; 457 m_state.context.fpu.no_avx.__fpu_reserved1 = -1; 458 } 459 m_state.SetError(e_regSetFPU, Read, 0); 460 } 461 else 462 { 463 if (CPUHasAVX() || FORCE_AVX_REGS) 464 { 465 mach_msg_type_number_t count = e_regSetWordSizeAVX; 466 m_state.SetError (e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count)); 467 DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &avx, %u (%u passed in)) => 0x%8.8x", 468 m_thread->ThreadID(), __i386_AVX_STATE, count, e_regSetWordSizeAVX, 469 m_state.GetError(e_regSetFPU, Read)); 470 } 471 else 472 { 473 mach_msg_type_number_t count = e_regSetWordSizeFPU; 474 m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count)); 475 DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &fpu, %u (%u passed in) => 0x%8.8x", 476 m_thread->ThreadID(), __i386_FLOAT_STATE, count, e_regSetWordSizeFPU, 477 m_state.GetError(e_regSetFPU, Read)); 478 } 479 } 480 } 481 return m_state.GetError(e_regSetFPU, Read); 482} 483 484kern_return_t 485DNBArchImplI386::GetEXCState(bool force) 486{ 487 if (force || m_state.GetError(e_regSetEXC, Read)) 488 { 489 mach_msg_type_number_t count = e_regSetWordSizeEXC; 490 m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count)); 491 } 492 return m_state.GetError(e_regSetEXC, Read); 493} 494 495kern_return_t 496DNBArchImplI386::SetGPRState() 497{ 498 m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR)); 499 return m_state.GetError(e_regSetGPR, Write); 500} 501 502kern_return_t 503DNBArchImplI386::SetFPUState() 504{ 505 if (DEBUG_FPU_REGS) 506 { 507 m_state.SetError(e_regSetFPU, Write, 0); 508 return m_state.GetError(e_regSetFPU, Write); 509 } 510 else 511 { 512 if (CPUHasAVX() || FORCE_AVX_REGS) 513 m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX)); 514 else 515 m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU)); 516 return m_state.GetError(e_regSetFPU, Write); 517 } 518} 519 520kern_return_t 521DNBArchImplI386::SetEXCState() 522{ 523 m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC)); 524 return m_state.GetError(e_regSetEXC, Write); 525} 526 527kern_return_t 528DNBArchImplI386::GetDBGState(bool force) 529{ 530 if (force || m_state.GetError(e_regSetDBG, Read)) 531 { 532 mach_msg_type_number_t count = e_regSetWordSizeDBG; 533 m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->ThreadID(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count)); 534 } 535 return m_state.GetError(e_regSetDBG, Read); 536} 537 538kern_return_t 539DNBArchImplI386::SetDBGState() 540{ 541 m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->ThreadID(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG)); 542 return m_state.GetError(e_regSetDBG, Write); 543} 544 545void 546DNBArchImplI386::ThreadWillResume() 547{ 548 // Do we need to step this thread? If so, let the mach thread tell us so. 549 if (m_thread->IsStepping()) 550 { 551 // This is the primary thread, let the arch do anything it needs 552 EnableHardwareSingleStep(true); 553 } 554 555 // Reset the debug status register, if necessary, before we resume. 556 kern_return_t kret = GetDBGState(false); 557 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); 558 if (kret != KERN_SUCCESS) 559 return; 560 561 DBG &debug_state = m_state.context.dbg; 562 bool need_reset = false; 563 uint32_t i, num = NumSupportedHardwareWatchpoints(); 564 for (i = 0; i < num; ++i) 565 if (IsWatchpointHit(debug_state, i)) 566 need_reset = true; 567 568 if (need_reset) 569 { 570 ClearWatchpointHits(debug_state); 571 kret = SetDBGState(); 572 DNBLogThreadedIf(LOG_WATCHPOINTS,"DNBArchImplI386::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); 573 } 574} 575 576bool 577DNBArchImplI386::ThreadDidStop() 578{ 579 bool success = true; 580 581 m_state.InvalidateAllRegisterStates(); 582 583 // Are we stepping a single instruction? 584 if (GetGPRState(true) == KERN_SUCCESS) 585 { 586 // We are single stepping, was this the primary thread? 587 if (m_thread->IsStepping()) 588 { 589 // This was the primary thread, we need to clear the trace 590 // bit if so. 591 success = EnableHardwareSingleStep(false) == KERN_SUCCESS; 592 } 593 else 594 { 595 // The MachThread will automatically restore the suspend count 596 // in ThreadDidStop(), so we don't need to do anything here if 597 // we weren't the primary thread the last time 598 } 599 } 600 return success; 601} 602 603bool 604DNBArchImplI386::NotifyException(MachException::Data& exc) 605{ 606 switch (exc.exc_type) 607 { 608 case EXC_BAD_ACCESS: 609 break; 610 case EXC_BAD_INSTRUCTION: 611 break; 612 case EXC_ARITHMETIC: 613 break; 614 case EXC_EMULATION: 615 break; 616 case EXC_SOFTWARE: 617 break; 618 case EXC_BREAKPOINT: 619 if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) 620 { 621 // exc_code = EXC_I386_BPT 622 // 623 nub_addr_t pc = GetPC(INVALID_NUB_ADDRESS); 624 if (pc != INVALID_NUB_ADDRESS && pc > 0) 625 { 626 pc -= 1; 627 // Check for a breakpoint at one byte prior to the current PC value 628 // since the PC will be just past the trap. 629 630 nub_break_t breakID = m_thread->Process()->Breakpoints().FindIDByAddress(pc); 631 if (NUB_BREAK_ID_IS_VALID(breakID)) 632 { 633 // Backup the PC for i386 since the trap was taken and the PC 634 // is at the address following the single byte trap instruction. 635 if (m_state.context.gpr.__eip > 0) 636 { 637 m_state.context.gpr.__eip = pc; 638 // Write the new PC back out 639 SetGPRState (); 640 } 641 } 642 return true; 643 } 644 } 645 else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) 646 { 647 // exc_code = EXC_I386_SGL 648 // 649 // Check whether this corresponds to a watchpoint hit event. 650 // If yes, set the exc_sub_code to the data break address. 651 nub_addr_t addr = 0; 652 uint32_t hw_index = GetHardwareWatchpointHit(addr); 653 if (hw_index != INVALID_NUB_HW_INDEX) 654 { 655 exc.exc_data[1] = addr; 656 // Piggyback the hw_index in the exc.data. 657 exc.exc_data.push_back(hw_index); 658 } 659 660 return true; 661 } 662 break; 663 case EXC_SYSCALL: 664 break; 665 case EXC_MACH_SYSCALL: 666 break; 667 case EXC_RPC_ALERT: 668 break; 669 } 670 return false; 671} 672 673uint32_t 674DNBArchImplI386::NumSupportedHardwareWatchpoints() 675{ 676 // Available debug address registers: dr0, dr1, dr2, dr3. 677 return 4; 678} 679 680static uint32_t 681size_and_rw_bits(nub_size_t size, bool read, bool write) 682{ 683 uint32_t rw; 684 if (read) { 685 rw = 0x3; // READ or READ/WRITE 686 } else if (write) { 687 rw = 0x1; // WRITE 688 } else { 689 assert(0 && "read and write cannot both be false"); 690 } 691 692 switch (size) { 693 case 1: 694 return rw; 695 case 2: 696 return (0x1 << 2) | rw; 697 case 4: 698 return (0x3 << 2) | rw; 699 case 8: 700 return (0x2 << 2) | rw; 701 default: 702 assert(0 && "invalid size, must be one of 1, 2, 4, or 8"); 703 } 704} 705void 706DNBArchImplI386::SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write) 707{ 708 // Set both dr7 (debug control register) and dri (debug address register). 709 710 // dr7{7-0} encodes the local/gloabl enable bits: 711 // global enable --. .-- local enable 712 // | | 713 // v v 714 // dr0 -> bits{1-0} 715 // dr1 -> bits{3-2} 716 // dr2 -> bits{5-4} 717 // dr3 -> bits{7-6} 718 // 719 // dr7{31-16} encodes the rw/len bits: 720 // b_x+3, b_x+2, b_x+1, b_x 721 // where bits{x+1, x} => rw 722 // 0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io read-or-write (unused) 723 // and bits{x+3, x+2} => len 724 // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte 725 // 726 // dr0 -> bits{19-16} 727 // dr1 -> bits{23-20} 728 // dr2 -> bits{27-24} 729 // dr3 -> bits{31-28} 730 debug_state.__dr7 |= (1 << (2*hw_index) | 731 size_and_rw_bits(size, read, write) << (16+4*hw_index)); 732 uint32_t addr_32 = addr & 0xffffffff; 733 switch (hw_index) { 734 case 0: 735 debug_state.__dr0 = addr_32; break; 736 case 1: 737 debug_state.__dr1 = addr_32; break; 738 case 2: 739 debug_state.__dr2 = addr_32; break; 740 case 3: 741 debug_state.__dr3 = addr_32; break; 742 default: 743 assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); 744 } 745 return; 746} 747 748void 749DNBArchImplI386::ClearWatchpoint(DBG &debug_state, uint32_t hw_index) 750{ 751 debug_state.__dr7 &= ~(3 << (2*hw_index)); 752 switch (hw_index) { 753 case 0: 754 debug_state.__dr0 = 0; break; 755 case 1: 756 debug_state.__dr1 = 0; break; 757 case 2: 758 debug_state.__dr2 = 0; break; 759 case 3: 760 debug_state.__dr3 = 0; break; 761 default: 762 assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); 763 } 764 return; 765} 766 767bool 768DNBArchImplI386::IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index) 769{ 770 // Check dr7 (debug control register) for local/global enable bits: 771 // global enable --. .-- local enable 772 // | | 773 // v v 774 // dr0 -> bits{1-0} 775 // dr1 -> bits{3-2} 776 // dr2 -> bits{5-4} 777 // dr3 -> bits{7-6} 778 return (debug_state.__dr7 & (3 << (2*hw_index))) == 0; 779} 780 781// Resets local copy of debug status register to wait for the next debug excpetion. 782void 783DNBArchImplI386::ClearWatchpointHits(DBG &debug_state) 784{ 785 // See also IsWatchpointHit(). 786 debug_state.__dr6 = 0; 787 return; 788} 789 790bool 791DNBArchImplI386::IsWatchpointHit(const DBG &debug_state, uint32_t hw_index) 792{ 793 // Check dr6 (debug status register) whether a watchpoint hits: 794 // is watchpoint hit? 795 // | 796 // v 797 // dr0 -> bits{0} 798 // dr1 -> bits{1} 799 // dr2 -> bits{2} 800 // dr3 -> bits{3} 801 return (debug_state.__dr6 & (1 << hw_index)); 802} 803 804nub_addr_t 805DNBArchImplI386::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) 806{ 807 switch (hw_index) { 808 case 0: 809 return debug_state.__dr0; 810 case 1: 811 return debug_state.__dr1; 812 case 2: 813 return debug_state.__dr2; 814 case 3: 815 return debug_state.__dr3; 816 default: 817 assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); 818 } 819} 820 821uint32_t 822DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) 823{ 824 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::EnableHardwareWatchpoint(addr = 0x%llx, size = %zu, read = %u, write = %u)", (uint64_t)addr, size, read, write); 825 826 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 827 828 // Can only watch 1, 2, 4, or 8 bytes. 829 if (!(size == 1 || size == 2 || size == 4 || size == 8)) 830 return INVALID_NUB_HW_INDEX; 831 832 // We must watch for either read or write 833 if (read == false && write == false) 834 return INVALID_NUB_HW_INDEX; 835 836 // Read the debug state 837 kern_return_t kret = GetDBGState(false); 838 839 if (kret == KERN_SUCCESS) 840 { 841 // Check to make sure we have the needed hardware support 842 uint32_t i = 0; 843 844 DBG &debug_state = m_state.context.dbg; 845 for (i = 0; i < num_hw_watchpoints; ++i) 846 { 847 if (IsWatchpointVacant(debug_state, i)) 848 break; 849 } 850 851 // See if we found an available hw breakpoint slot above 852 if (i < num_hw_watchpoints) 853 { 854 // Modify our local copy of the debug state, first. 855 SetWatchpoint(debug_state, i, addr, size, read, write); 856 // Now set the watch point in the inferior. 857 kret = SetDBGState(); 858 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); 859 860 if (kret == KERN_SUCCESS) 861 return i; 862 } 863 else 864 { 865 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); 866 } 867 } 868 return INVALID_NUB_HW_INDEX; 869} 870 871bool 872DNBArchImplI386::DisableHardwareWatchpoint (uint32_t hw_index) 873{ 874 kern_return_t kret = GetDBGState(false); 875 876 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 877 if (kret == KERN_SUCCESS) 878 { 879 DBG &debug_state = m_state.context.dbg; 880 if (hw_index < num_hw_points && !IsWatchpointVacant(debug_state, hw_index)) 881 { 882 // Modify our local copy of the debug state, first. 883 ClearWatchpoint(debug_state, hw_index); 884 // Now disable the watch point in the inferior. 885 kret = SetDBGState(); 886 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::DisableHardwareWatchpoint( %u )", 887 hw_index); 888 889 if (kret == KERN_SUCCESS) 890 return true; 891 } 892 } 893 return false; 894} 895 896DNBArchImplI386::DBG DNBArchImplI386::Global_Debug_State = {0,0,0,0,0,0,0,0}; 897bool DNBArchImplI386::Valid_Global_Debug_State = false; 898 899// Use this callback from MachThread, which in turn was called from MachThreadList, to update 900// the global view of the hardware watchpoint state, so that when new thread comes along, they 901// get to inherit the existing hardware watchpoint state. 902void 903DNBArchImplI386::HardwareWatchpointStateChanged () 904{ 905 Global_Debug_State = m_state.context.dbg; 906 Valid_Global_Debug_State = true; 907} 908 909// Iterate through the debug status register; return the index of the first hit. 910uint32_t 911DNBArchImplI386::GetHardwareWatchpointHit(nub_addr_t &addr) 912{ 913 // Read the debug state 914 kern_return_t kret = GetDBGState(false); 915 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); 916 if (kret == KERN_SUCCESS) 917 { 918 DBG &debug_state = m_state.context.dbg; 919 uint32_t i, num = NumSupportedHardwareWatchpoints(); 920 for (i = 0; i < num; ++i) 921 { 922 if (IsWatchpointHit(debug_state, i)) 923 { 924 addr = GetWatchAddress(debug_state, i); 925 DNBLogThreadedIf(LOG_WATCHPOINTS, 926 "DNBArchImplI386::GetHardwareWatchpointHit() found => %u (addr = 0x%llx).", 927 i, (uint64_t)addr); 928 return i; 929 } 930 } 931 } 932 return INVALID_NUB_HW_INDEX; 933} 934 935// Set the single step bit in the processor status register. 936kern_return_t 937DNBArchImplI386::EnableHardwareSingleStep (bool enable) 938{ 939 if (GetGPRState(false) == KERN_SUCCESS) 940 { 941 const uint32_t trace_bit = 0x100u; 942 if (enable) 943 m_state.context.gpr.__eflags |= trace_bit; 944 else 945 m_state.context.gpr.__eflags &= ~trace_bit; 946 return SetGPRState(); 947 } 948 return m_state.GetError(e_regSetGPR, Read); 949} 950 951 952//---------------------------------------------------------------------- 953// Register information defintions 954//---------------------------------------------------------------------- 955 956 957#define GPR_OFFSET(reg) (offsetof (DNBArchImplI386::GPR, __##reg)) 958#define FPU_OFFSET(reg) (offsetof (DNBArchImplI386::FPU, __fpu_##reg) + offsetof (DNBArchImplI386::Context, fpu.no_avx)) 959#define AVX_OFFSET(reg) (offsetof (DNBArchImplI386::AVX, __fpu_##reg) + offsetof (DNBArchImplI386::Context, fpu.avx)) 960#define EXC_OFFSET(reg) (offsetof (DNBArchImplI386::EXC, __##reg) + offsetof (DNBArchImplI386::Context, exc)) 961 962#define GPR_SIZE(reg) (sizeof(((DNBArchImplI386::GPR *)NULL)->__##reg)) 963#define FPU_SIZE_UINT(reg) (sizeof(((DNBArchImplI386::FPU *)NULL)->__fpu_##reg)) 964#define FPU_SIZE_MMST(reg) (sizeof(((DNBArchImplI386::FPU *)NULL)->__fpu_##reg.__mmst_reg)) 965#define FPU_SIZE_XMM(reg) (sizeof(((DNBArchImplI386::FPU *)NULL)->__fpu_##reg.__xmm_reg)) 966#define FPU_SIZE_YMM(reg) (32) 967#define EXC_SIZE(reg) (sizeof(((DNBArchImplI386::EXC *)NULL)->__##reg)) 968 969// This does not accurately identify the location of ymm0...7 in 970// Context.fpu.avx. That is because there is a bunch of padding 971// in Context.fpu.avx that we don't need. Offset macros lay out 972// the register state that Debugserver transmits to the debugger 973// -- not to interpret the thread_get_state info. 974#define AVX_OFFSET_YMM(n) (AVX_OFFSET(xmm7) + FPU_SIZE_XMM(xmm7) + (32 * n)) 975 976// These macros will auto define the register name, alt name, register size, 977// register offset, encoding, format and native register. This ensures that 978// the register state structures are defined correctly and have the correct 979// sizes and offsets. 980 981// General purpose registers for 64 bit 982const DNBRegisterInfo 983DNBArchImplI386::g_gpr_registers[] = 984{ 985{ e_regSetGPR, gpr_eax, "eax" , NULL , Uint, Hex, GPR_SIZE(eax), GPR_OFFSET(eax) , gcc_eax , dwarf_eax , -1 , gdb_eax }, 986{ e_regSetGPR, gpr_ebx, "ebx" , NULL , Uint, Hex, GPR_SIZE(ebx), GPR_OFFSET(ebx) , gcc_ebx , dwarf_ebx , -1 , gdb_ebx }, 987{ e_regSetGPR, gpr_ecx, "ecx" , NULL , Uint, Hex, GPR_SIZE(ecx), GPR_OFFSET(ecx) , gcc_ecx , dwarf_ecx , -1 , gdb_ecx }, 988{ e_regSetGPR, gpr_edx, "edx" , NULL , Uint, Hex, GPR_SIZE(edx), GPR_OFFSET(edx) , gcc_edx , dwarf_edx , -1 , gdb_edx }, 989{ e_regSetGPR, gpr_edi, "edi" , NULL , Uint, Hex, GPR_SIZE(edi), GPR_OFFSET(edi) , gcc_edi , dwarf_edi , -1 , gdb_edi }, 990{ e_regSetGPR, gpr_esi, "esi" , NULL , Uint, Hex, GPR_SIZE(esi), GPR_OFFSET(esi) , gcc_esi , dwarf_esi , -1 , gdb_esi }, 991{ e_regSetGPR, gpr_ebp, "ebp" , "fp" , Uint, Hex, GPR_SIZE(ebp), GPR_OFFSET(ebp) , gcc_ebp , dwarf_ebp , GENERIC_REGNUM_FP , gdb_ebp }, 992{ e_regSetGPR, gpr_esp, "esp" , "sp" , Uint, Hex, GPR_SIZE(esp), GPR_OFFSET(esp) , gcc_esp , dwarf_esp , GENERIC_REGNUM_SP , gdb_esp }, 993{ e_regSetGPR, gpr_ss, "ss" , NULL , Uint, Hex, GPR_SIZE(ss), GPR_OFFSET(ss) , -1 , -1 , -1 , gdb_ss }, 994{ e_regSetGPR, gpr_eflags, "eflags", "flags" , Uint, Hex, GPR_SIZE(eflags), GPR_OFFSET(eflags) , gcc_eflags, dwarf_eflags , GENERIC_REGNUM_FLAGS , gdb_eflags}, 995{ e_regSetGPR, gpr_eip, "eip" , "pc" , Uint, Hex, GPR_SIZE(eip), GPR_OFFSET(eip) , gcc_eip , dwarf_eip , GENERIC_REGNUM_PC , gdb_eip }, 996{ e_regSetGPR, gpr_cs, "cs" , NULL , Uint, Hex, GPR_SIZE(cs), GPR_OFFSET(cs) , -1 , -1 , -1 , gdb_cs }, 997{ e_regSetGPR, gpr_ds, "ds" , NULL , Uint, Hex, GPR_SIZE(ds), GPR_OFFSET(ds) , -1 , -1 , -1 , gdb_ds }, 998{ e_regSetGPR, gpr_es, "es" , NULL , Uint, Hex, GPR_SIZE(es), GPR_OFFSET(es) , -1 , -1 , -1 , gdb_es }, 999{ e_regSetGPR, gpr_fs, "fs" , NULL , Uint, Hex, GPR_SIZE(fs), GPR_OFFSET(fs) , -1 , -1 , -1 , gdb_fs }, 1000{ e_regSetGPR, gpr_gs, "gs" , NULL , Uint, Hex, GPR_SIZE(gs), GPR_OFFSET(gs) , -1 , -1 , -1 , gdb_gs } 1001}; 1002 1003 1004const DNBRegisterInfo 1005DNBArchImplI386::g_fpu_registers_no_avx[] = 1006{ 1007{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1, -1, -1, -1 }, 1008{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1, -1, -1, -1 }, 1009{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1, -1, -1, -1 }, 1010{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1, -1, -1, -1 }, 1011{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1, -1, -1, -1 }, 1012{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1, -1, -1, -1 }, 1013{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1, -1, -1, -1 }, 1014{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1, -1, -1, -1 }, 1015{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1, -1, -1, -1 }, 1016{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1, -1, -1, -1 }, 1017 1018{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), -1, dwarf_stmm0, -1, gdb_stmm0 }, 1019{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), -1, dwarf_stmm1, -1, gdb_stmm1 }, 1020{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), -1, dwarf_stmm2, -1, gdb_stmm2 }, 1021{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), -1, dwarf_stmm3, -1, gdb_stmm3 }, 1022{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), -1, dwarf_stmm4, -1, gdb_stmm4 }, 1023{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), -1, dwarf_stmm5, -1, gdb_stmm5 }, 1024{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), -1, dwarf_stmm6, -1, gdb_stmm6 }, 1025{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), -1, dwarf_stmm7, -1, gdb_stmm7 }, 1026 1027{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), -1, dwarf_xmm0, -1, gdb_xmm0 }, 1028{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), -1, dwarf_xmm1, -1, gdb_xmm1 }, 1029{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), -1, dwarf_xmm2, -1, gdb_xmm2 }, 1030{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), -1, dwarf_xmm3, -1, gdb_xmm3 }, 1031{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), -1, dwarf_xmm4, -1, gdb_xmm4 }, 1032{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), -1, dwarf_xmm5, -1, gdb_xmm5 }, 1033{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), -1, dwarf_xmm6, -1, gdb_xmm6 }, 1034{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), -1, dwarf_xmm7, -1, gdb_xmm7 } 1035}; 1036 1037const DNBRegisterInfo 1038DNBArchImplI386::g_fpu_registers_avx[] = 1039{ 1040{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1, -1, -1, -1 }, 1041{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1, -1, -1, -1 }, 1042{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1, -1, -1, -1 }, 1043{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1, -1, -1, -1 }, 1044{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1, -1, -1, -1 }, 1045{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1, -1, -1, -1 }, 1046{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1, -1, -1, -1 }, 1047{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1, -1, -1, -1 }, 1048{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1, -1, -1, -1 }, 1049{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1, -1, -1, -1 }, 1050 1051{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), -1, dwarf_stmm0, -1, gdb_stmm0 }, 1052{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), -1, dwarf_stmm1, -1, gdb_stmm1 }, 1053{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), -1, dwarf_stmm2, -1, gdb_stmm2 }, 1054{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), -1, dwarf_stmm3, -1, gdb_stmm3 }, 1055{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), -1, dwarf_stmm4, -1, gdb_stmm4 }, 1056{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), -1, dwarf_stmm5, -1, gdb_stmm5 }, 1057{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), -1, dwarf_stmm6, -1, gdb_stmm6 }, 1058{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), -1, dwarf_stmm7, -1, gdb_stmm7 }, 1059 1060{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), AVX_OFFSET(xmm0), -1, dwarf_xmm0, -1, gdb_xmm0 }, 1061{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), AVX_OFFSET(xmm1), -1, dwarf_xmm1, -1, gdb_xmm1 }, 1062{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), AVX_OFFSET(xmm2), -1, dwarf_xmm2, -1, gdb_xmm2 }, 1063{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), AVX_OFFSET(xmm3), -1, dwarf_xmm3, -1, gdb_xmm3 }, 1064{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), AVX_OFFSET(xmm4), -1, dwarf_xmm4, -1, gdb_xmm4 }, 1065{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), AVX_OFFSET(xmm5), -1, dwarf_xmm5, -1, gdb_xmm5 }, 1066{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), AVX_OFFSET(xmm6), -1, dwarf_xmm6, -1, gdb_xmm6 }, 1067{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), AVX_OFFSET(xmm7), -1, dwarf_xmm7, -1, gdb_xmm7 }, 1068 1069{ e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), -1, dwarf_ymm0, -1, gdb_ymm0 }, 1070{ e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), -1, dwarf_ymm1, -1, gdb_ymm1 }, 1071{ e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), -1, dwarf_ymm2, -1, gdb_ymm2 }, 1072{ e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), -1, dwarf_ymm3, -1, gdb_ymm3 }, 1073{ e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), -1, dwarf_ymm4, -1, gdb_ymm4 }, 1074{ e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), -1, dwarf_ymm5, -1, gdb_ymm5 }, 1075{ e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), -1, dwarf_ymm6, -1, gdb_ymm6 }, 1076{ e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), -1, dwarf_ymm7, -1, gdb_ymm7 }, 1077}; 1078 1079const DNBRegisterInfo 1080DNBArchImplI386::g_exc_registers[] = 1081{ 1082{ e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1, -1, -1, -1 }, 1083{ e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1, -1, -1, -1 }, 1084{ e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1, -1, -1, -1 } 1085}; 1086 1087// Number of registers in each register set 1088const size_t DNBArchImplI386::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo); 1089const size_t DNBArchImplI386::k_num_fpu_registers_no_avx = sizeof(g_fpu_registers_no_avx)/sizeof(DNBRegisterInfo); 1090const size_t DNBArchImplI386::k_num_fpu_registers_avx = sizeof(g_fpu_registers_avx)/sizeof(DNBRegisterInfo); 1091const size_t DNBArchImplI386::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo); 1092const size_t DNBArchImplI386::k_num_all_registers_no_avx = k_num_gpr_registers + k_num_fpu_registers_no_avx + k_num_exc_registers; 1093const size_t DNBArchImplI386::k_num_all_registers_avx = k_num_gpr_registers + k_num_fpu_registers_avx + k_num_exc_registers; 1094 1095//---------------------------------------------------------------------- 1096// Register set definitions. The first definitions at register set index 1097// of zero is for all registers, followed by other registers sets. The 1098// register information for the all register set need not be filled in. 1099//---------------------------------------------------------------------- 1100const DNBRegisterSetInfo 1101DNBArchImplI386::g_reg_sets_no_avx[] = 1102{ 1103 { "i386 Registers", NULL, k_num_all_registers_no_avx }, 1104 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers }, 1105 { "Floating Point Registers", g_fpu_registers_no_avx, k_num_fpu_registers_no_avx }, 1106 { "Exception State Registers", g_exc_registers, k_num_exc_registers } 1107}; 1108 1109const DNBRegisterSetInfo 1110DNBArchImplI386::g_reg_sets_avx[] = 1111{ 1112 { "i386 Registers", NULL, k_num_all_registers_avx }, 1113 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers }, 1114 { "Floating Point Registers", g_fpu_registers_avx, k_num_fpu_registers_avx }, 1115 { "Exception State Registers", g_exc_registers, k_num_exc_registers } 1116}; 1117 1118// Total number of register sets for this architecture 1119const size_t DNBArchImplI386::k_num_register_sets = sizeof(g_reg_sets_no_avx)/sizeof(DNBRegisterSetInfo); 1120 1121DNBArchProtocol * 1122DNBArchImplI386::Create (MachThread *thread) 1123{ 1124 DNBArchImplI386 *obj = new DNBArchImplI386 (thread); 1125 1126 // When new thread comes along, it tries to inherit from the global debug state, if it is valid. 1127 if (Valid_Global_Debug_State) 1128 { 1129 obj->m_state.context.dbg = Global_Debug_State; 1130 kern_return_t kret = obj->SetDBGState(); 1131 DNBLogThreadedIf(LOG_WATCHPOINTS, 1132 "DNBArchImplX86_64::Create() Inherit and SetDBGState() => 0x%8.8x.", kret); 1133 } 1134 return obj; 1135} 1136 1137const uint8_t * const 1138DNBArchImplI386::SoftwareBreakpointOpcode (nub_size_t byte_size) 1139{ 1140 static const uint8_t g_breakpoint_opcode[] = { 0xCC }; 1141 if (byte_size == 1) 1142 return g_breakpoint_opcode; 1143 return NULL; 1144} 1145 1146const DNBRegisterSetInfo * 1147DNBArchImplI386::GetRegisterSetInfo(nub_size_t *num_reg_sets) 1148{ 1149 *num_reg_sets = k_num_register_sets; 1150 if (CPUHasAVX() || FORCE_AVX_REGS) 1151 return g_reg_sets_avx; 1152 else 1153 return g_reg_sets_no_avx; 1154} 1155 1156 1157void 1158DNBArchImplI386::Initialize() 1159{ 1160 DNBArchPluginInfo arch_plugin_info = 1161 { 1162 CPU_TYPE_I386, 1163 DNBArchImplI386::Create, 1164 DNBArchImplI386::GetRegisterSetInfo, 1165 DNBArchImplI386::SoftwareBreakpointOpcode 1166 }; 1167 1168 // Register this arch plug-in with the main protocol class 1169 DNBArchProtocol::RegisterArchPlugin (arch_plugin_info); 1170} 1171 1172bool 1173DNBArchImplI386::GetRegisterValue(int set, int reg, DNBRegisterValue *value) 1174{ 1175 if (set == REGISTER_SET_GENERIC) 1176 { 1177 switch (reg) 1178 { 1179 case GENERIC_REGNUM_PC: // Program Counter 1180 set = e_regSetGPR; 1181 reg = gpr_eip; 1182 break; 1183 1184 case GENERIC_REGNUM_SP: // Stack Pointer 1185 set = e_regSetGPR; 1186 reg = gpr_esp; 1187 break; 1188 1189 case GENERIC_REGNUM_FP: // Frame Pointer 1190 set = e_regSetGPR; 1191 reg = gpr_ebp; 1192 break; 1193 1194 case GENERIC_REGNUM_FLAGS: // Processor flags register 1195 set = e_regSetGPR; 1196 reg = gpr_eflags; 1197 break; 1198 1199 case GENERIC_REGNUM_RA: // Return Address 1200 default: 1201 return false; 1202 } 1203 } 1204 1205 if (GetRegisterState(set, false) != KERN_SUCCESS) 1206 return false; 1207 1208 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 1209 if (regInfo) 1210 { 1211 value->info = *regInfo; 1212 switch (set) 1213 { 1214 case e_regSetGPR: 1215 if (reg < k_num_gpr_registers) 1216 { 1217 value->value.uint32 = ((uint32_t*)(&m_state.context.gpr))[reg]; 1218 return true; 1219 } 1220 break; 1221 1222 case e_regSetFPU: 1223 if (CPUHasAVX() || FORCE_AVX_REGS) 1224 { 1225 switch (reg) 1226 { 1227 case fpu_fcw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fcw)); return true; 1228 case fpu_fsw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fsw)); return true; 1229 case fpu_ftw: value->value.uint8 = m_state.context.fpu.avx.__fpu_ftw; return true; 1230 case fpu_fop: value->value.uint16 = m_state.context.fpu.avx.__fpu_fop; return true; 1231 case fpu_ip: value->value.uint32 = m_state.context.fpu.avx.__fpu_ip; return true; 1232 case fpu_cs: value->value.uint16 = m_state.context.fpu.avx.__fpu_cs; return true; 1233 case fpu_dp: value->value.uint32 = m_state.context.fpu.avx.__fpu_dp; return true; 1234 case fpu_ds: value->value.uint16 = m_state.context.fpu.avx.__fpu_ds; return true; 1235 case fpu_mxcsr: value->value.uint32 = m_state.context.fpu.avx.__fpu_mxcsr; return true; 1236 case fpu_mxcsrmask: value->value.uint32 = m_state.context.fpu.avx.__fpu_mxcsrmask; return true; 1237 1238 case fpu_stmm0: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg, 10); return true; 1239 case fpu_stmm1: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg, 10); return true; 1240 case fpu_stmm2: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg, 10); return true; 1241 case fpu_stmm3: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg, 10); return true; 1242 case fpu_stmm4: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg, 10); return true; 1243 case fpu_stmm5: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg, 10); return true; 1244 case fpu_stmm6: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg, 10); return true; 1245 case fpu_stmm7: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg, 10); return true; 1246 1247 case fpu_xmm0: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm0.__xmm_reg, 16); return true; 1248 case fpu_xmm1: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm1.__xmm_reg, 16); return true; 1249 case fpu_xmm2: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm2.__xmm_reg, 16); return true; 1250 case fpu_xmm3: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm3.__xmm_reg, 16); return true; 1251 case fpu_xmm4: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm4.__xmm_reg, 16); return true; 1252 case fpu_xmm5: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm5.__xmm_reg, 16); return true; 1253 case fpu_xmm6: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm6.__xmm_reg, 16); return true; 1254 case fpu_xmm7: memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm7.__xmm_reg, 16); return true; 1255 1256#define MEMCPY_YMM(n) \ 1257 memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm##n.__xmm_reg, 16); \ 1258 memcpy((&value->value.uint8) + 16, m_state.context.fpu.avx.__fpu_ymmh##n.__xmm_reg, 16); 1259 case fpu_ymm0: MEMCPY_YMM(0); return true; 1260 case fpu_ymm1: MEMCPY_YMM(1); return true; 1261 case fpu_ymm2: MEMCPY_YMM(2); return true; 1262 case fpu_ymm3: MEMCPY_YMM(3); return true; 1263 case fpu_ymm4: MEMCPY_YMM(4); return true; 1264 case fpu_ymm5: MEMCPY_YMM(5); return true; 1265 case fpu_ymm6: MEMCPY_YMM(6); return true; 1266 case fpu_ymm7: MEMCPY_YMM(7); return true; 1267#undef MEMCPY_YMM 1268 } 1269 } 1270 else 1271 { 1272 switch (reg) 1273 { 1274 case fpu_fcw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)); return true; 1275 case fpu_fsw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)); return true; 1276 case fpu_ftw: value->value.uint8 = m_state.context.fpu.no_avx.__fpu_ftw; return true; 1277 case fpu_fop: value->value.uint16 = m_state.context.fpu.no_avx.__fpu_fop; return true; 1278 case fpu_ip: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_ip; return true; 1279 case fpu_cs: value->value.uint16 = m_state.context.fpu.no_avx.__fpu_cs; return true; 1280 case fpu_dp: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_dp; return true; 1281 case fpu_ds: value->value.uint16 = m_state.context.fpu.no_avx.__fpu_ds; return true; 1282 case fpu_mxcsr: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsr; return true; 1283 case fpu_mxcsrmask: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsrmask; return true; 1284 1285 case fpu_stmm0: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg, 10); return true; 1286 case fpu_stmm1: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg, 10); return true; 1287 case fpu_stmm2: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg, 10); return true; 1288 case fpu_stmm3: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg, 10); return true; 1289 case fpu_stmm4: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg, 10); return true; 1290 case fpu_stmm5: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg, 10); return true; 1291 case fpu_stmm6: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg, 10); return true; 1292 case fpu_stmm7: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg, 10); return true; 1293 1294 case fpu_xmm0: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg, 16); return true; 1295 case fpu_xmm1: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg, 16); return true; 1296 case fpu_xmm2: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg, 16); return true; 1297 case fpu_xmm3: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg, 16); return true; 1298 case fpu_xmm4: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg, 16); return true; 1299 case fpu_xmm5: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg, 16); return true; 1300 case fpu_xmm6: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg, 16); return true; 1301 case fpu_xmm7: memcpy(&value->value.uint8, m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg, 16); return true; 1302 } 1303 } 1304 break; 1305 1306 case e_regSetEXC: 1307 if (reg < k_num_exc_registers) 1308 { 1309 value->value.uint32 = (&m_state.context.exc.__trapno)[reg]; 1310 return true; 1311 } 1312 break; 1313 } 1314 } 1315 return false; 1316} 1317 1318 1319bool 1320DNBArchImplI386::SetRegisterValue(int set, int reg, const DNBRegisterValue *value) 1321{ 1322 if (set == REGISTER_SET_GENERIC) 1323 { 1324 switch (reg) 1325 { 1326 case GENERIC_REGNUM_PC: // Program Counter 1327 set = e_regSetGPR; 1328 reg = gpr_eip; 1329 break; 1330 1331 case GENERIC_REGNUM_SP: // Stack Pointer 1332 set = e_regSetGPR; 1333 reg = gpr_esp; 1334 break; 1335 1336 case GENERIC_REGNUM_FP: // Frame Pointer 1337 set = e_regSetGPR; 1338 reg = gpr_ebp; 1339 break; 1340 1341 case GENERIC_REGNUM_FLAGS: // Processor flags register 1342 set = e_regSetGPR; 1343 reg = gpr_eflags; 1344 break; 1345 1346 case GENERIC_REGNUM_RA: // Return Address 1347 default: 1348 return false; 1349 } 1350 } 1351 1352 if (GetRegisterState(set, false) != KERN_SUCCESS) 1353 return false; 1354 1355 bool success = false; 1356 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 1357 if (regInfo) 1358 { 1359 switch (set) 1360 { 1361 case e_regSetGPR: 1362 if (reg < k_num_gpr_registers) 1363 { 1364 ((uint32_t*)(&m_state.context.gpr))[reg] = value->value.uint32; 1365 success = true; 1366 } 1367 break; 1368 1369 case e_regSetFPU: 1370 if (CPUHasAVX() || FORCE_AVX_REGS) 1371 { 1372 switch (reg) 1373 { 1374 case fpu_fcw: *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fcw)) = value->value.uint16; success = true; break; 1375 case fpu_fsw: *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fsw)) = value->value.uint16; success = true; break; 1376 case fpu_ftw: m_state.context.fpu.avx.__fpu_ftw = value->value.uint8; success = true; break; 1377 case fpu_fop: m_state.context.fpu.avx.__fpu_fop = value->value.uint16; success = true; break; 1378 case fpu_ip: m_state.context.fpu.avx.__fpu_ip = value->value.uint32; success = true; break; 1379 case fpu_cs: m_state.context.fpu.avx.__fpu_cs = value->value.uint16; success = true; break; 1380 case fpu_dp: m_state.context.fpu.avx.__fpu_dp = value->value.uint32; success = true; break; 1381 case fpu_ds: m_state.context.fpu.avx.__fpu_ds = value->value.uint16; success = true; break; 1382 case fpu_mxcsr: m_state.context.fpu.avx.__fpu_mxcsr = value->value.uint32; success = true; break; 1383 case fpu_mxcsrmask: m_state.context.fpu.avx.__fpu_mxcsrmask = value->value.uint32; success = true; break; 1384 1385 case fpu_stmm0: memcpy (m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg, &value->value.uint8, 10); success = true; break; 1386 case fpu_stmm1: memcpy (m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg, &value->value.uint8, 10); success = true; break; 1387 case fpu_stmm2: memcpy (m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg, &value->value.uint8, 10); success = true; break; 1388 case fpu_stmm3: memcpy (m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg, &value->value.uint8, 10); success = true; break; 1389 case fpu_stmm4: memcpy (m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg, &value->value.uint8, 10); success = true; break; 1390 case fpu_stmm5: memcpy (m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg, &value->value.uint8, 10); success = true; break; 1391 case fpu_stmm6: memcpy (m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg, &value->value.uint8, 10); success = true; break; 1392 case fpu_stmm7: memcpy (m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg, &value->value.uint8, 10); success = true; break; 1393 1394 case fpu_xmm0: memcpy(m_state.context.fpu.avx.__fpu_xmm0.__xmm_reg, &value->value.uint8, 16); success = true; break; 1395 case fpu_xmm1: memcpy(m_state.context.fpu.avx.__fpu_xmm1.__xmm_reg, &value->value.uint8, 16); success = true; break; 1396 case fpu_xmm2: memcpy(m_state.context.fpu.avx.__fpu_xmm2.__xmm_reg, &value->value.uint8, 16); success = true; break; 1397 case fpu_xmm3: memcpy(m_state.context.fpu.avx.__fpu_xmm3.__xmm_reg, &value->value.uint8, 16); success = true; break; 1398 case fpu_xmm4: memcpy(m_state.context.fpu.avx.__fpu_xmm4.__xmm_reg, &value->value.uint8, 16); success = true; break; 1399 case fpu_xmm5: memcpy(m_state.context.fpu.avx.__fpu_xmm5.__xmm_reg, &value->value.uint8, 16); success = true; break; 1400 case fpu_xmm6: memcpy(m_state.context.fpu.avx.__fpu_xmm6.__xmm_reg, &value->value.uint8, 16); success = true; break; 1401 case fpu_xmm7: memcpy(m_state.context.fpu.avx.__fpu_xmm7.__xmm_reg, &value->value.uint8, 16); success = true; break; 1402 1403#define MEMCPY_YMM(n) \ 1404 memcpy(m_state.context.fpu.avx.__fpu_xmm##n.__xmm_reg, &value->value.uint8, 16); \ 1405 memcpy(m_state.context.fpu.avx.__fpu_ymmh##n.__xmm_reg, (&value->value.uint8) + 16, 16); 1406 case fpu_ymm0: MEMCPY_YMM(0); return true; 1407 case fpu_ymm1: MEMCPY_YMM(1); return true; 1408 case fpu_ymm2: MEMCPY_YMM(2); return true; 1409 case fpu_ymm3: MEMCPY_YMM(3); return true; 1410 case fpu_ymm4: MEMCPY_YMM(4); return true; 1411 case fpu_ymm5: MEMCPY_YMM(5); return true; 1412 case fpu_ymm6: MEMCPY_YMM(6); return true; 1413 case fpu_ymm7: MEMCPY_YMM(7); return true; 1414#undef MEMCPY_YMM 1415 } 1416 } 1417 else 1418 { 1419 switch (reg) 1420 { 1421 case fpu_fcw: *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)) = value->value.uint16; success = true; break; 1422 case fpu_fsw: *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)) = value->value.uint16; success = true; break; 1423 case fpu_ftw: m_state.context.fpu.no_avx.__fpu_ftw = value->value.uint8; success = true; break; 1424 case fpu_fop: m_state.context.fpu.no_avx.__fpu_fop = value->value.uint16; success = true; break; 1425 case fpu_ip: m_state.context.fpu.no_avx.__fpu_ip = value->value.uint32; success = true; break; 1426 case fpu_cs: m_state.context.fpu.no_avx.__fpu_cs = value->value.uint16; success = true; break; 1427 case fpu_dp: m_state.context.fpu.no_avx.__fpu_dp = value->value.uint32; success = true; break; 1428 case fpu_ds: m_state.context.fpu.no_avx.__fpu_ds = value->value.uint16; success = true; break; 1429 case fpu_mxcsr: m_state.context.fpu.no_avx.__fpu_mxcsr = value->value.uint32; success = true; break; 1430 case fpu_mxcsrmask: m_state.context.fpu.no_avx.__fpu_mxcsrmask = value->value.uint32; success = true; break; 1431 1432 case fpu_stmm0: memcpy (m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg, &value->value.uint8, 10); success = true; break; 1433 case fpu_stmm1: memcpy (m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg, &value->value.uint8, 10); success = true; break; 1434 case fpu_stmm2: memcpy (m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg, &value->value.uint8, 10); success = true; break; 1435 case fpu_stmm3: memcpy (m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg, &value->value.uint8, 10); success = true; break; 1436 case fpu_stmm4: memcpy (m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg, &value->value.uint8, 10); success = true; break; 1437 case fpu_stmm5: memcpy (m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg, &value->value.uint8, 10); success = true; break; 1438 case fpu_stmm6: memcpy (m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg, &value->value.uint8, 10); success = true; break; 1439 case fpu_stmm7: memcpy (m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg, &value->value.uint8, 10); success = true; break; 1440 1441 case fpu_xmm0: memcpy(m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg, &value->value.uint8, 16); success = true; break; 1442 case fpu_xmm1: memcpy(m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg, &value->value.uint8, 16); success = true; break; 1443 case fpu_xmm2: memcpy(m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg, &value->value.uint8, 16); success = true; break; 1444 case fpu_xmm3: memcpy(m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg, &value->value.uint8, 16); success = true; break; 1445 case fpu_xmm4: memcpy(m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg, &value->value.uint8, 16); success = true; break; 1446 case fpu_xmm5: memcpy(m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg, &value->value.uint8, 16); success = true; break; 1447 case fpu_xmm6: memcpy(m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg, &value->value.uint8, 16); success = true; break; 1448 case fpu_xmm7: memcpy(m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg, &value->value.uint8, 16); success = true; break; 1449 } 1450 } 1451 break; 1452 1453 case e_regSetEXC: 1454 if (reg < k_num_exc_registers) 1455 { 1456 (&m_state.context.exc.__trapno)[reg] = value->value.uint32; 1457 success = true; 1458 } 1459 break; 1460 } 1461 } 1462 1463 if (success) 1464 return SetRegisterState(set) == KERN_SUCCESS; 1465 return false; 1466} 1467 1468 1469nub_size_t 1470DNBArchImplI386::GetRegisterContext (void *buf, nub_size_t buf_len) 1471{ 1472 nub_size_t size = sizeof (m_state.context); 1473 1474 if (buf && buf_len) 1475 { 1476 if (size > buf_len) 1477 size = buf_len; 1478 1479 bool force = false; 1480 kern_return_t kret; 1481 if ((kret = GetGPRState(force)) != KERN_SUCCESS) 1482 { 1483 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::GetRegisterContext (buf = %p, len = %zu) error: GPR regs failed to read: %u ", buf, buf_len, kret); 1484 size = 0; 1485 } 1486 else if ((kret = GetFPUState(force)) != KERN_SUCCESS) 1487 { 1488 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::GetRegisterContext (buf = %p, len = %zu) error: %s regs failed to read: %u", buf, buf_len, CPUHasAVX() ? "AVX" : "FPU", kret); 1489 size = 0; 1490 } 1491 else if ((kret = GetEXCState(force)) != KERN_SUCCESS) 1492 { 1493 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::GetRegisterContext (buf = %p, len = %zu) error: EXC regs failed to read: %u", buf, buf_len, kret); 1494 size = 0; 1495 } 1496 else 1497 { 1498 // Success 1499 ::memcpy (buf, &m_state.context, size); 1500 } 1501 } 1502 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::GetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size); 1503 // Return the size of the register context even if NULL was passed in 1504 return size; 1505} 1506 1507nub_size_t 1508DNBArchImplI386::SetRegisterContext (const void *buf, nub_size_t buf_len) 1509{ 1510 nub_size_t size = sizeof (m_state.context); 1511 if (buf == NULL || buf_len == 0) 1512 size = 0; 1513 1514 if (size) 1515 { 1516 if (size > buf_len) 1517 size = buf_len; 1518 1519 ::memcpy (&m_state.context, buf, size); 1520 kern_return_t kret; 1521 if ((kret = SetGPRState()) != KERN_SUCCESS) 1522 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::SetRegisterContext (buf = %p, len = %zu) error: GPR regs failed to write: %u", buf, buf_len, kret); 1523 if ((kret = SetFPUState()) != KERN_SUCCESS) 1524 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::SetRegisterContext (buf = %p, len = %zu) error: %s regs failed to write: %u", buf, buf_len, CPUHasAVX() ? "AVX" : "FPU", kret); 1525 if ((kret = SetEXCState()) != KERN_SUCCESS) 1526 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::SetRegisterContext (buf = %p, len = %zu) error: EXP regs failed to write: %u", buf, buf_len, kret); 1527 } 1528 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::SetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size); 1529 return size; 1530} 1531 1532 1533 1534kern_return_t 1535DNBArchImplI386::GetRegisterState(int set, bool force) 1536{ 1537 switch (set) 1538 { 1539 case e_regSetALL: return GetGPRState(force) | GetFPUState(force) | GetEXCState(force); 1540 case e_regSetGPR: return GetGPRState(force); 1541 case e_regSetFPU: return GetFPUState(force); 1542 case e_regSetEXC: return GetEXCState(force); 1543 default: break; 1544 } 1545 return KERN_INVALID_ARGUMENT; 1546} 1547 1548kern_return_t 1549DNBArchImplI386::SetRegisterState(int set) 1550{ 1551 // Make sure we have a valid context to set. 1552 if (RegisterSetStateIsValid(set)) 1553 { 1554 switch (set) 1555 { 1556 case e_regSetALL: return SetGPRState() | SetFPUState() | SetEXCState(); 1557 case e_regSetGPR: return SetGPRState(); 1558 case e_regSetFPU: return SetFPUState(); 1559 case e_regSetEXC: return SetEXCState(); 1560 default: break; 1561 } 1562 } 1563 return KERN_INVALID_ARGUMENT; 1564} 1565 1566bool 1567DNBArchImplI386::RegisterSetStateIsValid (int set) const 1568{ 1569 return m_state.RegsAreValid(set); 1570} 1571 1572#endif // #if defined (__i386__) 1573