DNBArchImplX86_64.cpp revision 34e71efd963d7422974739519abe4223909200a3
1//===-- DNBArchImplX86_64.cpp -----------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// 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#include <sys/types.h> 18#include <sys/sysctl.h> 19 20#include "MacOSX/x86_64/DNBArchImplX86_64.h" 21#include "DNBLog.h" 22#include "MachThread.h" 23#include "MachProcess.h" 24#include <mach/mach.h> 25#include <stdlib.h> 26 27#if defined (LLDB_DEBUGSERVER_RELEASE) || defined (LLDB_DEBUGSERVER_DEBUG) 28enum debugState { 29 debugStateUnknown, 30 debugStateOff, 31 debugStateOn 32}; 33 34static debugState sFPUDebugState = debugStateUnknown; 35static debugState sAVXForceState = debugStateUnknown; 36 37static bool DebugFPURegs () 38{ 39 if (sFPUDebugState == debugStateUnknown) 40 { 41 if (getenv("DNB_DEBUG_FPU_REGS")) 42 sFPUDebugState = debugStateOn; 43 else 44 sFPUDebugState = debugStateOff; 45 } 46 47 return (sFPUDebugState == debugStateOn); 48} 49 50static bool ForceAVXRegs () 51{ 52 if (sFPUDebugState == debugStateUnknown) 53 { 54 if (getenv("DNB_DEBUG_X86_FORCE_AVX_REGS")) 55 sAVXForceState = debugStateOn; 56 else 57 sAVXForceState = debugStateOff; 58 } 59 60 return (sAVXForceState == debugStateOn); 61} 62 63#define DEBUG_FPU_REGS (DebugFPURegs()) 64#define FORCE_AVX_REGS (ForceAVXRegs()) 65#else 66#define DEBUG_FPU_REGS (0) 67#define FORCE_AVX_REGS (0) 68#endif 69 70 71extern "C" bool 72CPUHasAVX() 73{ 74 enum AVXPresence 75 { 76 eAVXUnknown = -1, 77 eAVXNotPresent = 0, 78 eAVXPresent = 1 79 }; 80 81 static AVXPresence g_has_avx = eAVXUnknown; 82 if (g_has_avx == eAVXUnknown) 83 { 84 g_has_avx = eAVXNotPresent; 85 86 // Only xnu-2020 or later has AVX support, any versions before 87 // this have a busted thread_get_state RPC where it would truncate 88 // the thread state buffer (<rdar://problem/10122874>). So we need to 89 // verify the kernel version number manually or disable AVX support. 90 int mib[2]; 91 char buffer[1024]; 92 size_t length = sizeof(buffer); 93 uint64_t xnu_version = 0; 94 mib[0] = CTL_KERN; 95 mib[1] = KERN_VERSION; 96 int err = ::sysctl(mib, 2, &buffer, &length, NULL, 0); 97 if (err == 0) 98 { 99 const char *xnu = strstr (buffer, "xnu-"); 100 if (xnu) 101 { 102 const char *xnu_version_cstr = xnu + 4; 103 xnu_version = strtoull (xnu_version_cstr, NULL, 0); 104 if (xnu_version >= 2020 && xnu_version != ULLONG_MAX) 105 { 106 if (::HasAVX()) 107 { 108 g_has_avx = eAVXPresent; 109 } 110 } 111 } 112 } 113 DNBLogThreadedIf (LOG_THREAD, "CPUHasAVX(): g_has_avx = %i (err = %i, errno = %i, xnu_version = %llu)", g_has_avx, err, errno, xnu_version); 114 } 115 116 return (g_has_avx == eAVXPresent); 117} 118 119uint64_t 120DNBArchImplX86_64::GetPC(uint64_t failValue) 121{ 122 // Get program counter 123 if (GetGPRState(false) == KERN_SUCCESS) 124 return m_state.context.gpr.__rip; 125 return failValue; 126} 127 128kern_return_t 129DNBArchImplX86_64::SetPC(uint64_t value) 130{ 131 // Get program counter 132 kern_return_t err = GetGPRState(false); 133 if (err == KERN_SUCCESS) 134 { 135 m_state.context.gpr.__rip = value; 136 err = SetGPRState(); 137 } 138 return err == KERN_SUCCESS; 139} 140 141uint64_t 142DNBArchImplX86_64::GetSP(uint64_t failValue) 143{ 144 // Get stack pointer 145 if (GetGPRState(false) == KERN_SUCCESS) 146 return m_state.context.gpr.__rsp; 147 return failValue; 148} 149 150// Uncomment the value below to verify the values in the debugger. 151//#define DEBUG_GPR_VALUES 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED 152 153kern_return_t 154DNBArchImplX86_64::GetGPRState(bool force) 155{ 156 if (force || m_state.GetError(e_regSetGPR, Read)) 157 { 158#if DEBUG_GPR_VALUES 159 m_state.context.gpr.__rax = ('a' << 8) + 'x'; 160 m_state.context.gpr.__rbx = ('b' << 8) + 'x'; 161 m_state.context.gpr.__rcx = ('c' << 8) + 'x'; 162 m_state.context.gpr.__rdx = ('d' << 8) + 'x'; 163 m_state.context.gpr.__rdi = ('d' << 8) + 'i'; 164 m_state.context.gpr.__rsi = ('s' << 8) + 'i'; 165 m_state.context.gpr.__rbp = ('b' << 8) + 'p'; 166 m_state.context.gpr.__rsp = ('s' << 8) + 'p'; 167 m_state.context.gpr.__r8 = ('r' << 8) + '8'; 168 m_state.context.gpr.__r9 = ('r' << 8) + '9'; 169 m_state.context.gpr.__r10 = ('r' << 8) + 'a'; 170 m_state.context.gpr.__r11 = ('r' << 8) + 'b'; 171 m_state.context.gpr.__r12 = ('r' << 8) + 'c'; 172 m_state.context.gpr.__r13 = ('r' << 8) + 'd'; 173 m_state.context.gpr.__r14 = ('r' << 8) + 'e'; 174 m_state.context.gpr.__r15 = ('r' << 8) + 'f'; 175 m_state.context.gpr.__rip = ('i' << 8) + 'p'; 176 m_state.context.gpr.__rflags = ('f' << 8) + 'l'; 177 m_state.context.gpr.__cs = ('c' << 8) + 's'; 178 m_state.context.gpr.__fs = ('f' << 8) + 's'; 179 m_state.context.gpr.__gs = ('g' << 8) + 's'; 180 m_state.SetError(e_regSetGPR, Read, 0); 181#else 182 mach_msg_type_number_t count = e_regSetWordSizeGPR; 183 m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count)); 184 DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x" 185 "\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx" 186 "\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx" 187 "\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx" 188 "\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx" 189 "\n\trip = %16.16llx" 190 "\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx", 191 m_thread->ThreadID(), x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT, 192 m_state.GetError(e_regSetGPR, Read), 193 m_state.context.gpr.__rax,m_state.context.gpr.__rbx,m_state.context.gpr.__rcx, 194 m_state.context.gpr.__rdx,m_state.context.gpr.__rdi,m_state.context.gpr.__rsi, 195 m_state.context.gpr.__rbp,m_state.context.gpr.__rsp,m_state.context.gpr.__r8, 196 m_state.context.gpr.__r9, m_state.context.gpr.__r10,m_state.context.gpr.__r11, 197 m_state.context.gpr.__r12,m_state.context.gpr.__r13,m_state.context.gpr.__r14, 198 m_state.context.gpr.__r15,m_state.context.gpr.__rip,m_state.context.gpr.__rflags, 199 m_state.context.gpr.__cs,m_state.context.gpr.__fs, m_state.context.gpr.__gs); 200 201 // DNBLogThreadedIf (LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x" 202 // "\n\trax = %16.16llx" 203 // "\n\trbx = %16.16llx" 204 // "\n\trcx = %16.16llx" 205 // "\n\trdx = %16.16llx" 206 // "\n\trdi = %16.16llx" 207 // "\n\trsi = %16.16llx" 208 // "\n\trbp = %16.16llx" 209 // "\n\trsp = %16.16llx" 210 // "\n\t r8 = %16.16llx" 211 // "\n\t r9 = %16.16llx" 212 // "\n\tr10 = %16.16llx" 213 // "\n\tr11 = %16.16llx" 214 // "\n\tr12 = %16.16llx" 215 // "\n\tr13 = %16.16llx" 216 // "\n\tr14 = %16.16llx" 217 // "\n\tr15 = %16.16llx" 218 // "\n\trip = %16.16llx" 219 // "\n\tflg = %16.16llx" 220 // "\n\t cs = %16.16llx" 221 // "\n\t fs = %16.16llx" 222 // "\n\t gs = %16.16llx", 223 // m_thread->ThreadID(), 224 // x86_THREAD_STATE64, 225 // x86_THREAD_STATE64_COUNT, 226 // m_state.GetError(e_regSetGPR, Read), 227 // m_state.context.gpr.__rax, 228 // m_state.context.gpr.__rbx, 229 // m_state.context.gpr.__rcx, 230 // m_state.context.gpr.__rdx, 231 // m_state.context.gpr.__rdi, 232 // m_state.context.gpr.__rsi, 233 // m_state.context.gpr.__rbp, 234 // m_state.context.gpr.__rsp, 235 // m_state.context.gpr.__r8, 236 // m_state.context.gpr.__r9, 237 // m_state.context.gpr.__r10, 238 // m_state.context.gpr.__r11, 239 // m_state.context.gpr.__r12, 240 // m_state.context.gpr.__r13, 241 // m_state.context.gpr.__r14, 242 // m_state.context.gpr.__r15, 243 // m_state.context.gpr.__rip, 244 // m_state.context.gpr.__rflags, 245 // m_state.context.gpr.__cs, 246 // m_state.context.gpr.__fs, 247 // m_state.context.gpr.__gs); 248#endif 249 } 250 return m_state.GetError(e_regSetGPR, Read); 251} 252 253// Uncomment the value below to verify the values in the debugger. 254//#define DEBUG_FPU_REGS 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED 255 256kern_return_t 257DNBArchImplX86_64::GetFPUState(bool force) 258{ 259 if (force || m_state.GetError(e_regSetFPU, Read)) 260 { 261 if (DEBUG_FPU_REGS) { 262 if (CPUHasAVX() || FORCE_AVX_REGS) 263 { 264 m_state.context.fpu.avx.__fpu_reserved[0] = -1; 265 m_state.context.fpu.avx.__fpu_reserved[1] = -1; 266 *(uint16_t *)&(m_state.context.fpu.avx.__fpu_fcw) = 0x1234; 267 *(uint16_t *)&(m_state.context.fpu.avx.__fpu_fsw) = 0x5678; 268 m_state.context.fpu.avx.__fpu_ftw = 1; 269 m_state.context.fpu.avx.__fpu_rsrv1 = UINT8_MAX; 270 m_state.context.fpu.avx.__fpu_fop = 2; 271 m_state.context.fpu.avx.__fpu_ip = 3; 272 m_state.context.fpu.avx.__fpu_cs = 4; 273 m_state.context.fpu.avx.__fpu_rsrv2 = 5; 274 m_state.context.fpu.avx.__fpu_dp = 6; 275 m_state.context.fpu.avx.__fpu_ds = 7; 276 m_state.context.fpu.avx.__fpu_rsrv3 = UINT16_MAX; 277 m_state.context.fpu.avx.__fpu_mxcsr = 8; 278 m_state.context.fpu.avx.__fpu_mxcsrmask = 9; 279 int i; 280 for (i=0; i<16; ++i) 281 { 282 if (i<10) 283 { 284 m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg[i] = 'a'; 285 m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg[i] = 'b'; 286 m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg[i] = 'c'; 287 m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg[i] = 'd'; 288 m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg[i] = 'e'; 289 m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg[i] = 'f'; 290 m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg[i] = 'g'; 291 m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg[i] = 'h'; 292 } 293 else 294 { 295 m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN; 296 m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN; 297 m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN; 298 m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN; 299 m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN; 300 m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN; 301 m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN; 302 m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN; 303 } 304 305 m_state.context.fpu.avx.__fpu_xmm0.__xmm_reg[i] = '0'; 306 m_state.context.fpu.avx.__fpu_xmm1.__xmm_reg[i] = '1'; 307 m_state.context.fpu.avx.__fpu_xmm2.__xmm_reg[i] = '2'; 308 m_state.context.fpu.avx.__fpu_xmm3.__xmm_reg[i] = '3'; 309 m_state.context.fpu.avx.__fpu_xmm4.__xmm_reg[i] = '4'; 310 m_state.context.fpu.avx.__fpu_xmm5.__xmm_reg[i] = '5'; 311 m_state.context.fpu.avx.__fpu_xmm6.__xmm_reg[i] = '6'; 312 m_state.context.fpu.avx.__fpu_xmm7.__xmm_reg[i] = '7'; 313 m_state.context.fpu.avx.__fpu_xmm8.__xmm_reg[i] = '8'; 314 m_state.context.fpu.avx.__fpu_xmm9.__xmm_reg[i] = '9'; 315 m_state.context.fpu.avx.__fpu_xmm10.__xmm_reg[i] = 'A'; 316 m_state.context.fpu.avx.__fpu_xmm11.__xmm_reg[i] = 'B'; 317 m_state.context.fpu.avx.__fpu_xmm12.__xmm_reg[i] = 'C'; 318 m_state.context.fpu.avx.__fpu_xmm13.__xmm_reg[i] = 'D'; 319 m_state.context.fpu.avx.__fpu_xmm14.__xmm_reg[i] = 'E'; 320 m_state.context.fpu.avx.__fpu_xmm15.__xmm_reg[i] = 'F'; 321 322 m_state.context.fpu.avx.__fpu_ymmh0.__xmm_reg[i] = '0'; 323 m_state.context.fpu.avx.__fpu_ymmh1.__xmm_reg[i] = '1'; 324 m_state.context.fpu.avx.__fpu_ymmh2.__xmm_reg[i] = '2'; 325 m_state.context.fpu.avx.__fpu_ymmh3.__xmm_reg[i] = '3'; 326 m_state.context.fpu.avx.__fpu_ymmh4.__xmm_reg[i] = '4'; 327 m_state.context.fpu.avx.__fpu_ymmh5.__xmm_reg[i] = '5'; 328 m_state.context.fpu.avx.__fpu_ymmh6.__xmm_reg[i] = '6'; 329 m_state.context.fpu.avx.__fpu_ymmh7.__xmm_reg[i] = '7'; 330 m_state.context.fpu.avx.__fpu_ymmh8.__xmm_reg[i] = '8'; 331 m_state.context.fpu.avx.__fpu_ymmh9.__xmm_reg[i] = '9'; 332 m_state.context.fpu.avx.__fpu_ymmh10.__xmm_reg[i] = 'A'; 333 m_state.context.fpu.avx.__fpu_ymmh11.__xmm_reg[i] = 'B'; 334 m_state.context.fpu.avx.__fpu_ymmh12.__xmm_reg[i] = 'C'; 335 m_state.context.fpu.avx.__fpu_ymmh13.__xmm_reg[i] = 'D'; 336 m_state.context.fpu.avx.__fpu_ymmh14.__xmm_reg[i] = 'E'; 337 m_state.context.fpu.avx.__fpu_ymmh15.__xmm_reg[i] = 'F'; 338 } 339 for (i=0; i<sizeof(m_state.context.fpu.avx.__fpu_rsrv4); ++i) 340 m_state.context.fpu.avx.__fpu_rsrv4[i] = INT8_MIN; 341 m_state.context.fpu.avx.__fpu_reserved1 = -1; 342 for (i=0; i<sizeof(m_state.context.fpu.avx.__avx_reserved1); ++i) 343 m_state.context.fpu.avx.__avx_reserved1[i] = INT8_MIN; 344 m_state.SetError(e_regSetFPU, Read, 0); 345 } 346 else 347 { 348 m_state.context.fpu.no_avx.__fpu_reserved[0] = -1; 349 m_state.context.fpu.no_avx.__fpu_reserved[1] = -1; 350 *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fcw) = 0x1234; 351 *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fsw) = 0x5678; 352 m_state.context.fpu.no_avx.__fpu_ftw = 1; 353 m_state.context.fpu.no_avx.__fpu_rsrv1 = UINT8_MAX; 354 m_state.context.fpu.no_avx.__fpu_fop = 2; 355 m_state.context.fpu.no_avx.__fpu_ip = 3; 356 m_state.context.fpu.no_avx.__fpu_cs = 4; 357 m_state.context.fpu.no_avx.__fpu_rsrv2 = 5; 358 m_state.context.fpu.no_avx.__fpu_dp = 6; 359 m_state.context.fpu.no_avx.__fpu_ds = 7; 360 m_state.context.fpu.no_avx.__fpu_rsrv3 = UINT16_MAX; 361 m_state.context.fpu.no_avx.__fpu_mxcsr = 8; 362 m_state.context.fpu.no_avx.__fpu_mxcsrmask = 9; 363 int i; 364 for (i=0; i<16; ++i) 365 { 366 if (i<10) 367 { 368 m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = 'a'; 369 m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = 'b'; 370 m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = 'c'; 371 m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = 'd'; 372 m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = 'e'; 373 m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = 'f'; 374 m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = 'g'; 375 m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = 'h'; 376 } 377 else 378 { 379 m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN; 380 m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN; 381 m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN; 382 m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN; 383 m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN; 384 m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN; 385 m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN; 386 m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN; 387 } 388 389 m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg[i] = '0'; 390 m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg[i] = '1'; 391 m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg[i] = '2'; 392 m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg[i] = '3'; 393 m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg[i] = '4'; 394 m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg[i] = '5'; 395 m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg[i] = '6'; 396 m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg[i] = '7'; 397 m_state.context.fpu.no_avx.__fpu_xmm8.__xmm_reg[i] = '8'; 398 m_state.context.fpu.no_avx.__fpu_xmm9.__xmm_reg[i] = '9'; 399 m_state.context.fpu.no_avx.__fpu_xmm10.__xmm_reg[i] = 'A'; 400 m_state.context.fpu.no_avx.__fpu_xmm11.__xmm_reg[i] = 'B'; 401 m_state.context.fpu.no_avx.__fpu_xmm12.__xmm_reg[i] = 'C'; 402 m_state.context.fpu.no_avx.__fpu_xmm13.__xmm_reg[i] = 'D'; 403 m_state.context.fpu.no_avx.__fpu_xmm14.__xmm_reg[i] = 'E'; 404 m_state.context.fpu.no_avx.__fpu_xmm15.__xmm_reg[i] = 'F'; 405 } 406 for (i=0; i<sizeof(m_state.context.fpu.no_avx.__fpu_rsrv4); ++i) 407 m_state.context.fpu.no_avx.__fpu_rsrv4[i] = INT8_MIN; 408 m_state.context.fpu.no_avx.__fpu_reserved1 = -1; 409 m_state.SetError(e_regSetFPU, Read, 0); 410 } 411 } 412 else 413 { 414 if (CPUHasAVX() || FORCE_AVX_REGS) 415 { 416 mach_msg_type_number_t count = e_regSetWordSizeAVX; 417 m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count)); 418 DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &avx, %u (%u passed in) carp) => 0x%8.8x", 419 m_thread->ThreadID(), __x86_64_AVX_STATE, (uint32_t)count, 420 e_regSetWordSizeAVX, m_state.GetError(e_regSetFPU, Read)); 421 } 422 else 423 { 424 mach_msg_type_number_t count = e_regSetWordSizeFPU; 425 m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count)); 426 DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &fpu, %u (%u passed in) => 0x%8.8x", 427 m_thread->ThreadID(), __x86_64_FLOAT_STATE, (uint32_t)count, 428 e_regSetWordSizeFPU, m_state.GetError(e_regSetFPU, Read)); 429 } 430 } 431 } 432 return m_state.GetError(e_regSetFPU, Read); 433} 434 435kern_return_t 436DNBArchImplX86_64::GetEXCState(bool force) 437{ 438 if (force || m_state.GetError(e_regSetEXC, Read)) 439 { 440 mach_msg_type_number_t count = e_regSetWordSizeEXC; 441 m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count)); 442 } 443 return m_state.GetError(e_regSetEXC, Read); 444} 445 446kern_return_t 447DNBArchImplX86_64::SetGPRState() 448{ 449 kern_return_t kret = ::thread_abort_safely(m_thread->ThreadID()); 450 DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->ThreadID(), kret, m_thread->Process()->StopCount()); 451 452 m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR)); 453 DNBLogThreadedIf (LOG_THREAD, "::thread_set_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x" 454 "\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx" 455 "\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx" 456 "\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx" 457 "\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx" 458 "\n\trip = %16.16llx" 459 "\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx", 460 m_thread->ThreadID(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR, 461 m_state.GetError(e_regSetGPR, Write), 462 m_state.context.gpr.__rax,m_state.context.gpr.__rbx,m_state.context.gpr.__rcx, 463 m_state.context.gpr.__rdx,m_state.context.gpr.__rdi,m_state.context.gpr.__rsi, 464 m_state.context.gpr.__rbp,m_state.context.gpr.__rsp,m_state.context.gpr.__r8, 465 m_state.context.gpr.__r9, m_state.context.gpr.__r10,m_state.context.gpr.__r11, 466 m_state.context.gpr.__r12,m_state.context.gpr.__r13,m_state.context.gpr.__r14, 467 m_state.context.gpr.__r15,m_state.context.gpr.__rip,m_state.context.gpr.__rflags, 468 m_state.context.gpr.__cs, m_state.context.gpr.__fs, m_state.context.gpr.__gs); 469 return m_state.GetError(e_regSetGPR, Write); 470} 471 472kern_return_t 473DNBArchImplX86_64::SetFPUState() 474{ 475 if (DEBUG_FPU_REGS) 476 { 477 m_state.SetError(e_regSetFPU, Write, 0); 478 return m_state.GetError(e_regSetFPU, Write); 479 } 480 else 481 { 482 if (CPUHasAVX() || FORCE_AVX_REGS) 483 { 484 m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX)); 485 return m_state.GetError(e_regSetFPU, Write); 486 } 487 else 488 { 489 m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU)); 490 return m_state.GetError(e_regSetFPU, Write); 491 } 492 } 493} 494 495kern_return_t 496DNBArchImplX86_64::SetEXCState() 497{ 498 m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC)); 499 return m_state.GetError(e_regSetEXC, Write); 500} 501 502kern_return_t 503DNBArchImplX86_64::GetDBGState(bool force) 504{ 505 if (force || m_state.GetError(e_regSetDBG, Read)) 506 { 507 mach_msg_type_number_t count = e_regSetWordSizeDBG; 508 m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count)); 509 } 510 return m_state.GetError(e_regSetDBG, Read); 511} 512 513kern_return_t 514DNBArchImplX86_64::SetDBGState() 515{ 516 m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG)); 517 return m_state.GetError(e_regSetDBG, Write); 518} 519 520void 521DNBArchImplX86_64::ThreadWillResume() 522{ 523 // Do we need to step this thread? If so, let the mach thread tell us so. 524 if (m_thread->IsStepping()) 525 { 526 // This is the primary thread, let the arch do anything it needs 527 EnableHardwareSingleStep(true); 528 } 529 530 // Reset the debug status register, if necessary, before we resume. 531 kern_return_t kret = GetDBGState(false); 532 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); 533 if (kret != KERN_SUCCESS) 534 return; 535 536 DBG &debug_state = m_state.context.dbg; 537 bool need_reset = false; 538 uint32_t i, num = NumSupportedHardwareWatchpoints(); 539 for (i = 0; i < num; ++i) 540 if (IsWatchpointHit(debug_state, i)) 541 need_reset = true; 542 543 if (need_reset) 544 { 545 ClearWatchpointHits(debug_state); 546 kret = SetDBGState(); 547 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); 548 } 549} 550 551bool 552DNBArchImplX86_64::ThreadDidStop() 553{ 554 bool success = true; 555 556 m_state.InvalidateAllRegisterStates(); 557 558 // Are we stepping a single instruction? 559 if (GetGPRState(true) == KERN_SUCCESS) 560 { 561 // We are single stepping, was this the primary thread? 562 if (m_thread->IsStepping()) 563 { 564 // This was the primary thread, we need to clear the trace 565 // bit if so. 566 success = EnableHardwareSingleStep(false) == KERN_SUCCESS; 567 } 568 else 569 { 570 // The MachThread will automatically restore the suspend count 571 // in ThreadDidStop(), so we don't need to do anything here if 572 // we weren't the primary thread the last time 573 } 574 } 575 return success; 576} 577 578bool 579DNBArchImplX86_64::NotifyException(MachException::Data& exc) 580{ 581 switch (exc.exc_type) 582 { 583 case EXC_BAD_ACCESS: 584 break; 585 case EXC_BAD_INSTRUCTION: 586 break; 587 case EXC_ARITHMETIC: 588 break; 589 case EXC_EMULATION: 590 break; 591 case EXC_SOFTWARE: 592 break; 593 case EXC_BREAKPOINT: 594 if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) 595 { 596 // exc_code = EXC_I386_BPT 597 // 598 nub_addr_t pc = GetPC(INVALID_NUB_ADDRESS); 599 if (pc != INVALID_NUB_ADDRESS && pc > 0) 600 { 601 pc -= 1; 602 // Check for a breakpoint at one byte prior to the current PC value 603 // since the PC will be just past the trap. 604 605 nub_break_t breakID = m_thread->Process()->Breakpoints().FindIDByAddress(pc); 606 if (NUB_BREAK_ID_IS_VALID(breakID)) 607 { 608 // Backup the PC for i386 since the trap was taken and the PC 609 // is at the address following the single byte trap instruction. 610 if (m_state.context.gpr.__rip > 0) 611 { 612 m_state.context.gpr.__rip = pc; 613 // Write the new PC back out 614 SetGPRState (); 615 } 616 } 617 return true; 618 } 619 } 620 else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) 621 { 622 // exc_code = EXC_I386_SGL 623 // 624 // Check whether this corresponds to a watchpoint hit event. 625 // If yes, set the exc_sub_code to the data break address. 626 nub_addr_t addr = 0; 627 uint32_t hw_index = GetHardwareWatchpointHit(addr); 628 if (hw_index != INVALID_NUB_HW_INDEX) 629 { 630 exc.exc_data[1] = addr; 631 // Piggyback the hw_index in the exc.data. 632 exc.exc_data.push_back(hw_index); 633 } 634 635 return true; 636 } 637 break; 638 case EXC_SYSCALL: 639 break; 640 case EXC_MACH_SYSCALL: 641 break; 642 case EXC_RPC_ALERT: 643 break; 644 } 645 return false; 646} 647 648uint32_t 649DNBArchImplX86_64::NumSupportedHardwareWatchpoints() 650{ 651 // Available debug address registers: dr0, dr1, dr2, dr3. 652 return 4; 653} 654 655static uint32_t 656size_and_rw_bits(nub_size_t size, bool read, bool write) 657{ 658 uint32_t rw; 659 if (read) { 660 rw = 0x3; // READ or READ/WRITE 661 } else if (write) { 662 rw = 0x1; // WRITE 663 } else { 664 assert(0 && "read and write cannot both be false"); 665 } 666 667 switch (size) { 668 case 1: 669 return rw; 670 case 2: 671 return (0x1 << 2) | rw; 672 case 4: 673 return (0x3 << 2) | rw; 674 case 8: 675 return (0x2 << 2) | rw; 676 default: 677 assert(0 && "invalid size, must be one of 1, 2, 4, or 8"); 678 } 679} 680void 681DNBArchImplX86_64::SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write) 682{ 683 // Set both dr7 (debug control register) and dri (debug address register). 684 685 // dr7{7-0} encodes the local/gloabl enable bits: 686 // global enable --. .-- local enable 687 // | | 688 // v v 689 // dr0 -> bits{1-0} 690 // dr1 -> bits{3-2} 691 // dr2 -> bits{5-4} 692 // dr3 -> bits{7-6} 693 // 694 // dr7{31-16} encodes the rw/len bits: 695 // b_x+3, b_x+2, b_x+1, b_x 696 // where bits{x+1, x} => rw 697 // 0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io read-or-write (unused) 698 // and bits{x+3, x+2} => len 699 // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte 700 // 701 // dr0 -> bits{19-16} 702 // dr1 -> bits{23-20} 703 // dr2 -> bits{27-24} 704 // dr3 -> bits{31-28} 705 debug_state.__dr7 |= (1 << (2*hw_index) | 706 size_and_rw_bits(size, read, write) << (16+4*hw_index)); 707 switch (hw_index) { 708 case 0: 709 debug_state.__dr0 = addr; break; 710 case 1: 711 debug_state.__dr1 = addr; break; 712 case 2: 713 debug_state.__dr2 = addr; break; 714 case 3: 715 debug_state.__dr3 = addr; break; 716 default: 717 assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); 718 } 719 return; 720} 721 722void 723DNBArchImplX86_64::ClearWatchpoint(DBG &debug_state, uint32_t hw_index) 724{ 725 debug_state.__dr7 &= ~(3 << (2*hw_index)); 726 switch (hw_index) { 727 case 0: 728 debug_state.__dr0 = 0; break; 729 case 1: 730 debug_state.__dr1 = 0; break; 731 case 2: 732 debug_state.__dr2 = 0; break; 733 case 3: 734 debug_state.__dr3 = 0; break; 735 default: 736 assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); 737 } 738 return; 739} 740 741bool 742DNBArchImplX86_64::IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index) 743{ 744 // Check dr7 (debug control register) for local/global enable bits: 745 // global enable --. .-- local enable 746 // | | 747 // v v 748 // dr0 -> bits{1-0} 749 // dr1 -> bits{3-2} 750 // dr2 -> bits{5-4} 751 // dr3 -> bits{7-6} 752 return (debug_state.__dr7 & (3 << (2*hw_index))) == 0; 753} 754 755// Resets local copy of debug status register to wait for the next debug excpetion. 756void 757DNBArchImplX86_64::ClearWatchpointHits(DBG &debug_state) 758{ 759 // See also IsWatchpointHit(). 760 debug_state.__dr6 = 0; 761 return; 762} 763 764bool 765DNBArchImplX86_64::IsWatchpointHit(const DBG &debug_state, uint32_t hw_index) 766{ 767 // Check dr6 (debug status register) whether a watchpoint hits: 768 // is watchpoint hit? 769 // | 770 // v 771 // dr0 -> bits{0} 772 // dr1 -> bits{1} 773 // dr2 -> bits{2} 774 // dr3 -> bits{3} 775 return (debug_state.__dr6 & (1 << hw_index)); 776} 777 778nub_addr_t 779DNBArchImplX86_64::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) 780{ 781 switch (hw_index) { 782 case 0: 783 return debug_state.__dr0; 784 case 1: 785 return debug_state.__dr1; 786 case 2: 787 return debug_state.__dr2; 788 case 3: 789 return debug_state.__dr3; 790 default: 791 assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); 792 } 793} 794 795bool 796DNBArchImplX86_64::StartTransForHWP() 797{ 798 if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back) 799 DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state); 800 m_2pc_dbg_checkpoint = m_state.context.dbg; 801 m_2pc_trans_state = Trans_Pending; 802 return true; 803} 804bool 805DNBArchImplX86_64::RollbackTransForHWP() 806{ 807 m_state.context.dbg = m_2pc_dbg_checkpoint; 808 if (m_2pc_trans_state != Trans_Pending) 809 DNBLogError ("%s inconsistent state detected, expected %d, got: %d", __FUNCTION__, Trans_Pending, m_2pc_trans_state); 810 m_2pc_trans_state = Trans_Rolled_Back; 811 kern_return_t kret = SetDBGState(); 812 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret); 813 814 if (kret == KERN_SUCCESS) 815 return true; 816 else 817 return false; 818} 819bool 820DNBArchImplX86_64::FinishTransForHWP() 821{ 822 m_2pc_trans_state = Trans_Done; 823 return true; 824} 825DNBArchImplX86_64::DBG 826DNBArchImplX86_64::GetDBGCheckpoint() 827{ 828 return m_2pc_dbg_checkpoint; 829} 830 831uint32_t 832DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) 833{ 834 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint(addr = 0x%llx, size = %llu, read = %u, write = %u)", (uint64_t)addr, (uint64_t)size, read, write); 835 836 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 837 838 // Can only watch 1, 2, 4, or 8 bytes. 839 if (!(size == 1 || size == 2 || size == 4 || size == 8)) 840 return INVALID_NUB_HW_INDEX; 841 842 // We must watch for either read or write 843 if (read == false && write == false) 844 return INVALID_NUB_HW_INDEX; 845 846 // Read the debug state 847 kern_return_t kret = GetDBGState(false); 848 849 if (kret == KERN_SUCCESS) 850 { 851 // Check to make sure we have the needed hardware support 852 uint32_t i = 0; 853 854 DBG &debug_state = m_state.context.dbg; 855 for (i = 0; i < num_hw_watchpoints; ++i) 856 { 857 if (IsWatchpointVacant(debug_state, i)) 858 break; 859 } 860 861 // See if we found an available hw breakpoint slot above 862 if (i < num_hw_watchpoints) 863 { 864 StartTransForHWP(); 865 866 // Modify our local copy of the debug state, first. 867 SetWatchpoint(debug_state, i, addr, size, read, write); 868 // Now set the watch point in the inferior. 869 kret = SetDBGState(); 870 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); 871 872 if (kret == KERN_SUCCESS) 873 return i; 874 else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed. 875 m_state.context.dbg = GetDBGCheckpoint(); 876 } 877 else 878 { 879 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); 880 } 881 } 882 return INVALID_NUB_HW_INDEX; 883} 884 885bool 886DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index) 887{ 888 kern_return_t kret = GetDBGState(false); 889 890 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 891 if (kret == KERN_SUCCESS) 892 { 893 DBG &debug_state = m_state.context.dbg; 894 if (hw_index < num_hw_points && !IsWatchpointVacant(debug_state, hw_index)) 895 { 896 StartTransForHWP(); 897 898 // Modify our local copy of the debug state, first. 899 ClearWatchpoint(debug_state, hw_index); 900 // Now disable the watch point in the inferior. 901 kret = SetDBGState(); 902 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::DisableHardwareWatchpoint( %u )", 903 hw_index); 904 905 if (kret == KERN_SUCCESS) 906 return true; 907 else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed. 908 m_state.context.dbg = GetDBGCheckpoint(); 909 } 910 } 911 return false; 912} 913 914DNBArchImplX86_64::DBG DNBArchImplX86_64::Global_Debug_State = {0,0,0,0,0,0,0,0}; 915bool DNBArchImplX86_64::Valid_Global_Debug_State = false; 916 917// Use this callback from MachThread, which in turn was called from MachThreadList, to update 918// the global view of the hardware watchpoint state, so that when new thread comes along, they 919// get to inherit the existing hardware watchpoint state. 920void 921DNBArchImplX86_64::HardwareWatchpointStateChanged () 922{ 923 Global_Debug_State = m_state.context.dbg; 924 Valid_Global_Debug_State = true; 925} 926 927// Iterate through the debug status register; return the index of the first hit. 928uint32_t 929DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr) 930{ 931 // Read the debug state 932 kern_return_t kret = GetDBGState(true); 933 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); 934 if (kret == KERN_SUCCESS) 935 { 936 DBG &debug_state = m_state.context.dbg; 937 uint32_t i, num = NumSupportedHardwareWatchpoints(); 938 for (i = 0; i < num; ++i) 939 { 940 if (IsWatchpointHit(debug_state, i)) 941 { 942 addr = GetWatchAddress(debug_state, i); 943 DNBLogThreadedIf(LOG_WATCHPOINTS, 944 "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u (addr = 0x%llx).", 945 i, 946 (uint64_t)addr); 947 return i; 948 } 949 } 950 } 951 return INVALID_NUB_HW_INDEX; 952} 953 954// Set the single step bit in the processor status register. 955kern_return_t 956DNBArchImplX86_64::EnableHardwareSingleStep (bool enable) 957{ 958 if (GetGPRState(false) == KERN_SUCCESS) 959 { 960 const uint32_t trace_bit = 0x100u; 961 if (enable) 962 m_state.context.gpr.__rflags |= trace_bit; 963 else 964 m_state.context.gpr.__rflags &= ~trace_bit; 965 return SetGPRState(); 966 } 967 return m_state.GetError(e_regSetGPR, Read); 968} 969 970 971//---------------------------------------------------------------------- 972// Register information defintions 973//---------------------------------------------------------------------- 974 975enum 976{ 977 gpr_rax = 0, 978 gpr_rbx, 979 gpr_rcx, 980 gpr_rdx, 981 gpr_rdi, 982 gpr_rsi, 983 gpr_rbp, 984 gpr_rsp, 985 gpr_r8, 986 gpr_r9, 987 gpr_r10, 988 gpr_r11, 989 gpr_r12, 990 gpr_r13, 991 gpr_r14, 992 gpr_r15, 993 gpr_rip, 994 gpr_rflags, 995 gpr_cs, 996 gpr_fs, 997 gpr_gs, 998 gpr_eax, 999 gpr_ebx, 1000 gpr_ecx, 1001 gpr_edx, 1002 gpr_edi, 1003 gpr_esi, 1004 gpr_ebp, 1005 gpr_esp, 1006 gpr_r8d, // Low 32 bits or r8 1007 gpr_r9d, // Low 32 bits or r9 1008 gpr_r10d, // Low 32 bits or r10 1009 gpr_r11d, // Low 32 bits or r11 1010 gpr_r12d, // Low 32 bits or r12 1011 gpr_r13d, // Low 32 bits or r13 1012 gpr_r14d, // Low 32 bits or r14 1013 gpr_r15d, // Low 32 bits or r15 1014 gpr_ax , 1015 gpr_bx , 1016 gpr_cx , 1017 gpr_dx , 1018 gpr_di , 1019 gpr_si , 1020 gpr_bp , 1021 gpr_sp , 1022 gpr_r8w, // Low 16 bits or r8 1023 gpr_r9w, // Low 16 bits or r9 1024 gpr_r10w, // Low 16 bits or r10 1025 gpr_r11w, // Low 16 bits or r11 1026 gpr_r12w, // Low 16 bits or r12 1027 gpr_r13w, // Low 16 bits or r13 1028 gpr_r14w, // Low 16 bits or r14 1029 gpr_r15w, // Low 16 bits or r15 1030 gpr_ah , 1031 gpr_bh , 1032 gpr_ch , 1033 gpr_dh , 1034 gpr_al , 1035 gpr_bl , 1036 gpr_cl , 1037 gpr_dl , 1038 gpr_dil, 1039 gpr_sil, 1040 gpr_bpl, 1041 gpr_spl, 1042 gpr_r8l, // Low 8 bits or r8 1043 gpr_r9l, // Low 8 bits or r9 1044 gpr_r10l, // Low 8 bits or r10 1045 gpr_r11l, // Low 8 bits or r11 1046 gpr_r12l, // Low 8 bits or r12 1047 gpr_r13l, // Low 8 bits or r13 1048 gpr_r14l, // Low 8 bits or r14 1049 gpr_r15l, // Low 8 bits or r15 1050 k_num_gpr_regs 1051}; 1052 1053enum { 1054 fpu_fcw, 1055 fpu_fsw, 1056 fpu_ftw, 1057 fpu_fop, 1058 fpu_ip, 1059 fpu_cs, 1060 fpu_dp, 1061 fpu_ds, 1062 fpu_mxcsr, 1063 fpu_mxcsrmask, 1064 fpu_stmm0, 1065 fpu_stmm1, 1066 fpu_stmm2, 1067 fpu_stmm3, 1068 fpu_stmm4, 1069 fpu_stmm5, 1070 fpu_stmm6, 1071 fpu_stmm7, 1072 fpu_xmm0, 1073 fpu_xmm1, 1074 fpu_xmm2, 1075 fpu_xmm3, 1076 fpu_xmm4, 1077 fpu_xmm5, 1078 fpu_xmm6, 1079 fpu_xmm7, 1080 fpu_xmm8, 1081 fpu_xmm9, 1082 fpu_xmm10, 1083 fpu_xmm11, 1084 fpu_xmm12, 1085 fpu_xmm13, 1086 fpu_xmm14, 1087 fpu_xmm15, 1088 fpu_ymm0, 1089 fpu_ymm1, 1090 fpu_ymm2, 1091 fpu_ymm3, 1092 fpu_ymm4, 1093 fpu_ymm5, 1094 fpu_ymm6, 1095 fpu_ymm7, 1096 fpu_ymm8, 1097 fpu_ymm9, 1098 fpu_ymm10, 1099 fpu_ymm11, 1100 fpu_ymm12, 1101 fpu_ymm13, 1102 fpu_ymm14, 1103 fpu_ymm15, 1104 k_num_fpu_regs, 1105 1106 // Aliases 1107 fpu_fctrl = fpu_fcw, 1108 fpu_fstat = fpu_fsw, 1109 fpu_ftag = fpu_ftw, 1110 fpu_fiseg = fpu_cs, 1111 fpu_fioff = fpu_ip, 1112 fpu_foseg = fpu_ds, 1113 fpu_fooff = fpu_dp 1114}; 1115 1116enum { 1117 exc_trapno, 1118 exc_err, 1119 exc_faultvaddr, 1120 k_num_exc_regs, 1121}; 1122 1123 1124enum gcc_dwarf_regnums 1125{ 1126 gcc_dwarf_rax = 0, 1127 gcc_dwarf_rdx = 1, 1128 gcc_dwarf_rcx = 2, 1129 gcc_dwarf_rbx = 3, 1130 gcc_dwarf_rsi = 4, 1131 gcc_dwarf_rdi = 5, 1132 gcc_dwarf_rbp = 6, 1133 gcc_dwarf_rsp = 7, 1134 gcc_dwarf_r8, 1135 gcc_dwarf_r9, 1136 gcc_dwarf_r10, 1137 gcc_dwarf_r11, 1138 gcc_dwarf_r12, 1139 gcc_dwarf_r13, 1140 gcc_dwarf_r14, 1141 gcc_dwarf_r15, 1142 gcc_dwarf_rip, 1143 gcc_dwarf_xmm0, 1144 gcc_dwarf_xmm1, 1145 gcc_dwarf_xmm2, 1146 gcc_dwarf_xmm3, 1147 gcc_dwarf_xmm4, 1148 gcc_dwarf_xmm5, 1149 gcc_dwarf_xmm6, 1150 gcc_dwarf_xmm7, 1151 gcc_dwarf_xmm8, 1152 gcc_dwarf_xmm9, 1153 gcc_dwarf_xmm10, 1154 gcc_dwarf_xmm11, 1155 gcc_dwarf_xmm12, 1156 gcc_dwarf_xmm13, 1157 gcc_dwarf_xmm14, 1158 gcc_dwarf_xmm15, 1159 gcc_dwarf_stmm0, 1160 gcc_dwarf_stmm1, 1161 gcc_dwarf_stmm2, 1162 gcc_dwarf_stmm3, 1163 gcc_dwarf_stmm4, 1164 gcc_dwarf_stmm5, 1165 gcc_dwarf_stmm6, 1166 gcc_dwarf_stmm7, 1167 gcc_dwarf_ymm0 = gcc_dwarf_xmm0, 1168 gcc_dwarf_ymm1 = gcc_dwarf_xmm1, 1169 gcc_dwarf_ymm2 = gcc_dwarf_xmm2, 1170 gcc_dwarf_ymm3 = gcc_dwarf_xmm3, 1171 gcc_dwarf_ymm4 = gcc_dwarf_xmm4, 1172 gcc_dwarf_ymm5 = gcc_dwarf_xmm5, 1173 gcc_dwarf_ymm6 = gcc_dwarf_xmm6, 1174 gcc_dwarf_ymm7 = gcc_dwarf_xmm7, 1175 gcc_dwarf_ymm8 = gcc_dwarf_xmm8, 1176 gcc_dwarf_ymm9 = gcc_dwarf_xmm9, 1177 gcc_dwarf_ymm10 = gcc_dwarf_xmm10, 1178 gcc_dwarf_ymm11 = gcc_dwarf_xmm11, 1179 gcc_dwarf_ymm12 = gcc_dwarf_xmm12, 1180 gcc_dwarf_ymm13 = gcc_dwarf_xmm13, 1181 gcc_dwarf_ymm14 = gcc_dwarf_xmm14, 1182 gcc_dwarf_ymm15 = gcc_dwarf_xmm15 1183}; 1184 1185enum gdb_regnums 1186{ 1187 gdb_rax = 0, 1188 gdb_rbx = 1, 1189 gdb_rcx = 2, 1190 gdb_rdx = 3, 1191 gdb_rsi = 4, 1192 gdb_rdi = 5, 1193 gdb_rbp = 6, 1194 gdb_rsp = 7, 1195 gdb_r8 = 8, 1196 gdb_r9 = 9, 1197 gdb_r10 = 10, 1198 gdb_r11 = 11, 1199 gdb_r12 = 12, 1200 gdb_r13 = 13, 1201 gdb_r14 = 14, 1202 gdb_r15 = 15, 1203 gdb_rip = 16, 1204 gdb_rflags = 17, 1205 gdb_cs = 18, 1206 gdb_ss = 19, 1207 gdb_ds = 20, 1208 gdb_es = 21, 1209 gdb_fs = 22, 1210 gdb_gs = 23, 1211 gdb_stmm0 = 24, 1212 gdb_stmm1 = 25, 1213 gdb_stmm2 = 26, 1214 gdb_stmm3 = 27, 1215 gdb_stmm4 = 28, 1216 gdb_stmm5 = 29, 1217 gdb_stmm6 = 30, 1218 gdb_stmm7 = 31, 1219 gdb_fctrl = 32, gdb_fcw = gdb_fctrl, 1220 gdb_fstat = 33, gdb_fsw = gdb_fstat, 1221 gdb_ftag = 34, gdb_ftw = gdb_ftag, 1222 gdb_fiseg = 35, gdb_fpu_cs = gdb_fiseg, 1223 gdb_fioff = 36, gdb_ip = gdb_fioff, 1224 gdb_foseg = 37, gdb_fpu_ds = gdb_foseg, 1225 gdb_fooff = 38, gdb_dp = gdb_fooff, 1226 gdb_fop = 39, 1227 gdb_xmm0 = 40, 1228 gdb_xmm1 = 41, 1229 gdb_xmm2 = 42, 1230 gdb_xmm3 = 43, 1231 gdb_xmm4 = 44, 1232 gdb_xmm5 = 45, 1233 gdb_xmm6 = 46, 1234 gdb_xmm7 = 47, 1235 gdb_xmm8 = 48, 1236 gdb_xmm9 = 49, 1237 gdb_xmm10 = 50, 1238 gdb_xmm11 = 51, 1239 gdb_xmm12 = 52, 1240 gdb_xmm13 = 53, 1241 gdb_xmm14 = 54, 1242 gdb_xmm15 = 55, 1243 gdb_mxcsr = 56, 1244 gdb_ymm0 = gdb_xmm0, 1245 gdb_ymm1 = gdb_xmm1, 1246 gdb_ymm2 = gdb_xmm2, 1247 gdb_ymm3 = gdb_xmm3, 1248 gdb_ymm4 = gdb_xmm4, 1249 gdb_ymm5 = gdb_xmm5, 1250 gdb_ymm6 = gdb_xmm6, 1251 gdb_ymm7 = gdb_xmm7, 1252 gdb_ymm8 = gdb_xmm8, 1253 gdb_ymm9 = gdb_xmm9, 1254 gdb_ymm10 = gdb_xmm10, 1255 gdb_ymm11 = gdb_xmm11, 1256 gdb_ymm12 = gdb_xmm12, 1257 gdb_ymm13 = gdb_xmm13, 1258 gdb_ymm14 = gdb_xmm14, 1259 gdb_ymm15 = gdb_xmm15 1260}; 1261 1262#define GPR_OFFSET(reg) (offsetof (DNBArchImplX86_64::GPR, __##reg)) 1263#define FPU_OFFSET(reg) (offsetof (DNBArchImplX86_64::FPU, __fpu_##reg) + offsetof (DNBArchImplX86_64::Context, fpu.no_avx)) 1264#define AVX_OFFSET(reg) (offsetof (DNBArchImplX86_64::AVX, __fpu_##reg) + offsetof (DNBArchImplX86_64::Context, fpu.avx)) 1265#define EXC_OFFSET(reg) (offsetof (DNBArchImplX86_64::EXC, __##reg) + offsetof (DNBArchImplX86_64::Context, exc)) 1266 1267// This does not accurately identify the location of ymm0...7 in 1268// Context.fpu.avx. That is because there is a bunch of padding 1269// in Context.fpu.avx that we don't need. Offset macros lay out 1270// the register state that Debugserver transmits to the debugger 1271// -- not to interpret the thread_get_state info. 1272#define AVX_OFFSET_YMM(n) (AVX_OFFSET(xmm7) + FPU_SIZE_XMM(xmm7) + (32 * n)) 1273 1274#define GPR_SIZE(reg) (sizeof(((DNBArchImplX86_64::GPR *)NULL)->__##reg)) 1275#define FPU_SIZE_UINT(reg) (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg)) 1276#define FPU_SIZE_MMST(reg) (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg.__mmst_reg)) 1277#define FPU_SIZE_XMM(reg) (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg.__xmm_reg)) 1278#define FPU_SIZE_YMM(reg) (32) 1279#define EXC_SIZE(reg) (sizeof(((DNBArchImplX86_64::EXC *)NULL)->__##reg)) 1280 1281// These macros will auto define the register name, alt name, register size, 1282// register offset, encoding, format and native register. This ensures that 1283// the register state structures are defined correctly and have the correct 1284// sizes and offsets. 1285#define DEFINE_GPR(reg) { e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, INVALID_NUB_REGNUM, gdb_##reg, NULL, g_invalidate_##reg } 1286#define DEFINE_GPR_ALT(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg, NULL, g_invalidate_##reg } 1287#define DEFINE_GPR_ALT2(reg, alt) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_##reg, NULL, NULL } 1288#define DEFINE_GPR_ALT3(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gen, gdb_##reg, NULL, NULL } 1289#define DEFINE_GPR_ALT4(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg, NULL, NULL } 1290 1291#define DEFINE_GPR_PSEUDO_32(reg32,reg64) { e_regSetGPR, gpr_##reg32, #reg32, NULL, Uint, Hex, 4, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 } 1292#define DEFINE_GPR_PSEUDO_16(reg16,reg64) { e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 } 1293#define DEFINE_GPR_PSEUDO_8H(reg8,reg64) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg64)+1,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 } 1294#define DEFINE_GPR_PSEUDO_8L(reg8,reg64) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 } 1295 1296// General purpose registers for 64 bit 1297 1298uint32_t g_contained_rax[] = { gpr_rax, INVALID_NUB_REGNUM }; 1299uint32_t g_contained_rbx[] = { gpr_rbx, INVALID_NUB_REGNUM }; 1300uint32_t g_contained_rcx[] = { gpr_rcx, INVALID_NUB_REGNUM }; 1301uint32_t g_contained_rdx[] = { gpr_rdx, INVALID_NUB_REGNUM }; 1302uint32_t g_contained_rdi[] = { gpr_rdi, INVALID_NUB_REGNUM }; 1303uint32_t g_contained_rsi[] = { gpr_rsi, INVALID_NUB_REGNUM }; 1304uint32_t g_contained_rbp[] = { gpr_rbp, INVALID_NUB_REGNUM }; 1305uint32_t g_contained_rsp[] = { gpr_rsp, INVALID_NUB_REGNUM }; 1306uint32_t g_contained_r8[] = { gpr_r8 , INVALID_NUB_REGNUM }; 1307uint32_t g_contained_r9[] = { gpr_r9 , INVALID_NUB_REGNUM }; 1308uint32_t g_contained_r10[] = { gpr_r10, INVALID_NUB_REGNUM }; 1309uint32_t g_contained_r11[] = { gpr_r11, INVALID_NUB_REGNUM }; 1310uint32_t g_contained_r12[] = { gpr_r12, INVALID_NUB_REGNUM }; 1311uint32_t g_contained_r13[] = { gpr_r13, INVALID_NUB_REGNUM }; 1312uint32_t g_contained_r14[] = { gpr_r14, INVALID_NUB_REGNUM }; 1313uint32_t g_contained_r15[] = { gpr_r15, INVALID_NUB_REGNUM }; 1314 1315uint32_t g_invalidate_rax[] = { gpr_rax, gpr_eax , gpr_ax , gpr_ah , gpr_al, INVALID_NUB_REGNUM }; 1316uint32_t g_invalidate_rbx[] = { gpr_rbx, gpr_ebx , gpr_bx , gpr_bh , gpr_bl, INVALID_NUB_REGNUM }; 1317uint32_t g_invalidate_rcx[] = { gpr_rcx, gpr_ecx , gpr_cx , gpr_ch , gpr_cl, INVALID_NUB_REGNUM }; 1318uint32_t g_invalidate_rdx[] = { gpr_rdx, gpr_edx , gpr_dx , gpr_dh , gpr_dl, INVALID_NUB_REGNUM }; 1319uint32_t g_invalidate_rdi[] = { gpr_rdi, gpr_edi , gpr_di , gpr_dil , INVALID_NUB_REGNUM }; 1320uint32_t g_invalidate_rsi[] = { gpr_rsi, gpr_esi , gpr_si , gpr_sil , INVALID_NUB_REGNUM }; 1321uint32_t g_invalidate_rbp[] = { gpr_rbp, gpr_ebp , gpr_bp , gpr_bpl , INVALID_NUB_REGNUM }; 1322uint32_t g_invalidate_rsp[] = { gpr_rsp, gpr_esp , gpr_sp , gpr_spl , INVALID_NUB_REGNUM }; 1323uint32_t g_invalidate_r8 [] = { gpr_r8 , gpr_r8d , gpr_r8w , gpr_r8l , INVALID_NUB_REGNUM }; 1324uint32_t g_invalidate_r9 [] = { gpr_r9 , gpr_r9d , gpr_r9w , gpr_r9l , INVALID_NUB_REGNUM }; 1325uint32_t g_invalidate_r10[] = { gpr_r10, gpr_r10d, gpr_r10w, gpr_r10l, INVALID_NUB_REGNUM }; 1326uint32_t g_invalidate_r11[] = { gpr_r11, gpr_r11d, gpr_r11w, gpr_r11l, INVALID_NUB_REGNUM }; 1327uint32_t g_invalidate_r12[] = { gpr_r12, gpr_r12d, gpr_r12w, gpr_r12l, INVALID_NUB_REGNUM }; 1328uint32_t g_invalidate_r13[] = { gpr_r13, gpr_r13d, gpr_r13w, gpr_r13l, INVALID_NUB_REGNUM }; 1329uint32_t g_invalidate_r14[] = { gpr_r14, gpr_r14d, gpr_r14w, gpr_r14l, INVALID_NUB_REGNUM }; 1330uint32_t g_invalidate_r15[] = { gpr_r15, gpr_r15d, gpr_r15w, gpr_r15l, INVALID_NUB_REGNUM }; 1331 1332const DNBRegisterInfo 1333DNBArchImplX86_64::g_gpr_registers[] = 1334{ 1335 DEFINE_GPR (rax), 1336 DEFINE_GPR (rbx), 1337 DEFINE_GPR_ALT (rcx , "arg4", GENERIC_REGNUM_ARG4), 1338 DEFINE_GPR_ALT (rdx , "arg3", GENERIC_REGNUM_ARG3), 1339 DEFINE_GPR_ALT (rdi , "arg1", GENERIC_REGNUM_ARG1), 1340 DEFINE_GPR_ALT (rsi , "arg2", GENERIC_REGNUM_ARG2), 1341 DEFINE_GPR_ALT (rbp , "fp" , GENERIC_REGNUM_FP), 1342 DEFINE_GPR_ALT (rsp , "sp" , GENERIC_REGNUM_SP), 1343 DEFINE_GPR_ALT (r8 , "arg5", GENERIC_REGNUM_ARG5), 1344 DEFINE_GPR_ALT (r9 , "arg6", GENERIC_REGNUM_ARG6), 1345 DEFINE_GPR (r10), 1346 DEFINE_GPR (r11), 1347 DEFINE_GPR (r12), 1348 DEFINE_GPR (r13), 1349 DEFINE_GPR (r14), 1350 DEFINE_GPR (r15), 1351 DEFINE_GPR_ALT4 (rip , "pc", GENERIC_REGNUM_PC), 1352 DEFINE_GPR_ALT3 (rflags, "flags", GENERIC_REGNUM_FLAGS), 1353 DEFINE_GPR_ALT2 (cs, NULL), 1354 DEFINE_GPR_ALT2 (fs, NULL), 1355 DEFINE_GPR_ALT2 (gs, NULL), 1356 DEFINE_GPR_PSEUDO_32 (eax, rax), 1357 DEFINE_GPR_PSEUDO_32 (ebx, rbx), 1358 DEFINE_GPR_PSEUDO_32 (ecx, rcx), 1359 DEFINE_GPR_PSEUDO_32 (edx, rdx), 1360 DEFINE_GPR_PSEUDO_32 (edi, rdi), 1361 DEFINE_GPR_PSEUDO_32 (esi, rsi), 1362 DEFINE_GPR_PSEUDO_32 (ebp, rbp), 1363 DEFINE_GPR_PSEUDO_32 (esp, rsp), 1364 DEFINE_GPR_PSEUDO_32 (r8d, r8), 1365 DEFINE_GPR_PSEUDO_32 (r9d, r9), 1366 DEFINE_GPR_PSEUDO_32 (r10d, r10), 1367 DEFINE_GPR_PSEUDO_32 (r11d, r11), 1368 DEFINE_GPR_PSEUDO_32 (r12d, r12), 1369 DEFINE_GPR_PSEUDO_32 (r13d, r13), 1370 DEFINE_GPR_PSEUDO_32 (r14d, r14), 1371 DEFINE_GPR_PSEUDO_32 (r15d, r15), 1372 DEFINE_GPR_PSEUDO_16 (ax , rax), 1373 DEFINE_GPR_PSEUDO_16 (bx , rbx), 1374 DEFINE_GPR_PSEUDO_16 (cx , rcx), 1375 DEFINE_GPR_PSEUDO_16 (dx , rdx), 1376 DEFINE_GPR_PSEUDO_16 (di , rdi), 1377 DEFINE_GPR_PSEUDO_16 (si , rsi), 1378 DEFINE_GPR_PSEUDO_16 (bp , rbp), 1379 DEFINE_GPR_PSEUDO_16 (sp , rsp), 1380 DEFINE_GPR_PSEUDO_16 (r8w, r8), 1381 DEFINE_GPR_PSEUDO_16 (r9w, r9), 1382 DEFINE_GPR_PSEUDO_16 (r10w, r10), 1383 DEFINE_GPR_PSEUDO_16 (r11w, r11), 1384 DEFINE_GPR_PSEUDO_16 (r12w, r12), 1385 DEFINE_GPR_PSEUDO_16 (r13w, r13), 1386 DEFINE_GPR_PSEUDO_16 (r14w, r14), 1387 DEFINE_GPR_PSEUDO_16 (r15w, r15), 1388 DEFINE_GPR_PSEUDO_8H (ah , rax), 1389 DEFINE_GPR_PSEUDO_8H (bh , rbx), 1390 DEFINE_GPR_PSEUDO_8H (ch , rcx), 1391 DEFINE_GPR_PSEUDO_8H (dh , rdx), 1392 DEFINE_GPR_PSEUDO_8L (al , rax), 1393 DEFINE_GPR_PSEUDO_8L (bl , rbx), 1394 DEFINE_GPR_PSEUDO_8L (cl , rcx), 1395 DEFINE_GPR_PSEUDO_8L (dl , rdx), 1396 DEFINE_GPR_PSEUDO_8L (dil, rdi), 1397 DEFINE_GPR_PSEUDO_8L (sil, rsi), 1398 DEFINE_GPR_PSEUDO_8L (bpl, rbp), 1399 DEFINE_GPR_PSEUDO_8L (spl, rsp), 1400 DEFINE_GPR_PSEUDO_8L (r8l, r8), 1401 DEFINE_GPR_PSEUDO_8L (r9l, r9), 1402 DEFINE_GPR_PSEUDO_8L (r10l, r10), 1403 DEFINE_GPR_PSEUDO_8L (r11l, r11), 1404 DEFINE_GPR_PSEUDO_8L (r12l, r12), 1405 DEFINE_GPR_PSEUDO_8L (r13l, r13), 1406 DEFINE_GPR_PSEUDO_8L (r14l, r14), 1407 DEFINE_GPR_PSEUDO_8L (r15l, r15) 1408}; 1409 1410// Floating point registers 64 bit 1411const DNBRegisterInfo 1412DNBArchImplX86_64::g_fpu_registers_no_avx[] = 1413{ 1414 { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1U, -1U, -1U, -1U, NULL, NULL }, 1415 { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1U, -1U, -1U, -1U, NULL, NULL }, 1416 { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1U, -1U, -1U, -1U, NULL, NULL }, 1417 { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1U, -1U, -1U, -1U, NULL, NULL }, 1418 { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1U, -1U, -1U, -1U, NULL, NULL }, 1419 { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1U, -1U, -1U, -1U, NULL, NULL }, 1420 { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1U, -1U, -1U, -1U, NULL, NULL }, 1421 { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1U, -1U, -1U, -1U, NULL, NULL }, 1422 { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1U, -1U, -1U, -1U, NULL, NULL }, 1423 { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U, NULL, NULL }, 1424 1425 { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0, NULL, NULL }, 1426 { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1, NULL, NULL }, 1427 { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2, NULL, NULL }, 1428 { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3, NULL, NULL }, 1429 { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4, NULL, NULL }, 1430 { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5, NULL, NULL }, 1431 { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6, NULL, NULL }, 1432 { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7, NULL, NULL }, 1433 1434 { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , FPU_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 , NULL, NULL }, 1435 { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , FPU_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 , NULL, NULL }, 1436 { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , FPU_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 , NULL, NULL }, 1437 { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , FPU_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 , NULL, NULL }, 1438 { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , FPU_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 , NULL, NULL }, 1439 { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , FPU_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 , NULL, NULL }, 1440 { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , FPU_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 , NULL, NULL }, 1441 { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , FPU_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 , NULL, NULL }, 1442 { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , FPU_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 , NULL, NULL }, 1443 { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , FPU_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 , NULL, NULL }, 1444 { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , FPU_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10, NULL, NULL }, 1445 { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , FPU_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11, NULL, NULL }, 1446 { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , FPU_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12, NULL, NULL }, 1447 { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , FPU_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13, NULL, NULL }, 1448 { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , FPU_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14, NULL, NULL }, 1449 { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , FPU_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15, NULL, NULL }, 1450}; 1451 1452const DNBRegisterInfo 1453DNBArchImplX86_64::g_fpu_registers_avx[] = 1454{ 1455 { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1U, -1U, -1U, -1U, NULL, NULL }, 1456 { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1U, -1U, -1U, -1U, NULL, NULL }, 1457 { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1U, -1U, -1U, -1U, NULL, NULL }, 1458 { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1U, -1U, -1U, -1U, NULL, NULL }, 1459 { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1U, -1U, -1U, -1U, NULL, NULL }, 1460 { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1U, -1U, -1U, -1U, NULL, NULL }, 1461 { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1U, -1U, -1U, -1U, NULL, NULL }, 1462 { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1U, -1U, -1U, -1U, NULL, NULL }, 1463 { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1U, -1U, -1U, -1U, NULL, NULL }, 1464 { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U, NULL, NULL }, 1465 1466 { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0, NULL, NULL }, 1467 { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1, NULL, NULL }, 1468 { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2, NULL, NULL }, 1469 { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3, NULL, NULL }, 1470 { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4, NULL, NULL }, 1471 { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5, NULL, NULL }, 1472 { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6, NULL, NULL }, 1473 { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7, NULL, NULL }, 1474 1475 { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , AVX_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 , NULL, NULL }, 1476 { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , AVX_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 , NULL, NULL }, 1477 { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , AVX_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 , NULL, NULL }, 1478 { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , AVX_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 , NULL, NULL }, 1479 { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , AVX_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 , NULL, NULL }, 1480 { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , AVX_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 , NULL, NULL }, 1481 { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , AVX_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 , NULL, NULL }, 1482 { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , AVX_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 , NULL, NULL }, 1483 { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , AVX_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 , NULL, NULL }, 1484 { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , AVX_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 , NULL, NULL }, 1485 { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , AVX_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10, NULL, NULL }, 1486 { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , AVX_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11, NULL, NULL }, 1487 { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , AVX_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12, NULL, NULL }, 1488 { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , AVX_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13, NULL, NULL }, 1489 { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , AVX_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14, NULL, NULL }, 1490 { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , AVX_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15, NULL, NULL }, 1491 1492 { e_regSetFPU, fpu_ymm0 , "ymm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0) , AVX_OFFSET_YMM(0) , gcc_dwarf_ymm0 , gcc_dwarf_ymm0 , -1U, gdb_ymm0, NULL, NULL }, 1493 { e_regSetFPU, fpu_ymm1 , "ymm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1) , AVX_OFFSET_YMM(1) , gcc_dwarf_ymm1 , gcc_dwarf_ymm1 , -1U, gdb_ymm1, NULL, NULL }, 1494 { e_regSetFPU, fpu_ymm2 , "ymm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2) , AVX_OFFSET_YMM(2) , gcc_dwarf_ymm2 , gcc_dwarf_ymm2 , -1U, gdb_ymm2, NULL, NULL }, 1495 { e_regSetFPU, fpu_ymm3 , "ymm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3) , AVX_OFFSET_YMM(3) , gcc_dwarf_ymm3 , gcc_dwarf_ymm3 , -1U, gdb_ymm3, NULL, NULL }, 1496 { e_regSetFPU, fpu_ymm4 , "ymm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4) , AVX_OFFSET_YMM(4) , gcc_dwarf_ymm4 , gcc_dwarf_ymm4 , -1U, gdb_ymm4, NULL, NULL }, 1497 { e_regSetFPU, fpu_ymm5 , "ymm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5) , AVX_OFFSET_YMM(5) , gcc_dwarf_ymm5 , gcc_dwarf_ymm5 , -1U, gdb_ymm5, NULL, NULL }, 1498 { e_regSetFPU, fpu_ymm6 , "ymm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6) , AVX_OFFSET_YMM(6) , gcc_dwarf_ymm6 , gcc_dwarf_ymm6 , -1U, gdb_ymm6, NULL, NULL }, 1499 { e_regSetFPU, fpu_ymm7 , "ymm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7) , AVX_OFFSET_YMM(7) , gcc_dwarf_ymm7 , gcc_dwarf_ymm7 , -1U, gdb_ymm7, NULL, NULL }, 1500 { e_regSetFPU, fpu_ymm8 , "ymm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm8) , AVX_OFFSET_YMM(8) , gcc_dwarf_ymm8 , gcc_dwarf_ymm8 , -1U, gdb_ymm8 , NULL, NULL }, 1501 { e_regSetFPU, fpu_ymm9 , "ymm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm9) , AVX_OFFSET_YMM(9) , gcc_dwarf_ymm9 , gcc_dwarf_ymm9 , -1U, gdb_ymm9 , NULL, NULL }, 1502 { e_regSetFPU, fpu_ymm10, "ymm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm10) , AVX_OFFSET_YMM(10), gcc_dwarf_ymm10, gcc_dwarf_ymm10, -1U, gdb_ymm10, NULL, NULL }, 1503 { e_regSetFPU, fpu_ymm11, "ymm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm11) , AVX_OFFSET_YMM(11), gcc_dwarf_ymm11, gcc_dwarf_ymm11, -1U, gdb_ymm11, NULL, NULL }, 1504 { e_regSetFPU, fpu_ymm12, "ymm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm12) , AVX_OFFSET_YMM(12), gcc_dwarf_ymm12, gcc_dwarf_ymm12, -1U, gdb_ymm12, NULL, NULL }, 1505 { e_regSetFPU, fpu_ymm13, "ymm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm13) , AVX_OFFSET_YMM(13), gcc_dwarf_ymm13, gcc_dwarf_ymm13, -1U, gdb_ymm13, NULL, NULL }, 1506 { e_regSetFPU, fpu_ymm14, "ymm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm14) , AVX_OFFSET_YMM(14), gcc_dwarf_ymm14, gcc_dwarf_ymm14, -1U, gdb_ymm14, NULL, NULL }, 1507 { e_regSetFPU, fpu_ymm15, "ymm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm15) , AVX_OFFSET_YMM(15), gcc_dwarf_ymm15, gcc_dwarf_ymm15, -1U, gdb_ymm15, NULL, NULL } 1508}; 1509 1510// Exception registers 1511 1512const DNBRegisterInfo 1513DNBArchImplX86_64::g_exc_registers[] = 1514{ 1515 { e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1U, -1U, -1U, -1U, NULL, NULL }, 1516 { e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1U, -1U, -1U, -1U, NULL, NULL }, 1517 { e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1U, -1U, -1U, -1U, NULL, NULL } 1518}; 1519 1520// Number of registers in each register set 1521const size_t DNBArchImplX86_64::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo); 1522const size_t DNBArchImplX86_64::k_num_fpu_registers_no_avx = sizeof(g_fpu_registers_no_avx)/sizeof(DNBRegisterInfo); 1523const size_t DNBArchImplX86_64::k_num_fpu_registers_avx = sizeof(g_fpu_registers_avx)/sizeof(DNBRegisterInfo); 1524const size_t DNBArchImplX86_64::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo); 1525const size_t DNBArchImplX86_64::k_num_all_registers_no_avx = k_num_gpr_registers + k_num_fpu_registers_no_avx + k_num_exc_registers; 1526const size_t DNBArchImplX86_64::k_num_all_registers_avx = k_num_gpr_registers + k_num_fpu_registers_avx + k_num_exc_registers; 1527 1528//---------------------------------------------------------------------- 1529// Register set definitions. The first definitions at register set index 1530// of zero is for all registers, followed by other registers sets. The 1531// register information for the all register set need not be filled in. 1532//---------------------------------------------------------------------- 1533const DNBRegisterSetInfo 1534DNBArchImplX86_64::g_reg_sets_no_avx[] = 1535{ 1536 { "x86_64 Registers", NULL, k_num_all_registers_no_avx }, 1537 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers }, 1538 { "Floating Point Registers", g_fpu_registers_no_avx, k_num_fpu_registers_no_avx }, 1539 { "Exception State Registers", g_exc_registers, k_num_exc_registers } 1540}; 1541 1542const DNBRegisterSetInfo 1543DNBArchImplX86_64::g_reg_sets_avx[] = 1544{ 1545 { "x86_64 Registers", NULL, k_num_all_registers_avx }, 1546 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers }, 1547 { "Floating Point Registers", g_fpu_registers_avx, k_num_fpu_registers_avx }, 1548 { "Exception State Registers", g_exc_registers, k_num_exc_registers } 1549}; 1550 1551// Total number of register sets for this architecture 1552const size_t DNBArchImplX86_64::k_num_register_sets = sizeof(g_reg_sets_avx)/sizeof(DNBRegisterSetInfo); 1553 1554 1555DNBArchProtocol * 1556DNBArchImplX86_64::Create (MachThread *thread) 1557{ 1558 DNBArchImplX86_64 *obj = new DNBArchImplX86_64 (thread); 1559 1560 // When new thread comes along, it tries to inherit from the global debug state, if it is valid. 1561 if (Valid_Global_Debug_State) 1562 { 1563 obj->m_state.context.dbg = Global_Debug_State; 1564 kern_return_t kret = obj->SetDBGState(); 1565 DNBLogThreadedIf(LOG_WATCHPOINTS, 1566 "DNBArchImplX86_64::Create() Inherit and SetDBGState() => 0x%8.8x.", kret); 1567 } 1568 return obj; 1569} 1570 1571const uint8_t * const 1572DNBArchImplX86_64::SoftwareBreakpointOpcode (nub_size_t byte_size) 1573{ 1574 static const uint8_t g_breakpoint_opcode[] = { 0xCC }; 1575 if (byte_size == 1) 1576 return g_breakpoint_opcode; 1577 return NULL; 1578} 1579 1580const DNBRegisterSetInfo * 1581DNBArchImplX86_64::GetRegisterSetInfo(nub_size_t *num_reg_sets) 1582{ 1583 *num_reg_sets = k_num_register_sets; 1584 1585 if (CPUHasAVX() || FORCE_AVX_REGS) 1586 return g_reg_sets_avx; 1587 else 1588 return g_reg_sets_no_avx; 1589} 1590 1591void 1592DNBArchImplX86_64::Initialize() 1593{ 1594 DNBArchPluginInfo arch_plugin_info = 1595 { 1596 CPU_TYPE_X86_64, 1597 DNBArchImplX86_64::Create, 1598 DNBArchImplX86_64::GetRegisterSetInfo, 1599 DNBArchImplX86_64::SoftwareBreakpointOpcode 1600 }; 1601 1602 // Register this arch plug-in with the main protocol class 1603 DNBArchProtocol::RegisterArchPlugin (arch_plugin_info); 1604} 1605 1606bool 1607DNBArchImplX86_64::GetRegisterValue(int set, int reg, DNBRegisterValue *value) 1608{ 1609 if (set == REGISTER_SET_GENERIC) 1610 { 1611 switch (reg) 1612 { 1613 case GENERIC_REGNUM_PC: // Program Counter 1614 set = e_regSetGPR; 1615 reg = gpr_rip; 1616 break; 1617 1618 case GENERIC_REGNUM_SP: // Stack Pointer 1619 set = e_regSetGPR; 1620 reg = gpr_rsp; 1621 break; 1622 1623 case GENERIC_REGNUM_FP: // Frame Pointer 1624 set = e_regSetGPR; 1625 reg = gpr_rbp; 1626 break; 1627 1628 case GENERIC_REGNUM_FLAGS: // Processor flags register 1629 set = e_regSetGPR; 1630 reg = gpr_rflags; 1631 break; 1632 1633 case GENERIC_REGNUM_RA: // Return Address 1634 default: 1635 return false; 1636 } 1637 } 1638 1639 if (GetRegisterState(set, false) != KERN_SUCCESS) 1640 return false; 1641 1642 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 1643 if (regInfo) 1644 { 1645 value->info = *regInfo; 1646 switch (set) 1647 { 1648 case e_regSetGPR: 1649 if (reg < k_num_gpr_registers) 1650 { 1651 value->value.uint64 = ((uint64_t*)(&m_state.context.gpr))[reg]; 1652 return true; 1653 } 1654 break; 1655 1656 case e_regSetFPU: 1657 if (CPUHasAVX() || FORCE_AVX_REGS) 1658 { 1659 switch (reg) 1660 { 1661 case fpu_fcw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fcw)); return true; 1662 case fpu_fsw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fsw)); return true; 1663 case fpu_ftw: value->value.uint8 = m_state.context.fpu.avx.__fpu_ftw; return true; 1664 case fpu_fop: value->value.uint16 = m_state.context.fpu.avx.__fpu_fop; return true; 1665 case fpu_ip: value->value.uint32 = m_state.context.fpu.avx.__fpu_ip; return true; 1666 case fpu_cs: value->value.uint16 = m_state.context.fpu.avx.__fpu_cs; return true; 1667 case fpu_dp: value->value.uint32 = m_state.context.fpu.avx.__fpu_dp; return true; 1668 case fpu_ds: value->value.uint16 = m_state.context.fpu.avx.__fpu_ds; return true; 1669 case fpu_mxcsr: value->value.uint32 = m_state.context.fpu.avx.__fpu_mxcsr; return true; 1670 case fpu_mxcsrmask: value->value.uint32 = m_state.context.fpu.avx.__fpu_mxcsrmask; return true; 1671 1672 case fpu_stmm0: 1673 case fpu_stmm1: 1674 case fpu_stmm2: 1675 case fpu_stmm3: 1676 case fpu_stmm4: 1677 case fpu_stmm5: 1678 case fpu_stmm6: 1679 case fpu_stmm7: 1680 memcpy(&value->value.uint8, &m_state.context.fpu.avx.__fpu_stmm0 + (reg - fpu_stmm0), 10); 1681 return true; 1682 1683 case fpu_xmm0: 1684 case fpu_xmm1: 1685 case fpu_xmm2: 1686 case fpu_xmm3: 1687 case fpu_xmm4: 1688 case fpu_xmm5: 1689 case fpu_xmm6: 1690 case fpu_xmm7: 1691 case fpu_xmm8: 1692 case fpu_xmm9: 1693 case fpu_xmm10: 1694 case fpu_xmm11: 1695 case fpu_xmm12: 1696 case fpu_xmm13: 1697 case fpu_xmm14: 1698 case fpu_xmm15: 1699 memcpy(&value->value.uint8, &m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_xmm0), 16); 1700 return true; 1701 1702 case fpu_ymm0: 1703 case fpu_ymm1: 1704 case fpu_ymm2: 1705 case fpu_ymm3: 1706 case fpu_ymm4: 1707 case fpu_ymm5: 1708 case fpu_ymm6: 1709 case fpu_ymm7: 1710 case fpu_ymm8: 1711 case fpu_ymm9: 1712 case fpu_ymm10: 1713 case fpu_ymm11: 1714 case fpu_ymm12: 1715 case fpu_ymm13: 1716 case fpu_ymm14: 1717 case fpu_ymm15: 1718 memcpy(&value->value.uint8, &m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_ymm0), 16); 1719 memcpy((&value->value.uint8) + 16, &m_state.context.fpu.avx.__fpu_ymmh0 + (reg - fpu_ymm0), 16); 1720 return true; 1721 } 1722 } 1723 else 1724 { 1725 switch (reg) 1726 { 1727 case fpu_fcw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)); return true; 1728 case fpu_fsw: value->value.uint16 = *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)); return true; 1729 case fpu_ftw: value->value.uint8 = m_state.context.fpu.no_avx.__fpu_ftw; return true; 1730 case fpu_fop: value->value.uint16 = m_state.context.fpu.no_avx.__fpu_fop; return true; 1731 case fpu_ip: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_ip; return true; 1732 case fpu_cs: value->value.uint16 = m_state.context.fpu.no_avx.__fpu_cs; return true; 1733 case fpu_dp: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_dp; return true; 1734 case fpu_ds: value->value.uint16 = m_state.context.fpu.no_avx.__fpu_ds; return true; 1735 case fpu_mxcsr: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsr; return true; 1736 case fpu_mxcsrmask: value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsrmask; return true; 1737 1738 case fpu_stmm0: 1739 case fpu_stmm1: 1740 case fpu_stmm2: 1741 case fpu_stmm3: 1742 case fpu_stmm4: 1743 case fpu_stmm5: 1744 case fpu_stmm6: 1745 case fpu_stmm7: 1746 memcpy(&value->value.uint8, &m_state.context.fpu.no_avx.__fpu_stmm0 + (reg - fpu_stmm0), 10); 1747 return true; 1748 1749 case fpu_xmm0: 1750 case fpu_xmm1: 1751 case fpu_xmm2: 1752 case fpu_xmm3: 1753 case fpu_xmm4: 1754 case fpu_xmm5: 1755 case fpu_xmm6: 1756 case fpu_xmm7: 1757 case fpu_xmm8: 1758 case fpu_xmm9: 1759 case fpu_xmm10: 1760 case fpu_xmm11: 1761 case fpu_xmm12: 1762 case fpu_xmm13: 1763 case fpu_xmm14: 1764 case fpu_xmm15: 1765 memcpy(&value->value.uint8, &m_state.context.fpu.no_avx.__fpu_xmm0 + (reg - fpu_xmm0), 16); 1766 return true; 1767 } 1768 } 1769 break; 1770 1771 case e_regSetEXC: 1772 switch (reg) 1773 { 1774 case exc_trapno: value->value.uint32 = m_state.context.exc.__trapno; return true; 1775 case exc_err: value->value.uint32 = m_state.context.exc.__err; return true; 1776 case exc_faultvaddr:value->value.uint64 = m_state.context.exc.__faultvaddr; return true; 1777 } 1778 break; 1779 } 1780 } 1781 return false; 1782} 1783 1784 1785bool 1786DNBArchImplX86_64::SetRegisterValue(int set, int reg, const DNBRegisterValue *value) 1787{ 1788 if (set == REGISTER_SET_GENERIC) 1789 { 1790 switch (reg) 1791 { 1792 case GENERIC_REGNUM_PC: // Program Counter 1793 set = e_regSetGPR; 1794 reg = gpr_rip; 1795 break; 1796 1797 case GENERIC_REGNUM_SP: // Stack Pointer 1798 set = e_regSetGPR; 1799 reg = gpr_rsp; 1800 break; 1801 1802 case GENERIC_REGNUM_FP: // Frame Pointer 1803 set = e_regSetGPR; 1804 reg = gpr_rbp; 1805 break; 1806 1807 case GENERIC_REGNUM_FLAGS: // Processor flags register 1808 set = e_regSetGPR; 1809 reg = gpr_rflags; 1810 break; 1811 1812 case GENERIC_REGNUM_RA: // Return Address 1813 default: 1814 return false; 1815 } 1816 } 1817 1818 if (GetRegisterState(set, false) != KERN_SUCCESS) 1819 return false; 1820 1821 bool success = false; 1822 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 1823 if (regInfo) 1824 { 1825 switch (set) 1826 { 1827 case e_regSetGPR: 1828 if (reg < k_num_gpr_registers) 1829 { 1830 ((uint64_t*)(&m_state.context.gpr))[reg] = value->value.uint64; 1831 success = true; 1832 } 1833 break; 1834 1835 case e_regSetFPU: 1836 if (CPUHasAVX() || FORCE_AVX_REGS) 1837 { 1838 switch (reg) 1839 { 1840 case fpu_fcw: *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fcw)) = value->value.uint16; success = true; break; 1841 case fpu_fsw: *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fsw)) = value->value.uint16; success = true; break; 1842 case fpu_ftw: m_state.context.fpu.avx.__fpu_ftw = value->value.uint8; success = true; break; 1843 case fpu_fop: m_state.context.fpu.avx.__fpu_fop = value->value.uint16; success = true; break; 1844 case fpu_ip: m_state.context.fpu.avx.__fpu_ip = value->value.uint32; success = true; break; 1845 case fpu_cs: m_state.context.fpu.avx.__fpu_cs = value->value.uint16; success = true; break; 1846 case fpu_dp: m_state.context.fpu.avx.__fpu_dp = value->value.uint32; success = true; break; 1847 case fpu_ds: m_state.context.fpu.avx.__fpu_ds = value->value.uint16; success = true; break; 1848 case fpu_mxcsr: m_state.context.fpu.avx.__fpu_mxcsr = value->value.uint32; success = true; break; 1849 case fpu_mxcsrmask: m_state.context.fpu.avx.__fpu_mxcsrmask = value->value.uint32; success = true; break; 1850 1851 case fpu_stmm0: 1852 case fpu_stmm1: 1853 case fpu_stmm2: 1854 case fpu_stmm3: 1855 case fpu_stmm4: 1856 case fpu_stmm5: 1857 case fpu_stmm6: 1858 case fpu_stmm7: 1859 memcpy (&m_state.context.fpu.avx.__fpu_stmm0 + (reg - fpu_stmm0), &value->value.uint8, 10); 1860 success = true; 1861 break; 1862 1863 case fpu_xmm0: 1864 case fpu_xmm1: 1865 case fpu_xmm2: 1866 case fpu_xmm3: 1867 case fpu_xmm4: 1868 case fpu_xmm5: 1869 case fpu_xmm6: 1870 case fpu_xmm7: 1871 case fpu_xmm8: 1872 case fpu_xmm9: 1873 case fpu_xmm10: 1874 case fpu_xmm11: 1875 case fpu_xmm12: 1876 case fpu_xmm13: 1877 case fpu_xmm14: 1878 case fpu_xmm15: 1879 memcpy (&m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_xmm0), &value->value.uint8, 16); 1880 success = true; 1881 break; 1882 1883 case fpu_ymm0: 1884 case fpu_ymm1: 1885 case fpu_ymm2: 1886 case fpu_ymm3: 1887 case fpu_ymm4: 1888 case fpu_ymm5: 1889 case fpu_ymm6: 1890 case fpu_ymm7: 1891 case fpu_ymm8: 1892 case fpu_ymm9: 1893 case fpu_ymm10: 1894 case fpu_ymm11: 1895 case fpu_ymm12: 1896 case fpu_ymm13: 1897 case fpu_ymm14: 1898 case fpu_ymm15: 1899 memcpy(&m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_ymm0), &value->value.uint8, 16); 1900 memcpy(&m_state.context.fpu.avx.__fpu_ymmh0 + (reg - fpu_ymm0), (&value->value.uint8) + 16, 16); 1901 return true; 1902 } 1903 } 1904 else 1905 { 1906 switch (reg) 1907 { 1908 case fpu_fcw: *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)) = value->value.uint16; success = true; break; 1909 case fpu_fsw: *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)) = value->value.uint16; success = true; break; 1910 case fpu_ftw: m_state.context.fpu.no_avx.__fpu_ftw = value->value.uint8; success = true; break; 1911 case fpu_fop: m_state.context.fpu.no_avx.__fpu_fop = value->value.uint16; success = true; break; 1912 case fpu_ip: m_state.context.fpu.no_avx.__fpu_ip = value->value.uint32; success = true; break; 1913 case fpu_cs: m_state.context.fpu.no_avx.__fpu_cs = value->value.uint16; success = true; break; 1914 case fpu_dp: m_state.context.fpu.no_avx.__fpu_dp = value->value.uint32; success = true; break; 1915 case fpu_ds: m_state.context.fpu.no_avx.__fpu_ds = value->value.uint16; success = true; break; 1916 case fpu_mxcsr: m_state.context.fpu.no_avx.__fpu_mxcsr = value->value.uint32; success = true; break; 1917 case fpu_mxcsrmask: m_state.context.fpu.no_avx.__fpu_mxcsrmask = value->value.uint32; success = true; break; 1918 1919 case fpu_stmm0: 1920 case fpu_stmm1: 1921 case fpu_stmm2: 1922 case fpu_stmm3: 1923 case fpu_stmm4: 1924 case fpu_stmm5: 1925 case fpu_stmm6: 1926 case fpu_stmm7: 1927 memcpy (&m_state.context.fpu.no_avx.__fpu_stmm0 + (reg - fpu_stmm0), &value->value.uint8, 10); 1928 success = true; 1929 break; 1930 1931 case fpu_xmm0: 1932 case fpu_xmm1: 1933 case fpu_xmm2: 1934 case fpu_xmm3: 1935 case fpu_xmm4: 1936 case fpu_xmm5: 1937 case fpu_xmm6: 1938 case fpu_xmm7: 1939 case fpu_xmm8: 1940 case fpu_xmm9: 1941 case fpu_xmm10: 1942 case fpu_xmm11: 1943 case fpu_xmm12: 1944 case fpu_xmm13: 1945 case fpu_xmm14: 1946 case fpu_xmm15: 1947 memcpy (&m_state.context.fpu.no_avx.__fpu_xmm0 + (reg - fpu_xmm0), &value->value.uint8, 16); 1948 success = true; 1949 break; 1950 } 1951 } 1952 break; 1953 1954 case e_regSetEXC: 1955 switch (reg) 1956 { 1957 case exc_trapno: m_state.context.exc.__trapno = value->value.uint32; success = true; break; 1958 case exc_err: m_state.context.exc.__err = value->value.uint32; success = true; break; 1959 case exc_faultvaddr:m_state.context.exc.__faultvaddr = value->value.uint64; success = true; break; 1960 } 1961 break; 1962 } 1963 } 1964 1965 if (success) 1966 return SetRegisterState(set) == KERN_SUCCESS; 1967 return false; 1968} 1969 1970 1971nub_size_t 1972DNBArchImplX86_64::GetRegisterContext (void *buf, nub_size_t buf_len) 1973{ 1974 nub_size_t size = sizeof (m_state.context); 1975 1976 if (buf && buf_len) 1977 { 1978 if (size > buf_len) 1979 size = buf_len; 1980 1981 bool force = false; 1982 kern_return_t kret; 1983 if ((kret = GetGPRState(force)) != KERN_SUCCESS) 1984 { 1985 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = %llu) error: GPR regs failed to read: %u ", buf, (uint64_t)buf_len, kret); 1986 size = 0; 1987 } 1988 else 1989 if ((kret = GetFPUState(force)) != KERN_SUCCESS) 1990 { 1991 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = %llu) error: %s regs failed to read: %u", buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret); 1992 size = 0; 1993 } 1994 else 1995 if ((kret = GetEXCState(force)) != KERN_SUCCESS) 1996 { 1997 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = %llu) error: EXC regs failed to read: %u", buf, (uint64_t)buf_len, kret); 1998 size = 0; 1999 } 2000 else 2001 { 2002 // Success 2003 ::memcpy (buf, &m_state.context, size); 2004 } 2005 } 2006 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = %llu) => %llu", buf, (uint64_t)buf_len, (uint64_t)size); 2007 // Return the size of the register context even if NULL was passed in 2008 return size; 2009} 2010 2011nub_size_t 2012DNBArchImplX86_64::SetRegisterContext (const void *buf, nub_size_t buf_len) 2013{ 2014 nub_size_t size = sizeof (m_state.context); 2015 if (buf == NULL || buf_len == 0) 2016 size = 0; 2017 2018 if (size) 2019 { 2020 if (size > buf_len) 2021 size = buf_len; 2022 2023 ::memcpy (&m_state.context, buf, size); 2024 kern_return_t kret; 2025 if ((kret = SetGPRState()) != KERN_SUCCESS) 2026 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = %llu) error: GPR regs failed to write: %u", buf, (uint64_t)buf_len, kret); 2027 if ((kret = SetFPUState()) != KERN_SUCCESS) 2028 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = %llu) error: %s regs failed to write: %u", buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret); 2029 if ((kret = SetEXCState()) != KERN_SUCCESS) 2030 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = %llu) error: EXP regs failed to write: %u", buf, (uint64_t)buf_len, kret); 2031 } 2032 DNBLogThreadedIf (LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = %llu) => %llu", buf, (uint64_t)buf_len, (uint64_t)size); 2033 return size; 2034} 2035 2036 2037kern_return_t 2038DNBArchImplX86_64::GetRegisterState(int set, bool force) 2039{ 2040 switch (set) 2041 { 2042 case e_regSetALL: return GetGPRState(force) | GetFPUState(force) | GetEXCState(force); 2043 case e_regSetGPR: return GetGPRState(force); 2044 case e_regSetFPU: return GetFPUState(force); 2045 case e_regSetEXC: return GetEXCState(force); 2046 default: break; 2047 } 2048 return KERN_INVALID_ARGUMENT; 2049} 2050 2051kern_return_t 2052DNBArchImplX86_64::SetRegisterState(int set) 2053{ 2054 // Make sure we have a valid context to set. 2055 if (RegisterSetStateIsValid(set)) 2056 { 2057 switch (set) 2058 { 2059 case e_regSetALL: return SetGPRState() | SetFPUState() | SetEXCState(); 2060 case e_regSetGPR: return SetGPRState(); 2061 case e_regSetFPU: return SetFPUState(); 2062 case e_regSetEXC: return SetEXCState(); 2063 default: break; 2064 } 2065 } 2066 return KERN_INVALID_ARGUMENT; 2067} 2068 2069bool 2070DNBArchImplX86_64::RegisterSetStateIsValid (int set) const 2071{ 2072 return m_state.RegsAreValid(set); 2073} 2074 2075 2076 2077#endif // #if defined (__i386__) || defined (__x86_64__) 2078