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