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/sysctl.h> 18 #include <sys/types.h> 19 20 #include "../HasAVX.h" 21 #include "DNBLog.h" 22 #include "MacOSX/x86_64/DNBArchImplX86_64.h" 23 #include "MachProcess.h" 24 #include "MachThread.h" 25 #include <mach/mach.h> 26 #include <stdlib.h> 27 28 #if defined(LLDB_DEBUGSERVER_RELEASE) || defined(LLDB_DEBUGSERVER_DEBUG) 29 enum debugState { debugStateUnknown, debugStateOff, debugStateOn }; 30 31 static debugState sFPUDebugState = debugStateUnknown; 32 static debugState sAVXForceState = debugStateUnknown; 33 34 static bool DebugFPURegs() { 35 if (sFPUDebugState == debugStateUnknown) { 36 if (getenv("DNB_DEBUG_FPU_REGS")) 37 sFPUDebugState = debugStateOn; 38 else 39 sFPUDebugState = debugStateOff; 40 } 41 42 return (sFPUDebugState == debugStateOn); 43 } 44 45 static bool ForceAVXRegs() { 46 if (sFPUDebugState == debugStateUnknown) { 47 if (getenv("DNB_DEBUG_X86_FORCE_AVX_REGS")) 48 sAVXForceState = debugStateOn; 49 else 50 sAVXForceState = debugStateOff; 51 } 52 53 return (sAVXForceState == debugStateOn); 54 } 55 56 #define DEBUG_FPU_REGS (DebugFPURegs()) 57 #define FORCE_AVX_REGS (ForceAVXRegs()) 58 #else 59 #define DEBUG_FPU_REGS (0) 60 #define FORCE_AVX_REGS (0) 61 #endif 62 63 extern "C" bool CPUHasAVX() { 64 enum AVXPresence { eAVXUnknown = -1, eAVXNotPresent = 0, eAVXPresent = 1 }; 65 66 static AVXPresence g_has_avx = eAVXUnknown; 67 if (g_has_avx == eAVXUnknown) { 68 g_has_avx = eAVXNotPresent; 69 70 // Only xnu-2020 or later has AVX support, any versions before 71 // this have a busted thread_get_state RPC where it would truncate 72 // the thread state buffer (<rdar://problem/10122874>). So we need to 73 // verify the kernel version number manually or disable AVX support. 74 int mib[2]; 75 char buffer[1024]; 76 size_t length = sizeof(buffer); 77 uint64_t xnu_version = 0; 78 mib[0] = CTL_KERN; 79 mib[1] = KERN_VERSION; 80 int err = ::sysctl(mib, 2, &buffer, &length, NULL, 0); 81 if (err == 0) { 82 const char *xnu = strstr(buffer, "xnu-"); 83 if (xnu) { 84 const char *xnu_version_cstr = xnu + 4; 85 xnu_version = strtoull(xnu_version_cstr, NULL, 0); 86 if (xnu_version >= 2020 && xnu_version != ULLONG_MAX) { 87 if (::HasAVX()) { 88 g_has_avx = eAVXPresent; 89 } 90 } 91 } 92 } 93 DNBLogThreadedIf(LOG_THREAD, "CPUHasAVX(): g_has_avx = %i (err = %i, errno " 94 "= %i, xnu_version = %llu)", 95 g_has_avx, err, errno, xnu_version); 96 } 97 98 return (g_has_avx == eAVXPresent); 99 } 100 101 uint64_t DNBArchImplX86_64::GetPC(uint64_t failValue) { 102 // Get program counter 103 if (GetGPRState(false) == KERN_SUCCESS) 104 return m_state.context.gpr.__rip; 105 return failValue; 106 } 107 108 kern_return_t DNBArchImplX86_64::SetPC(uint64_t value) { 109 // Get program counter 110 kern_return_t err = GetGPRState(false); 111 if (err == KERN_SUCCESS) { 112 m_state.context.gpr.__rip = value; 113 err = SetGPRState(); 114 } 115 return err == KERN_SUCCESS; 116 } 117 118 uint64_t DNBArchImplX86_64::GetSP(uint64_t failValue) { 119 // Get stack pointer 120 if (GetGPRState(false) == KERN_SUCCESS) 121 return m_state.context.gpr.__rsp; 122 return failValue; 123 } 124 125 // Uncomment the value below to verify the values in the debugger. 126 //#define DEBUG_GPR_VALUES 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED 127 128 kern_return_t DNBArchImplX86_64::GetGPRState(bool force) { 129 if (force || m_state.GetError(e_regSetGPR, Read)) { 130 #if DEBUG_GPR_VALUES 131 m_state.context.gpr.__rax = ('a' << 8) + 'x'; 132 m_state.context.gpr.__rbx = ('b' << 8) + 'x'; 133 m_state.context.gpr.__rcx = ('c' << 8) + 'x'; 134 m_state.context.gpr.__rdx = ('d' << 8) + 'x'; 135 m_state.context.gpr.__rdi = ('d' << 8) + 'i'; 136 m_state.context.gpr.__rsi = ('s' << 8) + 'i'; 137 m_state.context.gpr.__rbp = ('b' << 8) + 'p'; 138 m_state.context.gpr.__rsp = ('s' << 8) + 'p'; 139 m_state.context.gpr.__r8 = ('r' << 8) + '8'; 140 m_state.context.gpr.__r9 = ('r' << 8) + '9'; 141 m_state.context.gpr.__r10 = ('r' << 8) + 'a'; 142 m_state.context.gpr.__r11 = ('r' << 8) + 'b'; 143 m_state.context.gpr.__r12 = ('r' << 8) + 'c'; 144 m_state.context.gpr.__r13 = ('r' << 8) + 'd'; 145 m_state.context.gpr.__r14 = ('r' << 8) + 'e'; 146 m_state.context.gpr.__r15 = ('r' << 8) + 'f'; 147 m_state.context.gpr.__rip = ('i' << 8) + 'p'; 148 m_state.context.gpr.__rflags = ('f' << 8) + 'l'; 149 m_state.context.gpr.__cs = ('c' << 8) + 's'; 150 m_state.context.gpr.__fs = ('f' << 8) + 's'; 151 m_state.context.gpr.__gs = ('g' << 8) + 's'; 152 m_state.SetError(e_regSetGPR, Read, 0); 153 #else 154 mach_msg_type_number_t count = e_regSetWordSizeGPR; 155 m_state.SetError( 156 e_regSetGPR, Read, 157 ::thread_get_state(m_thread->MachPortNumber(), __x86_64_THREAD_STATE, 158 (thread_state_t)&m_state.context.gpr, &count)); 159 DNBLogThreadedIf( 160 LOG_THREAD, 161 "::thread_get_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x" 162 "\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx" 163 "\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx" 164 "\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx" 165 "\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx" 166 "\n\trip = %16.16llx" 167 "\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx", 168 m_thread->MachPortNumber(), x86_THREAD_STATE64, 169 x86_THREAD_STATE64_COUNT, m_state.GetError(e_regSetGPR, Read), 170 m_state.context.gpr.__rax, m_state.context.gpr.__rbx, 171 m_state.context.gpr.__rcx, m_state.context.gpr.__rdx, 172 m_state.context.gpr.__rdi, m_state.context.gpr.__rsi, 173 m_state.context.gpr.__rbp, m_state.context.gpr.__rsp, 174 m_state.context.gpr.__r8, m_state.context.gpr.__r9, 175 m_state.context.gpr.__r10, m_state.context.gpr.__r11, 176 m_state.context.gpr.__r12, m_state.context.gpr.__r13, 177 m_state.context.gpr.__r14, m_state.context.gpr.__r15, 178 m_state.context.gpr.__rip, m_state.context.gpr.__rflags, 179 m_state.context.gpr.__cs, m_state.context.gpr.__fs, 180 m_state.context.gpr.__gs); 181 182 // DNBLogThreadedIf (LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) 183 // => 0x%8.8x" 184 // "\n\trax = %16.16llx" 185 // "\n\trbx = %16.16llx" 186 // "\n\trcx = %16.16llx" 187 // "\n\trdx = %16.16llx" 188 // "\n\trdi = %16.16llx" 189 // "\n\trsi = %16.16llx" 190 // "\n\trbp = %16.16llx" 191 // "\n\trsp = %16.16llx" 192 // "\n\t r8 = %16.16llx" 193 // "\n\t r9 = %16.16llx" 194 // "\n\tr10 = %16.16llx" 195 // "\n\tr11 = %16.16llx" 196 // "\n\tr12 = %16.16llx" 197 // "\n\tr13 = %16.16llx" 198 // "\n\tr14 = %16.16llx" 199 // "\n\tr15 = %16.16llx" 200 // "\n\trip = %16.16llx" 201 // "\n\tflg = %16.16llx" 202 // "\n\t cs = %16.16llx" 203 // "\n\t fs = %16.16llx" 204 // "\n\t gs = %16.16llx", 205 // m_thread->MachPortNumber(), 206 // x86_THREAD_STATE64, 207 // x86_THREAD_STATE64_COUNT, 208 // m_state.GetError(e_regSetGPR, Read), 209 // m_state.context.gpr.__rax, 210 // m_state.context.gpr.__rbx, 211 // m_state.context.gpr.__rcx, 212 // m_state.context.gpr.__rdx, 213 // m_state.context.gpr.__rdi, 214 // m_state.context.gpr.__rsi, 215 // m_state.context.gpr.__rbp, 216 // m_state.context.gpr.__rsp, 217 // m_state.context.gpr.__r8, 218 // m_state.context.gpr.__r9, 219 // m_state.context.gpr.__r10, 220 // m_state.context.gpr.__r11, 221 // m_state.context.gpr.__r12, 222 // m_state.context.gpr.__r13, 223 // m_state.context.gpr.__r14, 224 // m_state.context.gpr.__r15, 225 // m_state.context.gpr.__rip, 226 // m_state.context.gpr.__rflags, 227 // m_state.context.gpr.__cs, 228 // m_state.context.gpr.__fs, 229 // m_state.context.gpr.__gs); 230 #endif 231 } 232 return m_state.GetError(e_regSetGPR, Read); 233 } 234 235 // Uncomment the value below to verify the values in the debugger. 236 //#define DEBUG_FPU_REGS 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED 237 238 kern_return_t DNBArchImplX86_64::GetFPUState(bool force) { 239 if (force || m_state.GetError(e_regSetFPU, Read)) { 240 if (DEBUG_FPU_REGS) { 241 if (CPUHasAVX() || FORCE_AVX_REGS) { 242 m_state.context.fpu.avx.__fpu_reserved[0] = -1; 243 m_state.context.fpu.avx.__fpu_reserved[1] = -1; 244 *(uint16_t *)&(m_state.context.fpu.avx.__fpu_fcw) = 0x1234; 245 *(uint16_t *)&(m_state.context.fpu.avx.__fpu_fsw) = 0x5678; 246 m_state.context.fpu.avx.__fpu_ftw = 1; 247 m_state.context.fpu.avx.__fpu_rsrv1 = UINT8_MAX; 248 m_state.context.fpu.avx.__fpu_fop = 2; 249 m_state.context.fpu.avx.__fpu_ip = 3; 250 m_state.context.fpu.avx.__fpu_cs = 4; 251 m_state.context.fpu.avx.__fpu_rsrv2 = UINT8_MAX; 252 m_state.context.fpu.avx.__fpu_dp = 5; 253 m_state.context.fpu.avx.__fpu_ds = 6; 254 m_state.context.fpu.avx.__fpu_rsrv3 = UINT16_MAX; 255 m_state.context.fpu.avx.__fpu_mxcsr = 8; 256 m_state.context.fpu.avx.__fpu_mxcsrmask = 9; 257 int i; 258 for (i = 0; i < 16; ++i) { 259 if (i < 10) { 260 m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg[i] = 'a'; 261 m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg[i] = 'b'; 262 m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg[i] = 'c'; 263 m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg[i] = 'd'; 264 m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg[i] = 'e'; 265 m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg[i] = 'f'; 266 m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg[i] = 'g'; 267 m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg[i] = 'h'; 268 } else { 269 m_state.context.fpu.avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN; 270 m_state.context.fpu.avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN; 271 m_state.context.fpu.avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN; 272 m_state.context.fpu.avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN; 273 m_state.context.fpu.avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN; 274 m_state.context.fpu.avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN; 275 m_state.context.fpu.avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN; 276 m_state.context.fpu.avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN; 277 } 278 279 m_state.context.fpu.avx.__fpu_xmm0.__xmm_reg[i] = '0' + 2 * i; 280 m_state.context.fpu.avx.__fpu_xmm1.__xmm_reg[i] = '1' + 2 * i; 281 m_state.context.fpu.avx.__fpu_xmm2.__xmm_reg[i] = '2' + 2 * i; 282 m_state.context.fpu.avx.__fpu_xmm3.__xmm_reg[i] = '3' + 2 * i; 283 m_state.context.fpu.avx.__fpu_xmm4.__xmm_reg[i] = '4' + 2 * i; 284 m_state.context.fpu.avx.__fpu_xmm5.__xmm_reg[i] = '5' + 2 * i; 285 m_state.context.fpu.avx.__fpu_xmm6.__xmm_reg[i] = '6' + 2 * i; 286 m_state.context.fpu.avx.__fpu_xmm7.__xmm_reg[i] = '7' + 2 * i; 287 m_state.context.fpu.avx.__fpu_xmm8.__xmm_reg[i] = '8' + 2 * i; 288 m_state.context.fpu.avx.__fpu_xmm9.__xmm_reg[i] = '9' + 2 * i; 289 m_state.context.fpu.avx.__fpu_xmm10.__xmm_reg[i] = 'A' + 2 * i; 290 m_state.context.fpu.avx.__fpu_xmm11.__xmm_reg[i] = 'B' + 2 * i; 291 m_state.context.fpu.avx.__fpu_xmm12.__xmm_reg[i] = 'C' + 2 * i; 292 m_state.context.fpu.avx.__fpu_xmm13.__xmm_reg[i] = 'D' + 2 * i; 293 m_state.context.fpu.avx.__fpu_xmm14.__xmm_reg[i] = 'E' + 2 * i; 294 m_state.context.fpu.avx.__fpu_xmm15.__xmm_reg[i] = 'F' + 2 * i; 295 296 m_state.context.fpu.avx.__fpu_ymmh0.__xmm_reg[i] = '0' + i; 297 m_state.context.fpu.avx.__fpu_ymmh1.__xmm_reg[i] = '1' + i; 298 m_state.context.fpu.avx.__fpu_ymmh2.__xmm_reg[i] = '2' + i; 299 m_state.context.fpu.avx.__fpu_ymmh3.__xmm_reg[i] = '3' + i; 300 m_state.context.fpu.avx.__fpu_ymmh4.__xmm_reg[i] = '4' + i; 301 m_state.context.fpu.avx.__fpu_ymmh5.__xmm_reg[i] = '5' + i; 302 m_state.context.fpu.avx.__fpu_ymmh6.__xmm_reg[i] = '6' + i; 303 m_state.context.fpu.avx.__fpu_ymmh7.__xmm_reg[i] = '7' + i; 304 m_state.context.fpu.avx.__fpu_ymmh8.__xmm_reg[i] = '8' + i; 305 m_state.context.fpu.avx.__fpu_ymmh9.__xmm_reg[i] = '9' + i; 306 m_state.context.fpu.avx.__fpu_ymmh10.__xmm_reg[i] = 'A' + i; 307 m_state.context.fpu.avx.__fpu_ymmh11.__xmm_reg[i] = 'B' + i; 308 m_state.context.fpu.avx.__fpu_ymmh12.__xmm_reg[i] = 'C' + i; 309 m_state.context.fpu.avx.__fpu_ymmh13.__xmm_reg[i] = 'D' + i; 310 m_state.context.fpu.avx.__fpu_ymmh14.__xmm_reg[i] = 'E' + i; 311 m_state.context.fpu.avx.__fpu_ymmh15.__xmm_reg[i] = 'F' + i; 312 } 313 for (i = 0; i < sizeof(m_state.context.fpu.avx.__fpu_rsrv4); ++i) 314 m_state.context.fpu.avx.__fpu_rsrv4[i] = INT8_MIN; 315 m_state.context.fpu.avx.__fpu_reserved1 = -1; 316 for (i = 0; i < sizeof(m_state.context.fpu.avx.__avx_reserved1); ++i) 317 m_state.context.fpu.avx.__avx_reserved1[i] = INT8_MIN; 318 m_state.SetError(e_regSetFPU, Read, 0); 319 } else { 320 m_state.context.fpu.no_avx.__fpu_reserved[0] = -1; 321 m_state.context.fpu.no_avx.__fpu_reserved[1] = -1; 322 *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fcw) = 0x1234; 323 *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fsw) = 0x5678; 324 m_state.context.fpu.no_avx.__fpu_ftw = 1; 325 m_state.context.fpu.no_avx.__fpu_rsrv1 = UINT8_MAX; 326 m_state.context.fpu.no_avx.__fpu_fop = 2; 327 m_state.context.fpu.no_avx.__fpu_ip = 3; 328 m_state.context.fpu.no_avx.__fpu_cs = 4; 329 m_state.context.fpu.no_avx.__fpu_rsrv2 = 5; 330 m_state.context.fpu.no_avx.__fpu_dp = 6; 331 m_state.context.fpu.no_avx.__fpu_ds = 7; 332 m_state.context.fpu.no_avx.__fpu_rsrv3 = UINT16_MAX; 333 m_state.context.fpu.no_avx.__fpu_mxcsr = 8; 334 m_state.context.fpu.no_avx.__fpu_mxcsrmask = 9; 335 int i; 336 for (i = 0; i < 16; ++i) { 337 if (i < 10) { 338 m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = 'a'; 339 m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = 'b'; 340 m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = 'c'; 341 m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = 'd'; 342 m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = 'e'; 343 m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = 'f'; 344 m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = 'g'; 345 m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = 'h'; 346 } else { 347 m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN; 348 m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN; 349 m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN; 350 m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN; 351 m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN; 352 m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN; 353 m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN; 354 m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN; 355 } 356 357 m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg[i] = '0'; 358 m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg[i] = '1'; 359 m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg[i] = '2'; 360 m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg[i] = '3'; 361 m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg[i] = '4'; 362 m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg[i] = '5'; 363 m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg[i] = '6'; 364 m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg[i] = '7'; 365 m_state.context.fpu.no_avx.__fpu_xmm8.__xmm_reg[i] = '8'; 366 m_state.context.fpu.no_avx.__fpu_xmm9.__xmm_reg[i] = '9'; 367 m_state.context.fpu.no_avx.__fpu_xmm10.__xmm_reg[i] = 'A'; 368 m_state.context.fpu.no_avx.__fpu_xmm11.__xmm_reg[i] = 'B'; 369 m_state.context.fpu.no_avx.__fpu_xmm12.__xmm_reg[i] = 'C'; 370 m_state.context.fpu.no_avx.__fpu_xmm13.__xmm_reg[i] = 'D'; 371 m_state.context.fpu.no_avx.__fpu_xmm14.__xmm_reg[i] = 'E'; 372 m_state.context.fpu.no_avx.__fpu_xmm15.__xmm_reg[i] = 'F'; 373 } 374 for (i = 0; i < sizeof(m_state.context.fpu.no_avx.__fpu_rsrv4); ++i) 375 m_state.context.fpu.no_avx.__fpu_rsrv4[i] = INT8_MIN; 376 m_state.context.fpu.no_avx.__fpu_reserved1 = -1; 377 m_state.SetError(e_regSetFPU, Read, 0); 378 } 379 } else { 380 if (CPUHasAVX() || FORCE_AVX_REGS) { 381 mach_msg_type_number_t count = e_regSetWordSizeAVX; 382 m_state.SetError(e_regSetFPU, Read, 383 ::thread_get_state( 384 m_thread->MachPortNumber(), __x86_64_AVX_STATE, 385 (thread_state_t)&m_state.context.fpu.avx, &count)); 386 DNBLogThreadedIf(LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &avx, " 387 "%u (%u passed in) carp) => 0x%8.8x", 388 m_thread->MachPortNumber(), __x86_64_AVX_STATE, 389 (uint32_t)count, e_regSetWordSizeAVX, 390 m_state.GetError(e_regSetFPU, Read)); 391 } else { 392 mach_msg_type_number_t count = e_regSetWordSizeFPU; 393 m_state.SetError( 394 e_regSetFPU, Read, 395 ::thread_get_state(m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, 396 (thread_state_t)&m_state.context.fpu.no_avx, 397 &count)); 398 DNBLogThreadedIf(LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &fpu, " 399 "%u (%u passed in) => 0x%8.8x", 400 m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, 401 (uint32_t)count, e_regSetWordSizeFPU, 402 m_state.GetError(e_regSetFPU, Read)); 403 } 404 } 405 } 406 return m_state.GetError(e_regSetFPU, Read); 407 } 408 409 kern_return_t DNBArchImplX86_64::GetEXCState(bool force) { 410 if (force || m_state.GetError(e_regSetEXC, Read)) { 411 mach_msg_type_number_t count = e_regSetWordSizeEXC; 412 m_state.SetError( 413 e_regSetEXC, Read, 414 ::thread_get_state(m_thread->MachPortNumber(), __x86_64_EXCEPTION_STATE, 415 (thread_state_t)&m_state.context.exc, &count)); 416 } 417 return m_state.GetError(e_regSetEXC, Read); 418 } 419 420 kern_return_t DNBArchImplX86_64::SetGPRState() { 421 kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber()); 422 DNBLogThreadedIf( 423 LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u " 424 "(SetGPRState() for stop_count = %u)", 425 m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount()); 426 427 m_state.SetError(e_regSetGPR, Write, 428 ::thread_set_state(m_thread->MachPortNumber(), 429 __x86_64_THREAD_STATE, 430 (thread_state_t)&m_state.context.gpr, 431 e_regSetWordSizeGPR)); 432 DNBLogThreadedIf( 433 LOG_THREAD, 434 "::thread_set_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x" 435 "\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx" 436 "\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx" 437 "\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx" 438 "\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx" 439 "\n\trip = %16.16llx" 440 "\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx", 441 m_thread->MachPortNumber(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR, 442 m_state.GetError(e_regSetGPR, Write), m_state.context.gpr.__rax, 443 m_state.context.gpr.__rbx, m_state.context.gpr.__rcx, 444 m_state.context.gpr.__rdx, m_state.context.gpr.__rdi, 445 m_state.context.gpr.__rsi, m_state.context.gpr.__rbp, 446 m_state.context.gpr.__rsp, m_state.context.gpr.__r8, 447 m_state.context.gpr.__r9, m_state.context.gpr.__r10, 448 m_state.context.gpr.__r11, m_state.context.gpr.__r12, 449 m_state.context.gpr.__r13, m_state.context.gpr.__r14, 450 m_state.context.gpr.__r15, m_state.context.gpr.__rip, 451 m_state.context.gpr.__rflags, m_state.context.gpr.__cs, 452 m_state.context.gpr.__fs, m_state.context.gpr.__gs); 453 return m_state.GetError(e_regSetGPR, Write); 454 } 455 456 kern_return_t DNBArchImplX86_64::SetFPUState() { 457 if (DEBUG_FPU_REGS) { 458 m_state.SetError(e_regSetFPU, Write, 0); 459 return m_state.GetError(e_regSetFPU, Write); 460 } else { 461 if (CPUHasAVX() || FORCE_AVX_REGS) { 462 m_state.SetError( 463 e_regSetFPU, Write, 464 ::thread_set_state(m_thread->MachPortNumber(), __x86_64_AVX_STATE, 465 (thread_state_t)&m_state.context.fpu.avx, 466 e_regSetWordSizeAVX)); 467 return m_state.GetError(e_regSetFPU, Write); 468 } else { 469 m_state.SetError( 470 e_regSetFPU, Write, 471 ::thread_set_state(m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, 472 (thread_state_t)&m_state.context.fpu.no_avx, 473 e_regSetWordSizeFPU)); 474 return m_state.GetError(e_regSetFPU, Write); 475 } 476 } 477 } 478 479 kern_return_t DNBArchImplX86_64::SetEXCState() { 480 m_state.SetError(e_regSetEXC, Write, 481 ::thread_set_state(m_thread->MachPortNumber(), 482 __x86_64_EXCEPTION_STATE, 483 (thread_state_t)&m_state.context.exc, 484 e_regSetWordSizeEXC)); 485 return m_state.GetError(e_regSetEXC, Write); 486 } 487 488 kern_return_t DNBArchImplX86_64::GetDBGState(bool force) { 489 if (force || m_state.GetError(e_regSetDBG, Read)) { 490 mach_msg_type_number_t count = e_regSetWordSizeDBG; 491 m_state.SetError( 492 e_regSetDBG, Read, 493 ::thread_get_state(m_thread->MachPortNumber(), __x86_64_DEBUG_STATE, 494 (thread_state_t)&m_state.context.dbg, &count)); 495 } 496 return m_state.GetError(e_regSetDBG, Read); 497 } 498 499 kern_return_t DNBArchImplX86_64::SetDBGState(bool also_set_on_task) { 500 m_state.SetError(e_regSetDBG, Write, 501 ::thread_set_state(m_thread->MachPortNumber(), 502 __x86_64_DEBUG_STATE, 503 (thread_state_t)&m_state.context.dbg, 504 e_regSetWordSizeDBG)); 505 if (also_set_on_task) { 506 kern_return_t kret = ::task_set_state( 507 m_thread->Process()->Task().TaskPort(), __x86_64_DEBUG_STATE, 508 (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG); 509 if (kret != KERN_SUCCESS) 510 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::SetDBGState failed " 511 "to set debug control register state: " 512 "0x%8.8x.", 513 kret); 514 } 515 return m_state.GetError(e_regSetDBG, Write); 516 } 517 518 void DNBArchImplX86_64::ThreadWillResume() { 519 // Do we need to step this thread? If so, let the mach thread tell us so. 520 if (m_thread->IsStepping()) { 521 // This is the primary thread, let the arch do anything it needs 522 EnableHardwareSingleStep(true); 523 } 524 525 // Reset the debug status register, if necessary, before we resume. 526 kern_return_t kret = GetDBGState(false); 527 DNBLogThreadedIf( 528 LOG_WATCHPOINTS, 529 "DNBArchImplX86_64::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); 530 if (kret != KERN_SUCCESS) 531 return; 532 533 DBG &debug_state = m_state.context.dbg; 534 bool need_reset = false; 535 uint32_t i, num = NumSupportedHardwareWatchpoints(); 536 for (i = 0; i < num; ++i) 537 if (IsWatchpointHit(debug_state, i)) 538 need_reset = true; 539 540 if (need_reset) { 541 ClearWatchpointHits(debug_state); 542 kret = SetDBGState(false); 543 DNBLogThreadedIf( 544 LOG_WATCHPOINTS, 545 "DNBArchImplX86_64::ThreadWillResume() SetDBGState() => 0x%8.8x.", 546 kret); 547 } 548 } 549 550 bool DNBArchImplX86_64::ThreadDidStop() { 551 bool success = true; 552 553 m_state.InvalidateAllRegisterStates(); 554 555 // Are we stepping a single instruction? 556 if (GetGPRState(true) == KERN_SUCCESS) { 557 // We are single stepping, was this the primary thread? 558 if (m_thread->IsStepping()) { 559 // This was the primary thread, we need to clear the trace 560 // bit if so. 561 success = EnableHardwareSingleStep(false) == KERN_SUCCESS; 562 } else { 563 // The MachThread will automatically restore the suspend count 564 // in ThreadDidStop(), so we don't need to do anything here if 565 // we weren't the primary thread the last time 566 } 567 } 568 return success; 569 } 570 571 bool DNBArchImplX86_64::NotifyException(MachException::Data &exc) { 572 switch (exc.exc_type) { 573 case EXC_BAD_ACCESS: 574 break; 575 case EXC_BAD_INSTRUCTION: 576 break; 577 case EXC_ARITHMETIC: 578 break; 579 case EXC_EMULATION: 580 break; 581 case EXC_SOFTWARE: 582 break; 583 case EXC_BREAKPOINT: 584 if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) { 585 // exc_code = EXC_I386_BPT 586 // 587 nub_addr_t pc = GetPC(INVALID_NUB_ADDRESS); 588 if (pc != INVALID_NUB_ADDRESS && pc > 0) { 589 pc -= 1; 590 // Check for a breakpoint at one byte prior to the current PC value 591 // since the PC will be just past the trap. 592 593 DNBBreakpoint *bp = 594 m_thread->Process()->Breakpoints().FindByAddress(pc); 595 if (bp) { 596 // Backup the PC for i386 since the trap was taken and the PC 597 // is at the address following the single byte trap instruction. 598 if (m_state.context.gpr.__rip > 0) { 599 m_state.context.gpr.__rip = pc; 600 // Write the new PC back out 601 SetGPRState(); 602 } 603 } 604 return true; 605 } 606 } else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) { 607 // exc_code = EXC_I386_SGL 608 // 609 // Check whether this corresponds to a watchpoint hit event. 610 // If yes, set the exc_sub_code to the data break address. 611 nub_addr_t addr = 0; 612 uint32_t hw_index = GetHardwareWatchpointHit(addr); 613 if (hw_index != INVALID_NUB_HW_INDEX) { 614 exc.exc_data[1] = addr; 615 // Piggyback the hw_index in the exc.data. 616 exc.exc_data.push_back(hw_index); 617 } 618 619 return true; 620 } 621 break; 622 case EXC_SYSCALL: 623 break; 624 case EXC_MACH_SYSCALL: 625 break; 626 case EXC_RPC_ALERT: 627 break; 628 } 629 return false; 630 } 631 632 uint32_t DNBArchImplX86_64::NumSupportedHardwareWatchpoints() { 633 // Available debug address registers: dr0, dr1, dr2, dr3. 634 return 4; 635 } 636 637 static uint32_t size_and_rw_bits(nub_size_t size, bool read, bool write) { 638 uint32_t rw; 639 if (read) { 640 rw = 0x3; // READ or READ/WRITE 641 } else if (write) { 642 rw = 0x1; // WRITE 643 } else { 644 assert(0 && "read and write cannot both be false"); 645 } 646 647 switch (size) { 648 case 1: 649 return rw; 650 case 2: 651 return (0x1 << 2) | rw; 652 case 4: 653 return (0x3 << 2) | rw; 654 case 8: 655 return (0x2 << 2) | rw; 656 } 657 assert(0 && "invalid size, must be one of 1, 2, 4, or 8"); 658 return 0; 659 } 660 void DNBArchImplX86_64::SetWatchpoint(DBG &debug_state, uint32_t hw_index, 661 nub_addr_t addr, nub_size_t size, 662 bool read, bool write) { 663 // Set both dr7 (debug control register) and dri (debug address register). 664 665 // dr7{7-0} encodes the local/gloabl enable bits: 666 // global enable --. .-- local enable 667 // | | 668 // v v 669 // dr0 -> bits{1-0} 670 // dr1 -> bits{3-2} 671 // dr2 -> bits{5-4} 672 // dr3 -> bits{7-6} 673 // 674 // dr7{31-16} encodes the rw/len bits: 675 // b_x+3, b_x+2, b_x+1, b_x 676 // where bits{x+1, x} => rw 677 // 0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io 678 // read-or-write (unused) 679 // and bits{x+3, x+2} => len 680 // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte 681 // 682 // dr0 -> bits{19-16} 683 // dr1 -> bits{23-20} 684 // dr2 -> bits{27-24} 685 // dr3 -> bits{31-28} 686 debug_state.__dr7 |= 687 (1 << (2 * hw_index) | 688 size_and_rw_bits(size, read, write) << (16 + 4 * hw_index)); 689 switch (hw_index) { 690 case 0: 691 debug_state.__dr0 = addr; 692 break; 693 case 1: 694 debug_state.__dr1 = addr; 695 break; 696 case 2: 697 debug_state.__dr2 = addr; 698 break; 699 case 3: 700 debug_state.__dr3 = addr; 701 break; 702 default: 703 assert(0 && 704 "invalid hardware register index, must be one of 0, 1, 2, or 3"); 705 } 706 return; 707 } 708 709 void DNBArchImplX86_64::ClearWatchpoint(DBG &debug_state, uint32_t hw_index) { 710 debug_state.__dr7 &= ~(3 << (2 * hw_index)); 711 switch (hw_index) { 712 case 0: 713 debug_state.__dr0 = 0; 714 break; 715 case 1: 716 debug_state.__dr1 = 0; 717 break; 718 case 2: 719 debug_state.__dr2 = 0; 720 break; 721 case 3: 722 debug_state.__dr3 = 0; 723 break; 724 default: 725 assert(0 && 726 "invalid hardware register index, must be one of 0, 1, 2, or 3"); 727 } 728 return; 729 } 730 731 bool DNBArchImplX86_64::IsWatchpointVacant(const DBG &debug_state, 732 uint32_t hw_index) { 733 // Check dr7 (debug control register) for local/global enable bits: 734 // global enable --. .-- local enable 735 // | | 736 // v v 737 // dr0 -> bits{1-0} 738 // dr1 -> bits{3-2} 739 // dr2 -> bits{5-4} 740 // dr3 -> bits{7-6} 741 return (debug_state.__dr7 & (3 << (2 * hw_index))) == 0; 742 } 743 744 // Resets local copy of debug status register to wait for the next debug 745 // exception. 746 void DNBArchImplX86_64::ClearWatchpointHits(DBG &debug_state) { 747 // See also IsWatchpointHit(). 748 debug_state.__dr6 = 0; 749 return; 750 } 751 752 bool DNBArchImplX86_64::IsWatchpointHit(const DBG &debug_state, 753 uint32_t hw_index) { 754 // Check dr6 (debug status register) whether a watchpoint hits: 755 // is watchpoint hit? 756 // | 757 // v 758 // dr0 -> bits{0} 759 // dr1 -> bits{1} 760 // dr2 -> bits{2} 761 // dr3 -> bits{3} 762 return (debug_state.__dr6 & (1 << hw_index)); 763 } 764 765 nub_addr_t DNBArchImplX86_64::GetWatchAddress(const DBG &debug_state, 766 uint32_t hw_index) { 767 switch (hw_index) { 768 case 0: 769 return debug_state.__dr0; 770 case 1: 771 return debug_state.__dr1; 772 case 2: 773 return debug_state.__dr2; 774 case 3: 775 return debug_state.__dr3; 776 } 777 assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); 778 return 0; 779 } 780 781 bool DNBArchImplX86_64::StartTransForHWP() { 782 if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back) 783 DNBLogError("%s inconsistent state detected, expected %d or %d, got: %d", 784 __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state); 785 m_2pc_dbg_checkpoint = m_state.context.dbg; 786 m_2pc_trans_state = Trans_Pending; 787 return true; 788 } 789 bool DNBArchImplX86_64::RollbackTransForHWP() { 790 m_state.context.dbg = m_2pc_dbg_checkpoint; 791 if (m_2pc_trans_state != Trans_Pending) 792 DNBLogError("%s inconsistent state detected, expected %d, got: %d", 793 __FUNCTION__, Trans_Pending, m_2pc_trans_state); 794 m_2pc_trans_state = Trans_Rolled_Back; 795 kern_return_t kret = SetDBGState(false); 796 DNBLogThreadedIf( 797 LOG_WATCHPOINTS, 798 "DNBArchImplX86_64::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", 799 kret); 800 801 if (kret == KERN_SUCCESS) 802 return true; 803 else 804 return false; 805 } 806 bool DNBArchImplX86_64::FinishTransForHWP() { 807 m_2pc_trans_state = Trans_Done; 808 return true; 809 } 810 DNBArchImplX86_64::DBG DNBArchImplX86_64::GetDBGCheckpoint() { 811 return m_2pc_dbg_checkpoint; 812 } 813 814 uint32_t DNBArchImplX86_64::EnableHardwareWatchpoint(nub_addr_t addr, 815 nub_size_t size, bool read, 816 bool write, 817 bool also_set_on_task) { 818 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::" 819 "EnableHardwareWatchpoint(addr = 0x%llx, " 820 "size = %llu, read = %u, write = %u)", 821 (uint64_t)addr, (uint64_t)size, read, write); 822 823 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 824 825 // Can only watch 1, 2, 4, or 8 bytes. 826 if (!(size == 1 || size == 2 || size == 4 || size == 8)) 827 return INVALID_NUB_HW_INDEX; 828 829 // We must watch for either read or write 830 if (read == false && write == false) 831 return INVALID_NUB_HW_INDEX; 832 833 // Read the debug state 834 kern_return_t kret = GetDBGState(false); 835 836 if (kret == KERN_SUCCESS) { 837 // Check to make sure we have the needed hardware support 838 uint32_t i = 0; 839 840 DBG &debug_state = m_state.context.dbg; 841 for (i = 0; i < num_hw_watchpoints; ++i) { 842 if (IsWatchpointVacant(debug_state, i)) 843 break; 844 } 845 846 // See if we found an available hw breakpoint slot above 847 if (i < num_hw_watchpoints) { 848 StartTransForHWP(); 849 850 // Modify our local copy of the debug state, first. 851 SetWatchpoint(debug_state, i, addr, size, read, write); 852 // Now set the watch point in the inferior. 853 kret = SetDBGState(also_set_on_task); 854 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::" 855 "EnableHardwareWatchpoint() " 856 "SetDBGState() => 0x%8.8x.", 857 kret); 858 859 if (kret == KERN_SUCCESS) 860 return i; 861 else // Revert to the previous debug state voluntarily. The transaction 862 // coordinator knows that we have failed. 863 m_state.context.dbg = GetDBGCheckpoint(); 864 } else { 865 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::" 866 "EnableHardwareWatchpoint(): All " 867 "hardware resources (%u) are in use.", 868 num_hw_watchpoints); 869 } 870 } 871 return INVALID_NUB_HW_INDEX; 872 } 873 874 bool DNBArchImplX86_64::DisableHardwareWatchpoint(uint32_t hw_index, 875 bool also_set_on_task) { 876 kern_return_t kret = GetDBGState(false); 877 878 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 879 if (kret == KERN_SUCCESS) { 880 DBG &debug_state = m_state.context.dbg; 881 if (hw_index < num_hw_points && 882 !IsWatchpointVacant(debug_state, hw_index)) { 883 StartTransForHWP(); 884 885 // Modify our local copy of the debug state, first. 886 ClearWatchpoint(debug_state, hw_index); 887 // Now disable the watch point in the inferior. 888 kret = SetDBGState(also_set_on_task); 889 DNBLogThreadedIf(LOG_WATCHPOINTS, 890 "DNBArchImplX86_64::DisableHardwareWatchpoint( %u )", 891 hw_index); 892 893 if (kret == KERN_SUCCESS) 894 return true; 895 else // Revert to the previous debug state voluntarily. The transaction 896 // coordinator knows that we have failed. 897 m_state.context.dbg = GetDBGCheckpoint(); 898 } 899 } 900 return false; 901 } 902 903 // Iterate through the debug status register; return the index of the first hit. 904 uint32_t DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr) { 905 // Read the debug state 906 kern_return_t kret = GetDBGState(true); 907 DNBLogThreadedIf( 908 LOG_WATCHPOINTS, 909 "DNBArchImplX86_64::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", 910 kret); 911 if (kret == KERN_SUCCESS) { 912 DBG &debug_state = m_state.context.dbg; 913 uint32_t i, num = NumSupportedHardwareWatchpoints(); 914 for (i = 0; i < num; ++i) { 915 if (IsWatchpointHit(debug_state, i)) { 916 addr = GetWatchAddress(debug_state, i); 917 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::" 918 "GetHardwareWatchpointHit() found => " 919 "%u (addr = 0x%llx).", 920 i, (uint64_t)addr); 921 return i; 922 } 923 } 924 } 925 return INVALID_NUB_HW_INDEX; 926 } 927 928 // Set the single step bit in the processor status register. 929 kern_return_t DNBArchImplX86_64::EnableHardwareSingleStep(bool enable) { 930 if (GetGPRState(false) == KERN_SUCCESS) { 931 const uint32_t trace_bit = 0x100u; 932 if (enable) 933 m_state.context.gpr.__rflags |= trace_bit; 934 else 935 m_state.context.gpr.__rflags &= ~trace_bit; 936 return SetGPRState(); 937 } 938 return m_state.GetError(e_regSetGPR, Read); 939 } 940 941 //---------------------------------------------------------------------- 942 // Register information definitions 943 //---------------------------------------------------------------------- 944 945 enum { 946 gpr_rax = 0, 947 gpr_rbx, 948 gpr_rcx, 949 gpr_rdx, 950 gpr_rdi, 951 gpr_rsi, 952 gpr_rbp, 953 gpr_rsp, 954 gpr_r8, 955 gpr_r9, 956 gpr_r10, 957 gpr_r11, 958 gpr_r12, 959 gpr_r13, 960 gpr_r14, 961 gpr_r15, 962 gpr_rip, 963 gpr_rflags, 964 gpr_cs, 965 gpr_fs, 966 gpr_gs, 967 gpr_eax, 968 gpr_ebx, 969 gpr_ecx, 970 gpr_edx, 971 gpr_edi, 972 gpr_esi, 973 gpr_ebp, 974 gpr_esp, 975 gpr_r8d, // Low 32 bits or r8 976 gpr_r9d, // Low 32 bits or r9 977 gpr_r10d, // Low 32 bits or r10 978 gpr_r11d, // Low 32 bits or r11 979 gpr_r12d, // Low 32 bits or r12 980 gpr_r13d, // Low 32 bits or r13 981 gpr_r14d, // Low 32 bits or r14 982 gpr_r15d, // Low 32 bits or r15 983 gpr_ax, 984 gpr_bx, 985 gpr_cx, 986 gpr_dx, 987 gpr_di, 988 gpr_si, 989 gpr_bp, 990 gpr_sp, 991 gpr_r8w, // Low 16 bits or r8 992 gpr_r9w, // Low 16 bits or r9 993 gpr_r10w, // Low 16 bits or r10 994 gpr_r11w, // Low 16 bits or r11 995 gpr_r12w, // Low 16 bits or r12 996 gpr_r13w, // Low 16 bits or r13 997 gpr_r14w, // Low 16 bits or r14 998 gpr_r15w, // Low 16 bits or r15 999 gpr_ah, 1000 gpr_bh, 1001 gpr_ch, 1002 gpr_dh, 1003 gpr_al, 1004 gpr_bl, 1005 gpr_cl, 1006 gpr_dl, 1007 gpr_dil, 1008 gpr_sil, 1009 gpr_bpl, 1010 gpr_spl, 1011 gpr_r8l, // Low 8 bits or r8 1012 gpr_r9l, // Low 8 bits or r9 1013 gpr_r10l, // Low 8 bits or r10 1014 gpr_r11l, // Low 8 bits or r11 1015 gpr_r12l, // Low 8 bits or r12 1016 gpr_r13l, // Low 8 bits or r13 1017 gpr_r14l, // Low 8 bits or r14 1018 gpr_r15l, // Low 8 bits or r15 1019 k_num_gpr_regs 1020 }; 1021 1022 enum { 1023 fpu_fcw, 1024 fpu_fsw, 1025 fpu_ftw, 1026 fpu_fop, 1027 fpu_ip, 1028 fpu_cs, 1029 fpu_dp, 1030 fpu_ds, 1031 fpu_mxcsr, 1032 fpu_mxcsrmask, 1033 fpu_stmm0, 1034 fpu_stmm1, 1035 fpu_stmm2, 1036 fpu_stmm3, 1037 fpu_stmm4, 1038 fpu_stmm5, 1039 fpu_stmm6, 1040 fpu_stmm7, 1041 fpu_xmm0, 1042 fpu_xmm1, 1043 fpu_xmm2, 1044 fpu_xmm3, 1045 fpu_xmm4, 1046 fpu_xmm5, 1047 fpu_xmm6, 1048 fpu_xmm7, 1049 fpu_xmm8, 1050 fpu_xmm9, 1051 fpu_xmm10, 1052 fpu_xmm11, 1053 fpu_xmm12, 1054 fpu_xmm13, 1055 fpu_xmm14, 1056 fpu_xmm15, 1057 fpu_ymm0, 1058 fpu_ymm1, 1059 fpu_ymm2, 1060 fpu_ymm3, 1061 fpu_ymm4, 1062 fpu_ymm5, 1063 fpu_ymm6, 1064 fpu_ymm7, 1065 fpu_ymm8, 1066 fpu_ymm9, 1067 fpu_ymm10, 1068 fpu_ymm11, 1069 fpu_ymm12, 1070 fpu_ymm13, 1071 fpu_ymm14, 1072 fpu_ymm15, 1073 k_num_fpu_regs, 1074 1075 // Aliases 1076 fpu_fctrl = fpu_fcw, 1077 fpu_fstat = fpu_fsw, 1078 fpu_ftag = fpu_ftw, 1079 fpu_fiseg = fpu_cs, 1080 fpu_fioff = fpu_ip, 1081 fpu_foseg = fpu_ds, 1082 fpu_fooff = fpu_dp 1083 }; 1084 1085 enum { 1086 exc_trapno, 1087 exc_err, 1088 exc_faultvaddr, 1089 k_num_exc_regs, 1090 }; 1091 1092 enum ehframe_dwarf_regnums { 1093 ehframe_dwarf_rax = 0, 1094 ehframe_dwarf_rdx = 1, 1095 ehframe_dwarf_rcx = 2, 1096 ehframe_dwarf_rbx = 3, 1097 ehframe_dwarf_rsi = 4, 1098 ehframe_dwarf_rdi = 5, 1099 ehframe_dwarf_rbp = 6, 1100 ehframe_dwarf_rsp = 7, 1101 ehframe_dwarf_r8, 1102 ehframe_dwarf_r9, 1103 ehframe_dwarf_r10, 1104 ehframe_dwarf_r11, 1105 ehframe_dwarf_r12, 1106 ehframe_dwarf_r13, 1107 ehframe_dwarf_r14, 1108 ehframe_dwarf_r15, 1109 ehframe_dwarf_rip, 1110 ehframe_dwarf_xmm0, 1111 ehframe_dwarf_xmm1, 1112 ehframe_dwarf_xmm2, 1113 ehframe_dwarf_xmm3, 1114 ehframe_dwarf_xmm4, 1115 ehframe_dwarf_xmm5, 1116 ehframe_dwarf_xmm6, 1117 ehframe_dwarf_xmm7, 1118 ehframe_dwarf_xmm8, 1119 ehframe_dwarf_xmm9, 1120 ehframe_dwarf_xmm10, 1121 ehframe_dwarf_xmm11, 1122 ehframe_dwarf_xmm12, 1123 ehframe_dwarf_xmm13, 1124 ehframe_dwarf_xmm14, 1125 ehframe_dwarf_xmm15, 1126 ehframe_dwarf_stmm0, 1127 ehframe_dwarf_stmm1, 1128 ehframe_dwarf_stmm2, 1129 ehframe_dwarf_stmm3, 1130 ehframe_dwarf_stmm4, 1131 ehframe_dwarf_stmm5, 1132 ehframe_dwarf_stmm6, 1133 ehframe_dwarf_stmm7, 1134 ehframe_dwarf_ymm0 = ehframe_dwarf_xmm0, 1135 ehframe_dwarf_ymm1 = ehframe_dwarf_xmm1, 1136 ehframe_dwarf_ymm2 = ehframe_dwarf_xmm2, 1137 ehframe_dwarf_ymm3 = ehframe_dwarf_xmm3, 1138 ehframe_dwarf_ymm4 = ehframe_dwarf_xmm4, 1139 ehframe_dwarf_ymm5 = ehframe_dwarf_xmm5, 1140 ehframe_dwarf_ymm6 = ehframe_dwarf_xmm6, 1141 ehframe_dwarf_ymm7 = ehframe_dwarf_xmm7, 1142 ehframe_dwarf_ymm8 = ehframe_dwarf_xmm8, 1143 ehframe_dwarf_ymm9 = ehframe_dwarf_xmm9, 1144 ehframe_dwarf_ymm10 = ehframe_dwarf_xmm10, 1145 ehframe_dwarf_ymm11 = ehframe_dwarf_xmm11, 1146 ehframe_dwarf_ymm12 = ehframe_dwarf_xmm12, 1147 ehframe_dwarf_ymm13 = ehframe_dwarf_xmm13, 1148 ehframe_dwarf_ymm14 = ehframe_dwarf_xmm14, 1149 ehframe_dwarf_ymm15 = ehframe_dwarf_xmm15 1150 }; 1151 1152 enum debugserver_regnums { 1153 debugserver_rax = 0, 1154 debugserver_rbx = 1, 1155 debugserver_rcx = 2, 1156 debugserver_rdx = 3, 1157 debugserver_rsi = 4, 1158 debugserver_rdi = 5, 1159 debugserver_rbp = 6, 1160 debugserver_rsp = 7, 1161 debugserver_r8 = 8, 1162 debugserver_r9 = 9, 1163 debugserver_r10 = 10, 1164 debugserver_r11 = 11, 1165 debugserver_r12 = 12, 1166 debugserver_r13 = 13, 1167 debugserver_r14 = 14, 1168 debugserver_r15 = 15, 1169 debugserver_rip = 16, 1170 debugserver_rflags = 17, 1171 debugserver_cs = 18, 1172 debugserver_ss = 19, 1173 debugserver_ds = 20, 1174 debugserver_es = 21, 1175 debugserver_fs = 22, 1176 debugserver_gs = 23, 1177 debugserver_stmm0 = 24, 1178 debugserver_stmm1 = 25, 1179 debugserver_stmm2 = 26, 1180 debugserver_stmm3 = 27, 1181 debugserver_stmm4 = 28, 1182 debugserver_stmm5 = 29, 1183 debugserver_stmm6 = 30, 1184 debugserver_stmm7 = 31, 1185 debugserver_fctrl = 32, 1186 debugserver_fcw = debugserver_fctrl, 1187 debugserver_fstat = 33, 1188 debugserver_fsw = debugserver_fstat, 1189 debugserver_ftag = 34, 1190 debugserver_ftw = debugserver_ftag, 1191 debugserver_fiseg = 35, 1192 debugserver_fpu_cs = debugserver_fiseg, 1193 debugserver_fioff = 36, 1194 debugserver_ip = debugserver_fioff, 1195 debugserver_foseg = 37, 1196 debugserver_fpu_ds = debugserver_foseg, 1197 debugserver_fooff = 38, 1198 debugserver_dp = debugserver_fooff, 1199 debugserver_fop = 39, 1200 debugserver_xmm0 = 40, 1201 debugserver_xmm1 = 41, 1202 debugserver_xmm2 = 42, 1203 debugserver_xmm3 = 43, 1204 debugserver_xmm4 = 44, 1205 debugserver_xmm5 = 45, 1206 debugserver_xmm6 = 46, 1207 debugserver_xmm7 = 47, 1208 debugserver_xmm8 = 48, 1209 debugserver_xmm9 = 49, 1210 debugserver_xmm10 = 50, 1211 debugserver_xmm11 = 51, 1212 debugserver_xmm12 = 52, 1213 debugserver_xmm13 = 53, 1214 debugserver_xmm14 = 54, 1215 debugserver_xmm15 = 55, 1216 debugserver_mxcsr = 56, 1217 debugserver_ymm0 = debugserver_xmm0, 1218 debugserver_ymm1 = debugserver_xmm1, 1219 debugserver_ymm2 = debugserver_xmm2, 1220 debugserver_ymm3 = debugserver_xmm3, 1221 debugserver_ymm4 = debugserver_xmm4, 1222 debugserver_ymm5 = debugserver_xmm5, 1223 debugserver_ymm6 = debugserver_xmm6, 1224 debugserver_ymm7 = debugserver_xmm7, 1225 debugserver_ymm8 = debugserver_xmm8, 1226 debugserver_ymm9 = debugserver_xmm9, 1227 debugserver_ymm10 = debugserver_xmm10, 1228 debugserver_ymm11 = debugserver_xmm11, 1229 debugserver_ymm12 = debugserver_xmm12, 1230 debugserver_ymm13 = debugserver_xmm13, 1231 debugserver_ymm14 = debugserver_xmm14, 1232 debugserver_ymm15 = debugserver_xmm15 1233 }; 1234 1235 #define GPR_OFFSET(reg) (offsetof(DNBArchImplX86_64::GPR, __##reg)) 1236 #define FPU_OFFSET(reg) \ 1237 (offsetof(DNBArchImplX86_64::FPU, __fpu_##reg) + \ 1238 offsetof(DNBArchImplX86_64::Context, fpu.no_avx)) 1239 #define AVX_OFFSET(reg) \ 1240 (offsetof(DNBArchImplX86_64::AVX, __fpu_##reg) + \ 1241 offsetof(DNBArchImplX86_64::Context, fpu.avx)) 1242 #define EXC_OFFSET(reg) \ 1243 (offsetof(DNBArchImplX86_64::EXC, __##reg) + \ 1244 offsetof(DNBArchImplX86_64::Context, exc)) 1245 #define AVX_OFFSET_YMM(n) (AVX_OFFSET(ymmh0) + (32 * n)) 1246 1247 #define GPR_SIZE(reg) (sizeof(((DNBArchImplX86_64::GPR *)NULL)->__##reg)) 1248 #define FPU_SIZE_UINT(reg) \ 1249 (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg)) 1250 #define FPU_SIZE_MMST(reg) \ 1251 (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg.__mmst_reg)) 1252 #define FPU_SIZE_XMM(reg) \ 1253 (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg.__xmm_reg)) 1254 #define FPU_SIZE_YMM(reg) (32) 1255 #define EXC_SIZE(reg) (sizeof(((DNBArchImplX86_64::EXC *)NULL)->__##reg)) 1256 1257 // These macros will auto define the register name, alt name, register size, 1258 // register offset, encoding, format and native register. This ensures that 1259 // the register state structures are defined correctly and have the correct 1260 // sizes and offsets. 1261 #define DEFINE_GPR(reg) \ 1262 { \ 1263 e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, GPR_SIZE(reg), \ 1264 GPR_OFFSET(reg), ehframe_dwarf_##reg, ehframe_dwarf_##reg, \ 1265 INVALID_NUB_REGNUM, debugserver_##reg, NULL, g_invalidate_##reg \ 1266 } 1267 #define DEFINE_GPR_ALT(reg, alt, gen) \ 1268 { \ 1269 e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \ 1270 GPR_OFFSET(reg), ehframe_dwarf_##reg, ehframe_dwarf_##reg, gen, \ 1271 debugserver_##reg, NULL, g_invalidate_##reg \ 1272 } 1273 #define DEFINE_GPR_ALT2(reg, alt) \ 1274 { \ 1275 e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \ 1276 GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \ 1277 INVALID_NUB_REGNUM, debugserver_##reg, NULL, NULL \ 1278 } 1279 #define DEFINE_GPR_ALT3(reg, alt, gen) \ 1280 { \ 1281 e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \ 1282 GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gen, \ 1283 debugserver_##reg, NULL, NULL \ 1284 } 1285 #define DEFINE_GPR_ALT4(reg, alt, gen) \ 1286 { \ 1287 e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \ 1288 GPR_OFFSET(reg), ehframe_dwarf_##reg, ehframe_dwarf_##reg, gen, \ 1289 debugserver_##reg, NULL, NULL \ 1290 } 1291 1292 #define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ 1293 { \ 1294 e_regSetGPR, gpr_##reg32, #reg32, NULL, Uint, Hex, 4, 0, \ 1295 INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \ 1296 INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 \ 1297 } 1298 #define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ 1299 { \ 1300 e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, 0, \ 1301 INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \ 1302 INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 \ 1303 } 1304 #define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ 1305 { \ 1306 e_regSetGPR, gpr_##reg8, #reg8, NULL, Uint, Hex, 1, 1, INVALID_NUB_REGNUM, \ 1307 INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \ 1308 g_contained_##reg64, g_invalidate_##reg64 \ 1309 } 1310 #define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ 1311 { \ 1312 e_regSetGPR, gpr_##reg8, #reg8, NULL, Uint, Hex, 1, 0, INVALID_NUB_REGNUM, \ 1313 INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \ 1314 g_contained_##reg64, g_invalidate_##reg64 \ 1315 } 1316 1317 // General purpose registers for 64 bit 1318 1319 const char *g_contained_rax[] = {"rax", NULL}; 1320 const char *g_contained_rbx[] = {"rbx", NULL}; 1321 const char *g_contained_rcx[] = {"rcx", NULL}; 1322 const char *g_contained_rdx[] = {"rdx", NULL}; 1323 const char *g_contained_rdi[] = {"rdi", NULL}; 1324 const char *g_contained_rsi[] = {"rsi", NULL}; 1325 const char *g_contained_rbp[] = {"rbp", NULL}; 1326 const char *g_contained_rsp[] = {"rsp", NULL}; 1327 const char *g_contained_r8[] = {"r8", NULL}; 1328 const char *g_contained_r9[] = {"r9", NULL}; 1329 const char *g_contained_r10[] = {"r10", NULL}; 1330 const char *g_contained_r11[] = {"r11", NULL}; 1331 const char *g_contained_r12[] = {"r12", NULL}; 1332 const char *g_contained_r13[] = {"r13", NULL}; 1333 const char *g_contained_r14[] = {"r14", NULL}; 1334 const char *g_contained_r15[] = {"r15", NULL}; 1335 1336 const char *g_invalidate_rax[] = {"rax", "eax", "ax", "ah", "al", NULL}; 1337 const char *g_invalidate_rbx[] = {"rbx", "ebx", "bx", "bh", "bl", NULL}; 1338 const char *g_invalidate_rcx[] = {"rcx", "ecx", "cx", "ch", "cl", NULL}; 1339 const char *g_invalidate_rdx[] = {"rdx", "edx", "dx", "dh", "dl", NULL}; 1340 const char *g_invalidate_rdi[] = {"rdi", "edi", "di", "dil", NULL}; 1341 const char *g_invalidate_rsi[] = {"rsi", "esi", "si", "sil", NULL}; 1342 const char *g_invalidate_rbp[] = {"rbp", "ebp", "bp", "bpl", NULL}; 1343 const char *g_invalidate_rsp[] = {"rsp", "esp", "sp", "spl", NULL}; 1344 const char *g_invalidate_r8[] = {"r8", "r8d", "r8w", "r8l", NULL}; 1345 const char *g_invalidate_r9[] = {"r9", "r9d", "r9w", "r9l", NULL}; 1346 const char *g_invalidate_r10[] = {"r10", "r10d", "r10w", "r10l", NULL}; 1347 const char *g_invalidate_r11[] = {"r11", "r11d", "r11w", "r11l", NULL}; 1348 const char *g_invalidate_r12[] = {"r12", "r12d", "r12w", "r12l", NULL}; 1349 const char *g_invalidate_r13[] = {"r13", "r13d", "r13w", "r13l", NULL}; 1350 const char *g_invalidate_r14[] = {"r14", "r14d", "r14w", "r14l", NULL}; 1351 const char *g_invalidate_r15[] = {"r15", "r15d", "r15w", "r15l", NULL}; 1352 1353 const DNBRegisterInfo DNBArchImplX86_64::g_gpr_registers[] = { 1354 DEFINE_GPR(rax), 1355 DEFINE_GPR(rbx), 1356 DEFINE_GPR_ALT(rcx, "arg4", GENERIC_REGNUM_ARG4), 1357 DEFINE_GPR_ALT(rdx, "arg3", GENERIC_REGNUM_ARG3), 1358 DEFINE_GPR_ALT(rdi, "arg1", GENERIC_REGNUM_ARG1), 1359 DEFINE_GPR_ALT(rsi, "arg2", GENERIC_REGNUM_ARG2), 1360 DEFINE_GPR_ALT(rbp, "fp", GENERIC_REGNUM_FP), 1361 DEFINE_GPR_ALT(rsp, "sp", GENERIC_REGNUM_SP), 1362 DEFINE_GPR_ALT(r8, "arg5", GENERIC_REGNUM_ARG5), 1363 DEFINE_GPR_ALT(r9, "arg6", GENERIC_REGNUM_ARG6), 1364 DEFINE_GPR(r10), 1365 DEFINE_GPR(r11), 1366 DEFINE_GPR(r12), 1367 DEFINE_GPR(r13), 1368 DEFINE_GPR(r14), 1369 DEFINE_GPR(r15), 1370 DEFINE_GPR_ALT4(rip, "pc", GENERIC_REGNUM_PC), 1371 DEFINE_GPR_ALT3(rflags, "flags", GENERIC_REGNUM_FLAGS), 1372 DEFINE_GPR_ALT2(cs, NULL), 1373 DEFINE_GPR_ALT2(fs, NULL), 1374 DEFINE_GPR_ALT2(gs, NULL), 1375 DEFINE_GPR_PSEUDO_32(eax, rax), 1376 DEFINE_GPR_PSEUDO_32(ebx, rbx), 1377 DEFINE_GPR_PSEUDO_32(ecx, rcx), 1378 DEFINE_GPR_PSEUDO_32(edx, rdx), 1379 DEFINE_GPR_PSEUDO_32(edi, rdi), 1380 DEFINE_GPR_PSEUDO_32(esi, rsi), 1381 DEFINE_GPR_PSEUDO_32(ebp, rbp), 1382 DEFINE_GPR_PSEUDO_32(esp, rsp), 1383 DEFINE_GPR_PSEUDO_32(r8d, r8), 1384 DEFINE_GPR_PSEUDO_32(r9d, r9), 1385 DEFINE_GPR_PSEUDO_32(r10d, r10), 1386 DEFINE_GPR_PSEUDO_32(r11d, r11), 1387 DEFINE_GPR_PSEUDO_32(r12d, r12), 1388 DEFINE_GPR_PSEUDO_32(r13d, r13), 1389 DEFINE_GPR_PSEUDO_32(r14d, r14), 1390 DEFINE_GPR_PSEUDO_32(r15d, r15), 1391 DEFINE_GPR_PSEUDO_16(ax, rax), 1392 DEFINE_GPR_PSEUDO_16(bx, rbx), 1393 DEFINE_GPR_PSEUDO_16(cx, rcx), 1394 DEFINE_GPR_PSEUDO_16(dx, rdx), 1395 DEFINE_GPR_PSEUDO_16(di, rdi), 1396 DEFINE_GPR_PSEUDO_16(si, rsi), 1397 DEFINE_GPR_PSEUDO_16(bp, rbp), 1398 DEFINE_GPR_PSEUDO_16(sp, rsp), 1399 DEFINE_GPR_PSEUDO_16(r8w, r8), 1400 DEFINE_GPR_PSEUDO_16(r9w, r9), 1401 DEFINE_GPR_PSEUDO_16(r10w, r10), 1402 DEFINE_GPR_PSEUDO_16(r11w, r11), 1403 DEFINE_GPR_PSEUDO_16(r12w, r12), 1404 DEFINE_GPR_PSEUDO_16(r13w, r13), 1405 DEFINE_GPR_PSEUDO_16(r14w, r14), 1406 DEFINE_GPR_PSEUDO_16(r15w, r15), 1407 DEFINE_GPR_PSEUDO_8H(ah, rax), 1408 DEFINE_GPR_PSEUDO_8H(bh, rbx), 1409 DEFINE_GPR_PSEUDO_8H(ch, rcx), 1410 DEFINE_GPR_PSEUDO_8H(dh, rdx), 1411 DEFINE_GPR_PSEUDO_8L(al, rax), 1412 DEFINE_GPR_PSEUDO_8L(bl, rbx), 1413 DEFINE_GPR_PSEUDO_8L(cl, rcx), 1414 DEFINE_GPR_PSEUDO_8L(dl, rdx), 1415 DEFINE_GPR_PSEUDO_8L(dil, rdi), 1416 DEFINE_GPR_PSEUDO_8L(sil, rsi), 1417 DEFINE_GPR_PSEUDO_8L(bpl, rbp), 1418 DEFINE_GPR_PSEUDO_8L(spl, rsp), 1419 DEFINE_GPR_PSEUDO_8L(r8l, r8), 1420 DEFINE_GPR_PSEUDO_8L(r9l, r9), 1421 DEFINE_GPR_PSEUDO_8L(r10l, r10), 1422 DEFINE_GPR_PSEUDO_8L(r11l, r11), 1423 DEFINE_GPR_PSEUDO_8L(r12l, r12), 1424 DEFINE_GPR_PSEUDO_8L(r13l, r13), 1425 DEFINE_GPR_PSEUDO_8L(r14l, r14), 1426 DEFINE_GPR_PSEUDO_8L(r15l, r15)}; 1427 1428 // Floating point registers 64 bit 1429 const DNBRegisterInfo DNBArchImplX86_64::g_fpu_registers_no_avx[] = { 1430 {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw), 1431 FPU_OFFSET(fcw), -1U, -1U, -1U, -1U, NULL, NULL}, 1432 {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw), 1433 FPU_OFFSET(fsw), -1U, -1U, -1U, -1U, NULL, NULL}, 1434 {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, FPU_SIZE_UINT(ftw), 1435 FPU_OFFSET(ftw), -1U, -1U, -1U, -1U, NULL, NULL}, 1436 {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop), 1437 FPU_OFFSET(fop), -1U, -1U, -1U, -1U, NULL, NULL}, 1438 {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip), 1439 FPU_OFFSET(ip), -1U, -1U, -1U, -1U, NULL, NULL}, 1440 {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs), 1441 FPU_OFFSET(cs), -1U, -1U, -1U, -1U, NULL, NULL}, 1442 {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp), 1443 FPU_OFFSET(dp), -1U, -1U, -1U, -1U, NULL, NULL}, 1444 {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds), 1445 FPU_OFFSET(ds), -1U, -1U, -1U, -1U, NULL, NULL}, 1446 {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr), 1447 FPU_OFFSET(mxcsr), -1U, -1U, -1U, -1U, NULL, NULL}, 1448 {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex, 1449 FPU_SIZE_UINT(mxcsrmask), FPU_OFFSET(mxcsrmask), -1U, -1U, -1U, -1U, NULL, 1450 NULL}, 1451 1452 {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, 1453 FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), ehframe_dwarf_stmm0, 1454 ehframe_dwarf_stmm0, -1U, debugserver_stmm0, NULL, NULL}, 1455 {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, 1456 FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), ehframe_dwarf_stmm1, 1457 ehframe_dwarf_stmm1, -1U, debugserver_stmm1, NULL, NULL}, 1458 {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, 1459 FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), ehframe_dwarf_stmm2, 1460 ehframe_dwarf_stmm2, -1U, debugserver_stmm2, NULL, NULL}, 1461 {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, 1462 FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), ehframe_dwarf_stmm3, 1463 ehframe_dwarf_stmm3, -1U, debugserver_stmm3, NULL, NULL}, 1464 {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, 1465 FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), ehframe_dwarf_stmm4, 1466 ehframe_dwarf_stmm4, -1U, debugserver_stmm4, NULL, NULL}, 1467 {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, 1468 FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), ehframe_dwarf_stmm5, 1469 ehframe_dwarf_stmm5, -1U, debugserver_stmm5, NULL, NULL}, 1470 {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, 1471 FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), ehframe_dwarf_stmm6, 1472 ehframe_dwarf_stmm6, -1U, debugserver_stmm6, NULL, NULL}, 1473 {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, 1474 FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), ehframe_dwarf_stmm7, 1475 ehframe_dwarf_stmm7, -1U, debugserver_stmm7, NULL, NULL}, 1476 1477 {e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, 1478 FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), ehframe_dwarf_xmm0, 1479 ehframe_dwarf_xmm0, -1U, debugserver_xmm0, NULL, NULL}, 1480 {e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, 1481 FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), ehframe_dwarf_xmm1, 1482 ehframe_dwarf_xmm1, -1U, debugserver_xmm1, NULL, NULL}, 1483 {e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, 1484 FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), ehframe_dwarf_xmm2, 1485 ehframe_dwarf_xmm2, -1U, debugserver_xmm2, NULL, NULL}, 1486 {e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, 1487 FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), ehframe_dwarf_xmm3, 1488 ehframe_dwarf_xmm3, -1U, debugserver_xmm3, NULL, NULL}, 1489 {e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, 1490 FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), ehframe_dwarf_xmm4, 1491 ehframe_dwarf_xmm4, -1U, debugserver_xmm4, NULL, NULL}, 1492 {e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, 1493 FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), ehframe_dwarf_xmm5, 1494 ehframe_dwarf_xmm5, -1U, debugserver_xmm5, NULL, NULL}, 1495 {e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, 1496 FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), ehframe_dwarf_xmm6, 1497 ehframe_dwarf_xmm6, -1U, debugserver_xmm6, NULL, NULL}, 1498 {e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, 1499 FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), ehframe_dwarf_xmm7, 1500 ehframe_dwarf_xmm7, -1U, debugserver_xmm7, NULL, NULL}, 1501 {e_regSetFPU, fpu_xmm8, "xmm8", NULL, Vector, VectorOfUInt8, 1502 FPU_SIZE_XMM(xmm8), FPU_OFFSET(xmm8), ehframe_dwarf_xmm8, 1503 ehframe_dwarf_xmm8, -1U, debugserver_xmm8, NULL, NULL}, 1504 {e_regSetFPU, fpu_xmm9, "xmm9", NULL, Vector, VectorOfUInt8, 1505 FPU_SIZE_XMM(xmm9), FPU_OFFSET(xmm9), ehframe_dwarf_xmm9, 1506 ehframe_dwarf_xmm9, -1U, debugserver_xmm9, NULL, NULL}, 1507 {e_regSetFPU, fpu_xmm10, "xmm10", NULL, Vector, VectorOfUInt8, 1508 FPU_SIZE_XMM(xmm10), FPU_OFFSET(xmm10), ehframe_dwarf_xmm10, 1509 ehframe_dwarf_xmm10, -1U, debugserver_xmm10, NULL, NULL}, 1510 {e_regSetFPU, fpu_xmm11, "xmm11", NULL, Vector, VectorOfUInt8, 1511 FPU_SIZE_XMM(xmm11), FPU_OFFSET(xmm11), ehframe_dwarf_xmm11, 1512 ehframe_dwarf_xmm11, -1U, debugserver_xmm11, NULL, NULL}, 1513 {e_regSetFPU, fpu_xmm12, "xmm12", NULL, Vector, VectorOfUInt8, 1514 FPU_SIZE_XMM(xmm12), FPU_OFFSET(xmm12), ehframe_dwarf_xmm12, 1515 ehframe_dwarf_xmm12, -1U, debugserver_xmm12, NULL, NULL}, 1516 {e_regSetFPU, fpu_xmm13, "xmm13", NULL, Vector, VectorOfUInt8, 1517 FPU_SIZE_XMM(xmm13), FPU_OFFSET(xmm13), ehframe_dwarf_xmm13, 1518 ehframe_dwarf_xmm13, -1U, debugserver_xmm13, NULL, NULL}, 1519 {e_regSetFPU, fpu_xmm14, "xmm14", NULL, Vector, VectorOfUInt8, 1520 FPU_SIZE_XMM(xmm14), FPU_OFFSET(xmm14), ehframe_dwarf_xmm14, 1521 ehframe_dwarf_xmm14, -1U, debugserver_xmm14, NULL, NULL}, 1522 {e_regSetFPU, fpu_xmm15, "xmm15", NULL, Vector, VectorOfUInt8, 1523 FPU_SIZE_XMM(xmm15), FPU_OFFSET(xmm15), ehframe_dwarf_xmm15, 1524 ehframe_dwarf_xmm15, -1U, debugserver_xmm15, NULL, NULL}, 1525 }; 1526 1527 static const char *g_contained_ymm0[] = {"ymm0", NULL}; 1528 static const char *g_contained_ymm1[] = {"ymm1", NULL}; 1529 static const char *g_contained_ymm2[] = {"ymm2", NULL}; 1530 static const char *g_contained_ymm3[] = {"ymm3", NULL}; 1531 static const char *g_contained_ymm4[] = {"ymm4", NULL}; 1532 static const char *g_contained_ymm5[] = {"ymm5", NULL}; 1533 static const char *g_contained_ymm6[] = {"ymm6", NULL}; 1534 static const char *g_contained_ymm7[] = {"ymm7", NULL}; 1535 static const char *g_contained_ymm8[] = {"ymm8", NULL}; 1536 static const char *g_contained_ymm9[] = {"ymm9", NULL}; 1537 static const char *g_contained_ymm10[] = {"ymm10", NULL}; 1538 static const char *g_contained_ymm11[] = {"ymm11", NULL}; 1539 static const char *g_contained_ymm12[] = {"ymm12", NULL}; 1540 static const char *g_contained_ymm13[] = {"ymm13", NULL}; 1541 static const char *g_contained_ymm14[] = {"ymm14", NULL}; 1542 static const char *g_contained_ymm15[] = {"ymm15", NULL}; 1543 1544 const DNBRegisterInfo DNBArchImplX86_64::g_fpu_registers_avx[] = { 1545 {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw), 1546 AVX_OFFSET(fcw), -1U, -1U, -1U, -1U, NULL, NULL}, 1547 {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw), 1548 AVX_OFFSET(fsw), -1U, -1U, -1U, -1U, NULL, NULL}, 1549 {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, FPU_SIZE_UINT(ftw), 1550 AVX_OFFSET(ftw), -1U, -1U, -1U, -1U, NULL, NULL}, 1551 {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop), 1552 AVX_OFFSET(fop), -1U, -1U, -1U, -1U, NULL, NULL}, 1553 {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip), 1554 AVX_OFFSET(ip), -1U, -1U, -1U, -1U, NULL, NULL}, 1555 {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs), 1556 AVX_OFFSET(cs), -1U, -1U, -1U, -1U, NULL, NULL}, 1557 {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp), 1558 AVX_OFFSET(dp), -1U, -1U, -1U, -1U, NULL, NULL}, 1559 {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds), 1560 AVX_OFFSET(ds), -1U, -1U, -1U, -1U, NULL, NULL}, 1561 {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr), 1562 AVX_OFFSET(mxcsr), -1U, -1U, -1U, -1U, NULL, NULL}, 1563 {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex, 1564 FPU_SIZE_UINT(mxcsrmask), AVX_OFFSET(mxcsrmask), -1U, -1U, -1U, -1U, NULL, 1565 NULL}, 1566 1567 {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, 1568 FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), ehframe_dwarf_stmm0, 1569 ehframe_dwarf_stmm0, -1U, debugserver_stmm0, NULL, NULL}, 1570 {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, 1571 FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), ehframe_dwarf_stmm1, 1572 ehframe_dwarf_stmm1, -1U, debugserver_stmm1, NULL, NULL}, 1573 {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, 1574 FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), ehframe_dwarf_stmm2, 1575 ehframe_dwarf_stmm2, -1U, debugserver_stmm2, NULL, NULL}, 1576 {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, 1577 FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), ehframe_dwarf_stmm3, 1578 ehframe_dwarf_stmm3, -1U, debugserver_stmm3, NULL, NULL}, 1579 {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, 1580 FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), ehframe_dwarf_stmm4, 1581 ehframe_dwarf_stmm4, -1U, debugserver_stmm4, NULL, NULL}, 1582 {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, 1583 FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), ehframe_dwarf_stmm5, 1584 ehframe_dwarf_stmm5, -1U, debugserver_stmm5, NULL, NULL}, 1585 {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, 1586 FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), ehframe_dwarf_stmm6, 1587 ehframe_dwarf_stmm6, -1U, debugserver_stmm6, NULL, NULL}, 1588 {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, 1589 FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), ehframe_dwarf_stmm7, 1590 ehframe_dwarf_stmm7, -1U, debugserver_stmm7, NULL, NULL}, 1591 1592 {e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8, 1593 FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), ehframe_dwarf_ymm0, 1594 ehframe_dwarf_ymm0, -1U, debugserver_ymm0, NULL, NULL}, 1595 {e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8, 1596 FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), ehframe_dwarf_ymm1, 1597 ehframe_dwarf_ymm1, -1U, debugserver_ymm1, NULL, NULL}, 1598 {e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8, 1599 FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), ehframe_dwarf_ymm2, 1600 ehframe_dwarf_ymm2, -1U, debugserver_ymm2, NULL, NULL}, 1601 {e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8, 1602 FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), ehframe_dwarf_ymm3, 1603 ehframe_dwarf_ymm3, -1U, debugserver_ymm3, NULL, NULL}, 1604 {e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8, 1605 FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), ehframe_dwarf_ymm4, 1606 ehframe_dwarf_ymm4, -1U, debugserver_ymm4, NULL, NULL}, 1607 {e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8, 1608 FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), ehframe_dwarf_ymm5, 1609 ehframe_dwarf_ymm5, -1U, debugserver_ymm5, NULL, NULL}, 1610 {e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8, 1611 FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), ehframe_dwarf_ymm6, 1612 ehframe_dwarf_ymm6, -1U, debugserver_ymm6, NULL, NULL}, 1613 {e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8, 1614 FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), ehframe_dwarf_ymm7, 1615 ehframe_dwarf_ymm7, -1U, debugserver_ymm7, NULL, NULL}, 1616 {e_regSetFPU, fpu_ymm8, "ymm8", NULL, Vector, VectorOfUInt8, 1617 FPU_SIZE_YMM(ymm8), AVX_OFFSET_YMM(8), ehframe_dwarf_ymm8, 1618 ehframe_dwarf_ymm8, -1U, debugserver_ymm8, NULL, NULL}, 1619 {e_regSetFPU, fpu_ymm9, "ymm9", NULL, Vector, VectorOfUInt8, 1620 FPU_SIZE_YMM(ymm9), AVX_OFFSET_YMM(9), ehframe_dwarf_ymm9, 1621 ehframe_dwarf_ymm9, -1U, debugserver_ymm9, NULL, NULL}, 1622 {e_regSetFPU, fpu_ymm10, "ymm10", NULL, Vector, VectorOfUInt8, 1623 FPU_SIZE_YMM(ymm10), AVX_OFFSET_YMM(10), ehframe_dwarf_ymm10, 1624 ehframe_dwarf_ymm10, -1U, debugserver_ymm10, NULL, NULL}, 1625 {e_regSetFPU, fpu_ymm11, "ymm11", NULL, Vector, VectorOfUInt8, 1626 FPU_SIZE_YMM(ymm11), AVX_OFFSET_YMM(11), ehframe_dwarf_ymm11, 1627 ehframe_dwarf_ymm11, -1U, debugserver_ymm11, NULL, NULL}, 1628 {e_regSetFPU, fpu_ymm12, "ymm12", NULL, Vector, VectorOfUInt8, 1629 FPU_SIZE_YMM(ymm12), AVX_OFFSET_YMM(12), ehframe_dwarf_ymm12, 1630 ehframe_dwarf_ymm12, -1U, debugserver_ymm12, NULL, NULL}, 1631 {e_regSetFPU, fpu_ymm13, "ymm13", NULL, Vector, VectorOfUInt8, 1632 FPU_SIZE_YMM(ymm13), AVX_OFFSET_YMM(13), ehframe_dwarf_ymm13, 1633 ehframe_dwarf_ymm13, -1U, debugserver_ymm13, NULL, NULL}, 1634 {e_regSetFPU, fpu_ymm14, "ymm14", NULL, Vector, VectorOfUInt8, 1635 FPU_SIZE_YMM(ymm14), AVX_OFFSET_YMM(14), ehframe_dwarf_ymm14, 1636 ehframe_dwarf_ymm14, -1U, debugserver_ymm14, NULL, NULL}, 1637 {e_regSetFPU, fpu_ymm15, "ymm15", NULL, Vector, VectorOfUInt8, 1638 FPU_SIZE_YMM(ymm15), AVX_OFFSET_YMM(15), ehframe_dwarf_ymm15, 1639 ehframe_dwarf_ymm15, -1U, debugserver_ymm15, NULL, NULL}, 1640 1641 {e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, 1642 FPU_SIZE_XMM(xmm0), 0, ehframe_dwarf_xmm0, ehframe_dwarf_xmm0, -1U, 1643 debugserver_xmm0, g_contained_ymm0, NULL}, 1644 {e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, 1645 FPU_SIZE_XMM(xmm1), 0, ehframe_dwarf_xmm1, ehframe_dwarf_xmm1, -1U, 1646 debugserver_xmm1, g_contained_ymm1, NULL}, 1647 {e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, 1648 FPU_SIZE_XMM(xmm2), 0, ehframe_dwarf_xmm2, ehframe_dwarf_xmm2, -1U, 1649 debugserver_xmm2, g_contained_ymm2, NULL}, 1650 {e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, 1651 FPU_SIZE_XMM(xmm3), 0, ehframe_dwarf_xmm3, ehframe_dwarf_xmm3, -1U, 1652 debugserver_xmm3, g_contained_ymm3, NULL}, 1653 {e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, 1654 FPU_SIZE_XMM(xmm4), 0, ehframe_dwarf_xmm4, ehframe_dwarf_xmm4, -1U, 1655 debugserver_xmm4, g_contained_ymm4, NULL}, 1656 {e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, 1657 FPU_SIZE_XMM(xmm5), 0, ehframe_dwarf_xmm5, ehframe_dwarf_xmm5, -1U, 1658 debugserver_xmm5, g_contained_ymm5, NULL}, 1659 {e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, 1660 FPU_SIZE_XMM(xmm6), 0, ehframe_dwarf_xmm6, ehframe_dwarf_xmm6, -1U, 1661 debugserver_xmm6, g_contained_ymm6, NULL}, 1662 {e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, 1663 FPU_SIZE_XMM(xmm7), 0, ehframe_dwarf_xmm7, ehframe_dwarf_xmm7, -1U, 1664 debugserver_xmm7, g_contained_ymm7, NULL}, 1665 {e_regSetFPU, fpu_xmm8, "xmm8", NULL, Vector, VectorOfUInt8, 1666 FPU_SIZE_XMM(xmm8), 0, ehframe_dwarf_xmm8, ehframe_dwarf_xmm8, -1U, 1667 debugserver_xmm8, g_contained_ymm8, NULL}, 1668 {e_regSetFPU, fpu_xmm9, "xmm9", NULL, Vector, VectorOfUInt8, 1669 FPU_SIZE_XMM(xmm9), 0, ehframe_dwarf_xmm9, ehframe_dwarf_xmm9, -1U, 1670 debugserver_xmm9, g_contained_ymm9, NULL}, 1671 {e_regSetFPU, fpu_xmm10, "xmm10", NULL, Vector, VectorOfUInt8, 1672 FPU_SIZE_XMM(xmm10), 0, ehframe_dwarf_xmm10, ehframe_dwarf_xmm10, -1U, 1673 debugserver_xmm10, g_contained_ymm10, NULL}, 1674 {e_regSetFPU, fpu_xmm11, "xmm11", NULL, Vector, VectorOfUInt8, 1675 FPU_SIZE_XMM(xmm11), 0, ehframe_dwarf_xmm11, ehframe_dwarf_xmm11, -1U, 1676 debugserver_xmm11, g_contained_ymm11, NULL}, 1677 {e_regSetFPU, fpu_xmm12, "xmm12", NULL, Vector, VectorOfUInt8, 1678 FPU_SIZE_XMM(xmm12), 0, ehframe_dwarf_xmm12, ehframe_dwarf_xmm12, -1U, 1679 debugserver_xmm12, g_contained_ymm12, NULL}, 1680 {e_regSetFPU, fpu_xmm13, "xmm13", NULL, Vector, VectorOfUInt8, 1681 FPU_SIZE_XMM(xmm13), 0, ehframe_dwarf_xmm13, ehframe_dwarf_xmm13, -1U, 1682 debugserver_xmm13, g_contained_ymm13, NULL}, 1683 {e_regSetFPU, fpu_xmm14, "xmm14", NULL, Vector, VectorOfUInt8, 1684 FPU_SIZE_XMM(xmm14), 0, ehframe_dwarf_xmm14, ehframe_dwarf_xmm14, -1U, 1685 debugserver_xmm14, g_contained_ymm14, NULL}, 1686 {e_regSetFPU, fpu_xmm15, "xmm15", NULL, Vector, VectorOfUInt8, 1687 FPU_SIZE_XMM(xmm15), 0, ehframe_dwarf_xmm15, ehframe_dwarf_xmm15, -1U, 1688 debugserver_xmm15, g_contained_ymm15, NULL} 1689 1690 }; 1691 1692 // Exception registers 1693 1694 const DNBRegisterInfo DNBArchImplX86_64::g_exc_registers[] = { 1695 {e_regSetEXC, exc_trapno, "trapno", NULL, Uint, Hex, EXC_SIZE(trapno), 1696 EXC_OFFSET(trapno), -1U, -1U, -1U, -1U, NULL, NULL}, 1697 {e_regSetEXC, exc_err, "err", NULL, Uint, Hex, EXC_SIZE(err), 1698 EXC_OFFSET(err), -1U, -1U, -1U, -1U, NULL, NULL}, 1699 {e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, 1700 EXC_SIZE(faultvaddr), EXC_OFFSET(faultvaddr), -1U, -1U, -1U, -1U, NULL, 1701 NULL}}; 1702 1703 // Number of registers in each register set 1704 const size_t DNBArchImplX86_64::k_num_gpr_registers = 1705 sizeof(g_gpr_registers) / sizeof(DNBRegisterInfo); 1706 const size_t DNBArchImplX86_64::k_num_fpu_registers_no_avx = 1707 sizeof(g_fpu_registers_no_avx) / sizeof(DNBRegisterInfo); 1708 const size_t DNBArchImplX86_64::k_num_fpu_registers_avx = 1709 sizeof(g_fpu_registers_avx) / sizeof(DNBRegisterInfo); 1710 const size_t DNBArchImplX86_64::k_num_exc_registers = 1711 sizeof(g_exc_registers) / sizeof(DNBRegisterInfo); 1712 const size_t DNBArchImplX86_64::k_num_all_registers_no_avx = 1713 k_num_gpr_registers + k_num_fpu_registers_no_avx + k_num_exc_registers; 1714 const size_t DNBArchImplX86_64::k_num_all_registers_avx = 1715 k_num_gpr_registers + k_num_fpu_registers_avx + k_num_exc_registers; 1716 1717 //---------------------------------------------------------------------- 1718 // Register set definitions. The first definitions at register set index 1719 // of zero is for all registers, followed by other registers sets. The 1720 // register information for the all register set need not be filled in. 1721 //---------------------------------------------------------------------- 1722 const DNBRegisterSetInfo DNBArchImplX86_64::g_reg_sets_no_avx[] = { 1723 {"x86_64 Registers", NULL, k_num_all_registers_no_avx}, 1724 {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers}, 1725 {"Floating Point Registers", g_fpu_registers_no_avx, 1726 k_num_fpu_registers_no_avx}, 1727 {"Exception State Registers", g_exc_registers, k_num_exc_registers}}; 1728 1729 const DNBRegisterSetInfo DNBArchImplX86_64::g_reg_sets_avx[] = { 1730 {"x86_64 Registers", NULL, k_num_all_registers_avx}, 1731 {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers}, 1732 {"Floating Point Registers", g_fpu_registers_avx, k_num_fpu_registers_avx}, 1733 {"Exception State Registers", g_exc_registers, k_num_exc_registers}}; 1734 1735 // Total number of register sets for this architecture 1736 const size_t DNBArchImplX86_64::k_num_register_sets = 1737 sizeof(g_reg_sets_avx) / sizeof(DNBRegisterSetInfo); 1738 1739 DNBArchProtocol *DNBArchImplX86_64::Create(MachThread *thread) { 1740 DNBArchImplX86_64 *obj = new DNBArchImplX86_64(thread); 1741 return obj; 1742 } 1743 1744 const uint8_t * 1745 DNBArchImplX86_64::SoftwareBreakpointOpcode(nub_size_t byte_size) { 1746 static const uint8_t g_breakpoint_opcode[] = {0xCC}; 1747 if (byte_size == 1) 1748 return g_breakpoint_opcode; 1749 return NULL; 1750 } 1751 1752 const DNBRegisterSetInfo * 1753 DNBArchImplX86_64::GetRegisterSetInfo(nub_size_t *num_reg_sets) { 1754 *num_reg_sets = k_num_register_sets; 1755 1756 if (CPUHasAVX() || FORCE_AVX_REGS) 1757 return g_reg_sets_avx; 1758 else 1759 return g_reg_sets_no_avx; 1760 } 1761 1762 void DNBArchImplX86_64::Initialize() { 1763 DNBArchPluginInfo arch_plugin_info = { 1764 CPU_TYPE_X86_64, DNBArchImplX86_64::Create, 1765 DNBArchImplX86_64::GetRegisterSetInfo, 1766 DNBArchImplX86_64::SoftwareBreakpointOpcode}; 1767 1768 // Register this arch plug-in with the main protocol class 1769 DNBArchProtocol::RegisterArchPlugin(arch_plugin_info); 1770 } 1771 1772 bool DNBArchImplX86_64::GetRegisterValue(uint32_t set, uint32_t reg, 1773 DNBRegisterValue *value) { 1774 if (set == REGISTER_SET_GENERIC) { 1775 switch (reg) { 1776 case GENERIC_REGNUM_PC: // Program Counter 1777 set = e_regSetGPR; 1778 reg = gpr_rip; 1779 break; 1780 1781 case GENERIC_REGNUM_SP: // Stack Pointer 1782 set = e_regSetGPR; 1783 reg = gpr_rsp; 1784 break; 1785 1786 case GENERIC_REGNUM_FP: // Frame Pointer 1787 set = e_regSetGPR; 1788 reg = gpr_rbp; 1789 break; 1790 1791 case GENERIC_REGNUM_FLAGS: // Processor flags register 1792 set = e_regSetGPR; 1793 reg = gpr_rflags; 1794 break; 1795 1796 case GENERIC_REGNUM_RA: // Return Address 1797 default: 1798 return false; 1799 } 1800 } 1801 1802 if (GetRegisterState(set, false) != KERN_SUCCESS) 1803 return false; 1804 1805 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 1806 if (regInfo) { 1807 value->info = *regInfo; 1808 switch (set) { 1809 case e_regSetGPR: 1810 if (reg < k_num_gpr_registers) { 1811 value->value.uint64 = ((uint64_t *)(&m_state.context.gpr))[reg]; 1812 return true; 1813 } 1814 break; 1815 1816 case e_regSetFPU: 1817 if (CPUHasAVX() || FORCE_AVX_REGS) { 1818 switch (reg) { 1819 case fpu_fcw: 1820 value->value.uint16 = 1821 *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fcw)); 1822 return true; 1823 case fpu_fsw: 1824 value->value.uint16 = 1825 *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fsw)); 1826 return true; 1827 case fpu_ftw: 1828 value->value.uint8 = m_state.context.fpu.avx.__fpu_ftw; 1829 return true; 1830 case fpu_fop: 1831 value->value.uint16 = m_state.context.fpu.avx.__fpu_fop; 1832 return true; 1833 case fpu_ip: 1834 value->value.uint32 = m_state.context.fpu.avx.__fpu_ip; 1835 return true; 1836 case fpu_cs: 1837 value->value.uint16 = m_state.context.fpu.avx.__fpu_cs; 1838 return true; 1839 case fpu_dp: 1840 value->value.uint32 = m_state.context.fpu.avx.__fpu_dp; 1841 return true; 1842 case fpu_ds: 1843 value->value.uint16 = m_state.context.fpu.avx.__fpu_ds; 1844 return true; 1845 case fpu_mxcsr: 1846 value->value.uint32 = m_state.context.fpu.avx.__fpu_mxcsr; 1847 return true; 1848 case fpu_mxcsrmask: 1849 value->value.uint32 = m_state.context.fpu.avx.__fpu_mxcsrmask; 1850 return true; 1851 1852 case fpu_stmm0: 1853 case fpu_stmm1: 1854 case fpu_stmm2: 1855 case fpu_stmm3: 1856 case fpu_stmm4: 1857 case fpu_stmm5: 1858 case fpu_stmm6: 1859 case fpu_stmm7: 1860 memcpy(&value->value.uint8, 1861 &m_state.context.fpu.avx.__fpu_stmm0 + (reg - fpu_stmm0), 10); 1862 return true; 1863 1864 case fpu_xmm0: 1865 case fpu_xmm1: 1866 case fpu_xmm2: 1867 case fpu_xmm3: 1868 case fpu_xmm4: 1869 case fpu_xmm5: 1870 case fpu_xmm6: 1871 case fpu_xmm7: 1872 case fpu_xmm8: 1873 case fpu_xmm9: 1874 case fpu_xmm10: 1875 case fpu_xmm11: 1876 case fpu_xmm12: 1877 case fpu_xmm13: 1878 case fpu_xmm14: 1879 case fpu_xmm15: 1880 memcpy(&value->value.uint8, 1881 &m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_xmm0), 16); 1882 return true; 1883 1884 case fpu_ymm0: 1885 case fpu_ymm1: 1886 case fpu_ymm2: 1887 case fpu_ymm3: 1888 case fpu_ymm4: 1889 case fpu_ymm5: 1890 case fpu_ymm6: 1891 case fpu_ymm7: 1892 case fpu_ymm8: 1893 case fpu_ymm9: 1894 case fpu_ymm10: 1895 case fpu_ymm11: 1896 case fpu_ymm12: 1897 case fpu_ymm13: 1898 case fpu_ymm14: 1899 case fpu_ymm15: 1900 memcpy(&value->value.uint8, 1901 &m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_ymm0), 16); 1902 memcpy((&value->value.uint8) + 16, 1903 &m_state.context.fpu.avx.__fpu_ymmh0 + (reg - fpu_ymm0), 16); 1904 return true; 1905 } 1906 } else { 1907 switch (reg) { 1908 case fpu_fcw: 1909 value->value.uint16 = 1910 *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)); 1911 return true; 1912 case fpu_fsw: 1913 value->value.uint16 = 1914 *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)); 1915 return true; 1916 case fpu_ftw: 1917 value->value.uint8 = m_state.context.fpu.no_avx.__fpu_ftw; 1918 return true; 1919 case fpu_fop: 1920 value->value.uint16 = m_state.context.fpu.no_avx.__fpu_fop; 1921 return true; 1922 case fpu_ip: 1923 value->value.uint32 = m_state.context.fpu.no_avx.__fpu_ip; 1924 return true; 1925 case fpu_cs: 1926 value->value.uint16 = m_state.context.fpu.no_avx.__fpu_cs; 1927 return true; 1928 case fpu_dp: 1929 value->value.uint32 = m_state.context.fpu.no_avx.__fpu_dp; 1930 return true; 1931 case fpu_ds: 1932 value->value.uint16 = m_state.context.fpu.no_avx.__fpu_ds; 1933 return true; 1934 case fpu_mxcsr: 1935 value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsr; 1936 return true; 1937 case fpu_mxcsrmask: 1938 value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsrmask; 1939 return true; 1940 1941 case fpu_stmm0: 1942 case fpu_stmm1: 1943 case fpu_stmm2: 1944 case fpu_stmm3: 1945 case fpu_stmm4: 1946 case fpu_stmm5: 1947 case fpu_stmm6: 1948 case fpu_stmm7: 1949 memcpy(&value->value.uint8, 1950 &m_state.context.fpu.no_avx.__fpu_stmm0 + (reg - fpu_stmm0), 1951 10); 1952 return true; 1953 1954 case fpu_xmm0: 1955 case fpu_xmm1: 1956 case fpu_xmm2: 1957 case fpu_xmm3: 1958 case fpu_xmm4: 1959 case fpu_xmm5: 1960 case fpu_xmm6: 1961 case fpu_xmm7: 1962 case fpu_xmm8: 1963 case fpu_xmm9: 1964 case fpu_xmm10: 1965 case fpu_xmm11: 1966 case fpu_xmm12: 1967 case fpu_xmm13: 1968 case fpu_xmm14: 1969 case fpu_xmm15: 1970 memcpy(&value->value.uint8, 1971 &m_state.context.fpu.no_avx.__fpu_xmm0 + (reg - fpu_xmm0), 16); 1972 return true; 1973 } 1974 } 1975 break; 1976 1977 case e_regSetEXC: 1978 switch (reg) { 1979 case exc_trapno: 1980 value->value.uint32 = m_state.context.exc.__trapno; 1981 return true; 1982 case exc_err: 1983 value->value.uint32 = m_state.context.exc.__err; 1984 return true; 1985 case exc_faultvaddr: 1986 value->value.uint64 = m_state.context.exc.__faultvaddr; 1987 return true; 1988 } 1989 break; 1990 } 1991 } 1992 return false; 1993 } 1994 1995 bool DNBArchImplX86_64::SetRegisterValue(uint32_t set, uint32_t reg, 1996 const DNBRegisterValue *value) { 1997 if (set == REGISTER_SET_GENERIC) { 1998 switch (reg) { 1999 case GENERIC_REGNUM_PC: // Program Counter 2000 set = e_regSetGPR; 2001 reg = gpr_rip; 2002 break; 2003 2004 case GENERIC_REGNUM_SP: // Stack Pointer 2005 set = e_regSetGPR; 2006 reg = gpr_rsp; 2007 break; 2008 2009 case GENERIC_REGNUM_FP: // Frame Pointer 2010 set = e_regSetGPR; 2011 reg = gpr_rbp; 2012 break; 2013 2014 case GENERIC_REGNUM_FLAGS: // Processor flags register 2015 set = e_regSetGPR; 2016 reg = gpr_rflags; 2017 break; 2018 2019 case GENERIC_REGNUM_RA: // Return Address 2020 default: 2021 return false; 2022 } 2023 } 2024 2025 if (GetRegisterState(set, false) != KERN_SUCCESS) 2026 return false; 2027 2028 bool success = false; 2029 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 2030 if (regInfo) { 2031 switch (set) { 2032 case e_regSetGPR: 2033 if (reg < k_num_gpr_registers) { 2034 ((uint64_t *)(&m_state.context.gpr))[reg] = value->value.uint64; 2035 success = true; 2036 } 2037 break; 2038 2039 case e_regSetFPU: 2040 if (CPUHasAVX() || FORCE_AVX_REGS) { 2041 switch (reg) { 2042 case fpu_fcw: 2043 *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fcw)) = 2044 value->value.uint16; 2045 success = true; 2046 break; 2047 case fpu_fsw: 2048 *((uint16_t *)(&m_state.context.fpu.avx.__fpu_fsw)) = 2049 value->value.uint16; 2050 success = true; 2051 break; 2052 case fpu_ftw: 2053 m_state.context.fpu.avx.__fpu_ftw = value->value.uint8; 2054 success = true; 2055 break; 2056 case fpu_fop: 2057 m_state.context.fpu.avx.__fpu_fop = value->value.uint16; 2058 success = true; 2059 break; 2060 case fpu_ip: 2061 m_state.context.fpu.avx.__fpu_ip = value->value.uint32; 2062 success = true; 2063 break; 2064 case fpu_cs: 2065 m_state.context.fpu.avx.__fpu_cs = value->value.uint16; 2066 success = true; 2067 break; 2068 case fpu_dp: 2069 m_state.context.fpu.avx.__fpu_dp = value->value.uint32; 2070 success = true; 2071 break; 2072 case fpu_ds: 2073 m_state.context.fpu.avx.__fpu_ds = value->value.uint16; 2074 success = true; 2075 break; 2076 case fpu_mxcsr: 2077 m_state.context.fpu.avx.__fpu_mxcsr = value->value.uint32; 2078 success = true; 2079 break; 2080 case fpu_mxcsrmask: 2081 m_state.context.fpu.avx.__fpu_mxcsrmask = value->value.uint32; 2082 success = true; 2083 break; 2084 2085 case fpu_stmm0: 2086 case fpu_stmm1: 2087 case fpu_stmm2: 2088 case fpu_stmm3: 2089 case fpu_stmm4: 2090 case fpu_stmm5: 2091 case fpu_stmm6: 2092 case fpu_stmm7: 2093 memcpy(&m_state.context.fpu.avx.__fpu_stmm0 + (reg - fpu_stmm0), 2094 &value->value.uint8, 10); 2095 success = true; 2096 break; 2097 2098 case fpu_xmm0: 2099 case fpu_xmm1: 2100 case fpu_xmm2: 2101 case fpu_xmm3: 2102 case fpu_xmm4: 2103 case fpu_xmm5: 2104 case fpu_xmm6: 2105 case fpu_xmm7: 2106 case fpu_xmm8: 2107 case fpu_xmm9: 2108 case fpu_xmm10: 2109 case fpu_xmm11: 2110 case fpu_xmm12: 2111 case fpu_xmm13: 2112 case fpu_xmm14: 2113 case fpu_xmm15: 2114 memcpy(&m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_xmm0), 2115 &value->value.uint8, 16); 2116 success = true; 2117 break; 2118 2119 case fpu_ymm0: 2120 case fpu_ymm1: 2121 case fpu_ymm2: 2122 case fpu_ymm3: 2123 case fpu_ymm4: 2124 case fpu_ymm5: 2125 case fpu_ymm6: 2126 case fpu_ymm7: 2127 case fpu_ymm8: 2128 case fpu_ymm9: 2129 case fpu_ymm10: 2130 case fpu_ymm11: 2131 case fpu_ymm12: 2132 case fpu_ymm13: 2133 case fpu_ymm14: 2134 case fpu_ymm15: 2135 memcpy(&m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_ymm0), 2136 &value->value.uint8, 16); 2137 memcpy(&m_state.context.fpu.avx.__fpu_ymmh0 + (reg - fpu_ymm0), 2138 (&value->value.uint8) + 16, 16); 2139 return true; 2140 } 2141 } else { 2142 switch (reg) { 2143 case fpu_fcw: 2144 *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)) = 2145 value->value.uint16; 2146 success = true; 2147 break; 2148 case fpu_fsw: 2149 *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)) = 2150 value->value.uint16; 2151 success = true; 2152 break; 2153 case fpu_ftw: 2154 m_state.context.fpu.no_avx.__fpu_ftw = value->value.uint8; 2155 success = true; 2156 break; 2157 case fpu_fop: 2158 m_state.context.fpu.no_avx.__fpu_fop = value->value.uint16; 2159 success = true; 2160 break; 2161 case fpu_ip: 2162 m_state.context.fpu.no_avx.__fpu_ip = value->value.uint32; 2163 success = true; 2164 break; 2165 case fpu_cs: 2166 m_state.context.fpu.no_avx.__fpu_cs = value->value.uint16; 2167 success = true; 2168 break; 2169 case fpu_dp: 2170 m_state.context.fpu.no_avx.__fpu_dp = value->value.uint32; 2171 success = true; 2172 break; 2173 case fpu_ds: 2174 m_state.context.fpu.no_avx.__fpu_ds = value->value.uint16; 2175 success = true; 2176 break; 2177 case fpu_mxcsr: 2178 m_state.context.fpu.no_avx.__fpu_mxcsr = value->value.uint32; 2179 success = true; 2180 break; 2181 case fpu_mxcsrmask: 2182 m_state.context.fpu.no_avx.__fpu_mxcsrmask = value->value.uint32; 2183 success = true; 2184 break; 2185 2186 case fpu_stmm0: 2187 case fpu_stmm1: 2188 case fpu_stmm2: 2189 case fpu_stmm3: 2190 case fpu_stmm4: 2191 case fpu_stmm5: 2192 case fpu_stmm6: 2193 case fpu_stmm7: 2194 memcpy(&m_state.context.fpu.no_avx.__fpu_stmm0 + (reg - fpu_stmm0), 2195 &value->value.uint8, 10); 2196 success = true; 2197 break; 2198 2199 case fpu_xmm0: 2200 case fpu_xmm1: 2201 case fpu_xmm2: 2202 case fpu_xmm3: 2203 case fpu_xmm4: 2204 case fpu_xmm5: 2205 case fpu_xmm6: 2206 case fpu_xmm7: 2207 case fpu_xmm8: 2208 case fpu_xmm9: 2209 case fpu_xmm10: 2210 case fpu_xmm11: 2211 case fpu_xmm12: 2212 case fpu_xmm13: 2213 case fpu_xmm14: 2214 case fpu_xmm15: 2215 memcpy(&m_state.context.fpu.no_avx.__fpu_xmm0 + (reg - fpu_xmm0), 2216 &value->value.uint8, 16); 2217 success = true; 2218 break; 2219 } 2220 } 2221 break; 2222 2223 case e_regSetEXC: 2224 switch (reg) { 2225 case exc_trapno: 2226 m_state.context.exc.__trapno = value->value.uint32; 2227 success = true; 2228 break; 2229 case exc_err: 2230 m_state.context.exc.__err = value->value.uint32; 2231 success = true; 2232 break; 2233 case exc_faultvaddr: 2234 m_state.context.exc.__faultvaddr = value->value.uint64; 2235 success = true; 2236 break; 2237 } 2238 break; 2239 } 2240 } 2241 2242 if (success) 2243 return SetRegisterState(set) == KERN_SUCCESS; 2244 return false; 2245 } 2246 2247 uint32_t DNBArchImplX86_64::GetRegisterContextSize() { 2248 static uint32_t g_cached_size = 0; 2249 if (g_cached_size == 0) { 2250 if (CPUHasAVX() || FORCE_AVX_REGS) { 2251 for (size_t i = 0; i < k_num_fpu_registers_avx; ++i) { 2252 if (g_fpu_registers_avx[i].value_regs == NULL) 2253 g_cached_size += g_fpu_registers_avx[i].size; 2254 } 2255 } else { 2256 for (size_t i = 0; i < k_num_fpu_registers_no_avx; ++i) { 2257 if (g_fpu_registers_no_avx[i].value_regs == NULL) 2258 g_cached_size += g_fpu_registers_no_avx[i].size; 2259 } 2260 } 2261 DNBLogThreaded("DNBArchImplX86_64::GetRegisterContextSize() - GPR = %zu, " 2262 "FPU = %u, EXC = %zu", 2263 sizeof(GPR), g_cached_size, sizeof(EXC)); 2264 g_cached_size += sizeof(GPR); 2265 g_cached_size += sizeof(EXC); 2266 DNBLogThreaded( 2267 "DNBArchImplX86_64::GetRegisterContextSize() - GPR + FPU + EXC = %u", 2268 g_cached_size); 2269 } 2270 return g_cached_size; 2271 } 2272 2273 nub_size_t DNBArchImplX86_64::GetRegisterContext(void *buf, 2274 nub_size_t buf_len) { 2275 uint32_t size = GetRegisterContextSize(); 2276 2277 if (buf && buf_len) { 2278 bool force = false; 2279 kern_return_t kret; 2280 2281 if ((kret = GetGPRState(force)) != KERN_SUCCESS) { 2282 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf " 2283 "= %p, len = %llu) error: GPR regs failed " 2284 "to read: %u ", 2285 buf, (uint64_t)buf_len, kret); 2286 size = 0; 2287 } else if ((kret = GetFPUState(force)) != KERN_SUCCESS) { 2288 DNBLogThreadedIf( 2289 LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = " 2290 "%llu) error: %s regs failed to read: %u", 2291 buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret); 2292 size = 0; 2293 } else if ((kret = GetEXCState(force)) != KERN_SUCCESS) { 2294 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf " 2295 "= %p, len = %llu) error: EXC regs failed " 2296 "to read: %u", 2297 buf, (uint64_t)buf_len, kret); 2298 size = 0; 2299 } else { 2300 uint8_t *p = (uint8_t *)buf; 2301 // Copy the GPR registers 2302 memcpy(p, &m_state.context.gpr, sizeof(GPR)); 2303 p += sizeof(GPR); 2304 2305 if (CPUHasAVX() || FORCE_AVX_REGS) { 2306 // Walk around the gaps in the FPU regs 2307 memcpy(p, &m_state.context.fpu.avx.__fpu_fcw, 5); 2308 p += 5; 2309 memcpy(p, &m_state.context.fpu.avx.__fpu_fop, 8); 2310 p += 8; 2311 memcpy(p, &m_state.context.fpu.avx.__fpu_dp, 6); 2312 p += 6; 2313 memcpy(p, &m_state.context.fpu.avx.__fpu_mxcsr, 8); 2314 p += 8; 2315 2316 // Work around the padding between the stmm registers as they are 16 2317 // byte structs with 10 bytes of the value in each 2318 for (size_t i = 0; i < 8; ++i) { 2319 memcpy(p, &m_state.context.fpu.avx.__fpu_stmm0 + i, 10); 2320 p += 10; 2321 } 2322 2323 // Interleave the XMM and YMMH registers to make the YMM registers 2324 for (size_t i = 0; i < 16; ++i) { 2325 memcpy(p, &m_state.context.fpu.avx.__fpu_xmm0 + i, 16); 2326 p += 16; 2327 memcpy(p, &m_state.context.fpu.avx.__fpu_ymmh0 + i, 16); 2328 p += 16; 2329 } 2330 } else { 2331 // Walk around the gaps in the FPU regs 2332 memcpy(p, &m_state.context.fpu.no_avx.__fpu_fcw, 5); 2333 p += 5; 2334 memcpy(p, &m_state.context.fpu.no_avx.__fpu_fop, 8); 2335 p += 8; 2336 memcpy(p, &m_state.context.fpu.no_avx.__fpu_dp, 6); 2337 p += 6; 2338 memcpy(p, &m_state.context.fpu.no_avx.__fpu_mxcsr, 8); 2339 p += 8; 2340 2341 // Work around the padding between the stmm registers as they are 16 2342 // byte structs with 10 bytes of the value in each 2343 for (size_t i = 0; i < 8; ++i) { 2344 memcpy(p, &m_state.context.fpu.no_avx.__fpu_stmm0 + i, 10); 2345 p += 10; 2346 } 2347 2348 // Copy the XMM registers in a single block 2349 memcpy(p, &m_state.context.fpu.no_avx.__fpu_xmm0, 16 * 16); 2350 p += 16 * 16; 2351 } 2352 2353 // Copy the exception registers 2354 memcpy(p, &m_state.context.exc, sizeof(EXC)); 2355 p += sizeof(EXC); 2356 2357 // make sure we end up with exactly what we think we should have 2358 size_t bytes_written = p - (uint8_t *)buf; 2359 UNUSED_IF_ASSERT_DISABLED(bytes_written); 2360 assert(bytes_written == size); 2361 } 2362 } 2363 2364 DNBLogThreadedIf( 2365 LOG_THREAD, 2366 "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = %llu) => %u", buf, 2367 (uint64_t)buf_len, size); 2368 // Return the size of the register context even if NULL was passed in 2369 return size; 2370 } 2371 2372 nub_size_t DNBArchImplX86_64::SetRegisterContext(const void *buf, 2373 nub_size_t buf_len) { 2374 uint32_t size = GetRegisterContextSize(); 2375 if (buf == NULL || buf_len == 0) 2376 size = 0; 2377 2378 if (size) { 2379 if (size > buf_len) 2380 size = static_cast<uint32_t>(buf_len); 2381 2382 uint8_t *p = (uint8_t *)buf; 2383 // Copy the GPR registers 2384 memcpy(&m_state.context.gpr, p, sizeof(GPR)); 2385 p += sizeof(GPR); 2386 2387 if (CPUHasAVX() || FORCE_AVX_REGS) { 2388 // Walk around the gaps in the FPU regs 2389 memcpy(&m_state.context.fpu.avx.__fpu_fcw, p, 5); 2390 p += 5; 2391 memcpy(&m_state.context.fpu.avx.__fpu_fop, p, 8); 2392 p += 8; 2393 memcpy(&m_state.context.fpu.avx.__fpu_dp, p, 6); 2394 p += 6; 2395 memcpy(&m_state.context.fpu.avx.__fpu_mxcsr, p, 8); 2396 p += 8; 2397 2398 // Work around the padding between the stmm registers as they are 16 2399 // byte structs with 10 bytes of the value in each 2400 for (size_t i = 0; i < 8; ++i) { 2401 memcpy(&m_state.context.fpu.avx.__fpu_stmm0 + i, p, 10); 2402 p += 10; 2403 } 2404 2405 // Interleave the XMM and YMMH registers to make the YMM registers 2406 for (size_t i = 0; i < 16; ++i) { 2407 memcpy(&m_state.context.fpu.avx.__fpu_xmm0 + i, p, 16); 2408 p += 16; 2409 memcpy(&m_state.context.fpu.avx.__fpu_ymmh0 + i, p, 16); 2410 p += 16; 2411 } 2412 } else { 2413 // Copy fcw through mxcsrmask as there is no padding 2414 memcpy(&m_state.context.fpu.no_avx.__fpu_fcw, p, 5); 2415 p += 5; 2416 memcpy(&m_state.context.fpu.no_avx.__fpu_fop, p, 8); 2417 p += 8; 2418 memcpy(&m_state.context.fpu.no_avx.__fpu_dp, p, 6); 2419 p += 6; 2420 memcpy(&m_state.context.fpu.no_avx.__fpu_mxcsr, p, 8); 2421 p += 8; 2422 2423 // Work around the padding between the stmm registers as they are 16 2424 // byte structs with 10 bytes of the value in each 2425 for (size_t i = 0; i < 8; ++i) { 2426 memcpy(&m_state.context.fpu.no_avx.__fpu_stmm0 + i, p, 10); 2427 p += 10; 2428 } 2429 2430 // Copy the XMM registers in a single block 2431 memcpy(&m_state.context.fpu.no_avx.__fpu_xmm0, p, 16 * 16); 2432 p += 16 * 16; 2433 } 2434 2435 // Copy the exception registers 2436 memcpy(&m_state.context.exc, p, sizeof(EXC)); 2437 p += sizeof(EXC); 2438 2439 // make sure we end up with exactly what we think we should have 2440 size_t bytes_written = p - (uint8_t *)buf; 2441 UNUSED_IF_ASSERT_DISABLED(bytes_written); 2442 assert(bytes_written == size); 2443 2444 kern_return_t kret; 2445 if ((kret = SetGPRState()) != KERN_SUCCESS) 2446 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf " 2447 "= %p, len = %llu) error: GPR regs failed " 2448 "to write: %u", 2449 buf, (uint64_t)buf_len, kret); 2450 if ((kret = SetFPUState()) != KERN_SUCCESS) 2451 DNBLogThreadedIf( 2452 LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = " 2453 "%llu) error: %s regs failed to write: %u", 2454 buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret); 2455 if ((kret = SetEXCState()) != KERN_SUCCESS) 2456 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf " 2457 "= %p, len = %llu) error: EXP regs failed " 2458 "to write: %u", 2459 buf, (uint64_t)buf_len, kret); 2460 } 2461 DNBLogThreadedIf( 2462 LOG_THREAD, 2463 "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = %llu) => %llu", 2464 buf, (uint64_t)buf_len, (uint64_t)size); 2465 return size; 2466 } 2467 2468 uint32_t DNBArchImplX86_64::SaveRegisterState() { 2469 kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber()); 2470 DNBLogThreadedIf( 2471 LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u " 2472 "(SetGPRState() for stop_count = %u)", 2473 m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount()); 2474 2475 // Always re-read the registers because above we call thread_abort_safely(); 2476 bool force = true; 2477 2478 if ((kret = GetGPRState(force)) != KERN_SUCCESS) { 2479 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::SaveRegisterState () " 2480 "error: GPR regs failed to read: %u ", 2481 kret); 2482 } else if ((kret = GetFPUState(force)) != KERN_SUCCESS) { 2483 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::SaveRegisterState () " 2484 "error: %s regs failed to read: %u", 2485 CPUHasAVX() ? "AVX" : "FPU", kret); 2486 } else { 2487 const uint32_t save_id = GetNextRegisterStateSaveID(); 2488 m_saved_register_states[save_id] = m_state.context; 2489 return save_id; 2490 } 2491 return 0; 2492 } 2493 bool DNBArchImplX86_64::RestoreRegisterState(uint32_t save_id) { 2494 SaveRegisterStates::iterator pos = m_saved_register_states.find(save_id); 2495 if (pos != m_saved_register_states.end()) { 2496 m_state.context.gpr = pos->second.gpr; 2497 m_state.context.fpu = pos->second.fpu; 2498 m_state.SetError(e_regSetGPR, Read, 0); 2499 m_state.SetError(e_regSetFPU, Read, 0); 2500 kern_return_t kret; 2501 bool success = true; 2502 if ((kret = SetGPRState()) != KERN_SUCCESS) { 2503 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::RestoreRegisterState " 2504 "(save_id = %u) error: GPR regs failed to " 2505 "write: %u", 2506 save_id, kret); 2507 success = false; 2508 } else if ((kret = SetFPUState()) != KERN_SUCCESS) { 2509 DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::RestoreRegisterState " 2510 "(save_id = %u) error: %s regs failed to " 2511 "write: %u", 2512 save_id, CPUHasAVX() ? "AVX" : "FPU", kret); 2513 success = false; 2514 } 2515 m_saved_register_states.erase(pos); 2516 return success; 2517 } 2518 return false; 2519 } 2520 2521 kern_return_t DNBArchImplX86_64::GetRegisterState(int set, bool force) { 2522 switch (set) { 2523 case e_regSetALL: 2524 return GetGPRState(force) | GetFPUState(force) | GetEXCState(force); 2525 case e_regSetGPR: 2526 return GetGPRState(force); 2527 case e_regSetFPU: 2528 return GetFPUState(force); 2529 case e_regSetEXC: 2530 return GetEXCState(force); 2531 default: 2532 break; 2533 } 2534 return KERN_INVALID_ARGUMENT; 2535 } 2536 2537 kern_return_t DNBArchImplX86_64::SetRegisterState(int set) { 2538 // Make sure we have a valid context to set. 2539 if (RegisterSetStateIsValid(set)) { 2540 switch (set) { 2541 case e_regSetALL: 2542 return SetGPRState() | SetFPUState() | SetEXCState(); 2543 case e_regSetGPR: 2544 return SetGPRState(); 2545 case e_regSetFPU: 2546 return SetFPUState(); 2547 case e_regSetEXC: 2548 return SetEXCState(); 2549 default: 2550 break; 2551 } 2552 } 2553 return KERN_INVALID_ARGUMENT; 2554 } 2555 2556 bool DNBArchImplX86_64::RegisterSetStateIsValid(int set) const { 2557 return m_state.RegsAreValid(set); 2558 } 2559 2560 #endif // #if defined (__i386__) || defined (__x86_64__) 2561