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