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