diff --git a/headers/os/arch/x86_64/arch_debugger.h b/headers/os/arch/x86_64/arch_debugger.h index e4607d2fd9..ca89c14825 100644 --- a/headers/os/arch/x86_64/arch_debugger.h +++ b/headers/os/arch/x86_64/arch_debugger.h @@ -6,38 +6,14 @@ #define _ARCH_X86_64_DEBUGGER_H -typedef struct x86_64_fp_register { - uint8 value[10]; - uint8 reserved[6]; -} x86_64_fp_register; +#if __x86_64__ -typedef struct x86_64_xmm_register { - uint8 value[16]; -} x86_64_xmm_register; - - -typedef struct x86_64_extended_registers { - uint16 control; - uint16 status; - uint8 tag; - uint8 reserved1; - uint16 opcode; - uint64 instruction_pointer; - uint64 data_pointer; - uint32 mxcsr; - uint32 mxcsr_mask; - union { - x86_64_fp_register fp_registers[8]; // st0-st7 - x86_64_fp_register mmx_registers[8]; // mm0-mm7 - }; - x86_64_xmm_register xmm_registers[16]; // xmm0-xmm15 - uint8 reserved2[96]; // 416 - 512 -} x86_64_extended_registers; +#include struct x86_64_debug_cpu_state { - x86_64_extended_registers extended_registers; + struct savefpu extended_registers; uint64 gs; uint64 fs; @@ -68,4 +44,7 @@ struct x86_64_debug_cpu_state { } __attribute__((aligned(16))); +#endif + + #endif // _ARCH_X86_64_DEBUGGER_H diff --git a/headers/posix/arch/x86_64/signal.h b/headers/posix/arch/x86_64/signal.h index ad4fa4b128..e9146569ea 100644 --- a/headers/posix/arch/x86_64/signal.h +++ b/headers/posix/arch/x86_64/signal.h @@ -12,64 +12,18 @@ #if __x86_64__ - -struct fp_stack { - unsigned char st0[10]; - unsigned char _reserved_42_47[6]; - unsigned char st1[10]; - unsigned char _reserved_58_63[6]; - unsigned char st2[10]; - unsigned char _reserved_74_79[6]; - unsigned char st3[10]; - unsigned char _reserved_90_95[6]; - unsigned char st4[10]; - unsigned char _reserved_106_111[6]; - unsigned char st5[10]; - unsigned char _reserved_122_127[6]; - unsigned char st6[10]; - unsigned char _reserved_138_143[6]; - unsigned char st7[10]; - unsigned char _reserved_154_159[6]; +struct x86_64_fp_register { + unsigned char value[10]; + unsigned char reserved[6]; }; -struct mmx_regs { - unsigned char mm0[10]; - unsigned char _reserved_42_47[6]; - unsigned char mm1[10]; - unsigned char _reserved_58_63[6]; - unsigned char mm2[10]; - unsigned char _reserved_74_79[6]; - unsigned char mm3[10]; - unsigned char _reserved_90_95[6]; - unsigned char mm4[10]; - unsigned char _reserved_106_111[6]; - unsigned char mm5[10]; - unsigned char _reserved_122_127[6]; - unsigned char mm6[10]; - unsigned char _reserved_138_143[6]; - unsigned char mm7[10]; - unsigned char _reserved_154_159[6]; + +struct x86_64_xmm_register { + unsigned char value[16]; }; -struct xmm_regs { - unsigned char xmm0[16]; - unsigned char xmm1[16]; - unsigned char xmm2[16]; - unsigned char xmm3[16]; - unsigned char xmm4[16]; - unsigned char xmm5[16]; - unsigned char xmm6[16]; - unsigned char xmm7[16]; - unsigned char xmm8[16]; - unsigned char xmm9[16]; - unsigned char xmm10[16]; - unsigned char xmm11[16]; - unsigned char xmm12[16]; - unsigned char xmm13[16]; - unsigned char xmm14[16]; - unsigned char xmm15[16]; -}; +// The layout of this struct matches the one used by the FXSAVE instruction struct fpu_state { unsigned short control; unsigned short status; @@ -81,26 +35,33 @@ struct fpu_state { unsigned int mscsr_mask; union { - struct fp_stack fp; - struct mmx_regs mmx; + struct x86_64_fp_register fp[8]; + struct x86_64_fp_register mmx[8]; }; - struct xmm_regs xmm; + struct x86_64_xmm_register xmm[16]; unsigned char _reserved_416_511[96]; }; + struct xstate_hdr { unsigned long bv; unsigned long xcomp_bv; unsigned char _reserved[48]; }; + +// The layout of this struct matches the one used by the FXSAVE instruction on +// an AVX CPU struct savefpu { - struct fpu_state fp_fxsave; - struct xstate_hdr fp_xstate; - unsigned long fp_ymm[16][2]; + struct fpu_state fp_fxsave; + struct xstate_hdr fp_xstate; + struct x86_64_xmm_register fp_ymm[16]; + // The high half of the YMM registers, to combine with the low half + // found in fp_fxsave.xmm }; + struct vregs { unsigned long rax; unsigned long rbx; diff --git a/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp b/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp index cb03343633..995ecee58f 100644 --- a/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp +++ b/src/kits/debugger/arch/x86_64/ArchitectureX8664.cpp @@ -29,6 +29,7 @@ #include "disasm/DisassemblerX8664.h" +#define X86_64_EXTENDED_FEATURE_AVX (1 << 28) static const int32 kFromDwarfRegisters[] = { X86_64_REGISTER_RAX, @@ -170,6 +171,20 @@ ArchitectureX8664::Init() if (fAssemblyLanguage == NULL) return B_NO_MEMORY; + int featureFlags = 0; +#ifdef __x86_64__ + // TODO: this needs to be determined/retrieved indirectly from the + // target host interface, as in the remote case the CPU features may + // differ from those of the local CPU. + cpuid_info info; + status_t error = get_cpuid(&info, 1, 0); + if (error != B_OK) + return error; + + if ((info.eax_1.extended_features & X86_64_EXTENDED_FEATURE_AVX) != 0) + featureFlags |= X86_64_CPU_FEATURE_FLAG_AVX; +#endif + try { _AddIntegerRegister(X86_64_REGISTER_RIP, "rip", B_UINT64_TYPE, REGISTER_TYPE_INSTRUCTION_POINTER, false); @@ -240,38 +255,73 @@ ArchitectureX8664::Init() _AddSIMDRegister(X86_64_REGISTER_MM6, "mm6", sizeof(uint64)); _AddSIMDRegister(X86_64_REGISTER_MM7, "mm7", sizeof(uint64)); - _AddSIMDRegister(X86_64_REGISTER_XMM0, "xmm0", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM1, "xmm1", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM2, "xmm2", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM3, "xmm3", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM4, "xmm4", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM5, "xmm5", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM6, "xmm6", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM7, "xmm7", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM8, "xmm8", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM9, "xmm9", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM10, "xmm10", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM11, "xmm11", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM12, "xmm12", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM13, "xmm13", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM14, "xmm14", - sizeof(x86_64_xmm_register)); - _AddSIMDRegister(X86_64_REGISTER_XMM15, "xmm15", - sizeof(x86_64_xmm_register)); + if ((featureFlags & X86_64_CPU_FEATURE_FLAG_AVX) != 0) { + _AddSIMDRegister(X86_64_REGISTER_XMM0, "ymm0", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM1, "ymm1", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM2, "ymm2", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM3, "ymm3", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM4, "ymm4", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM5, "ymm5", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM6, "ymm6", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM7, "ymm7", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM8, "ymm8", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM9, "ymm9", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM10, "ymm10", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM11, "ymm11", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM12, "ymm12", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM13, "ymm13", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM14, "ymm14", + sizeof(x86_64_xmm_register) * 2); + _AddSIMDRegister(X86_64_REGISTER_XMM15, "ymm15", + sizeof(x86_64_xmm_register) * 2); + } else { + _AddSIMDRegister(X86_64_REGISTER_XMM0, "xmm0", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM1, "xmm1", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM2, "xmm2", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM3, "xmm3", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM4, "xmm4", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM5, "xmm5", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM6, "xmm6", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM7, "xmm7", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM8, "xmm8", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM9, "xmm9", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM10, "xmm10", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM11, "xmm11", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM12, "xmm12", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM13, "xmm13", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM14, "xmm14", + sizeof(x86_64_xmm_register)); + _AddSIMDRegister(X86_64_REGISTER_XMM15, "xmm15", + sizeof(x86_64_xmm_register)); + } } catch (std::bad_alloc&) { return B_NO_MEMORY; diff --git a/src/kits/debugger/arch/x86_64/ArchitectureX8664.h b/src/kits/debugger/arch/x86_64/ArchitectureX8664.h index dfeb2ed886..6d84c908b0 100644 --- a/src/kits/debugger/arch/x86_64/ArchitectureX8664.h +++ b/src/kits/debugger/arch/x86_64/ArchitectureX8664.h @@ -14,6 +14,13 @@ #include "Register.h" +enum { + X86_64_CPU_FEATURE_FLAG_NONE = 0, + X86_64_CPU_FEATURE_FLAG_AVX = 1, + X86_64_CPU_FEATURE_FLAG_AVX512 = 2 +}; + + class SourceLanguage; diff --git a/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp b/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp index 36e4b089b8..00c9946c5a 100644 --- a/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp +++ b/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp @@ -50,50 +50,70 @@ CpuStateX8664::CpuStateX8664(const x86_64_debug_cpu_state& state) SetIntRegister(X86_64_REGISTER_GS, state.gs); SetIntRegister(X86_64_REGISTER_SS, state.ss); - const x86_64_extended_registers& extended = state.extended_registers; + const struct savefpu& extended = state.extended_registers; SetFloatRegister(X86_64_REGISTER_ST0, - (double)(*(long double*)(extended.fp_registers[0].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[0].value))); SetFloatRegister(X86_64_REGISTER_ST1, - (double)(*(long double*)(extended.fp_registers[1].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[1].value))); SetFloatRegister(X86_64_REGISTER_ST2, - (double)(*(long double*)(extended.fp_registers[2].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[2].value))); SetFloatRegister(X86_64_REGISTER_ST3, - (double)(*(long double*)(extended.fp_registers[3].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[3].value))); SetFloatRegister(X86_64_REGISTER_ST4, - (double)(*(long double*)(extended.fp_registers[4].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[4].value))); SetFloatRegister(X86_64_REGISTER_ST5, - (double)(*(long double*)(extended.fp_registers[5].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[5].value))); SetFloatRegister(X86_64_REGISTER_ST6, - (double)(*(long double*)(extended.fp_registers[6].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[6].value))); SetFloatRegister(X86_64_REGISTER_ST7, - (double)(*(long double*)(extended.fp_registers[7].value))); + (double)(*(long double*)(extended.fp_fxsave.fp[7].value))); - SetMMXRegister(X86_64_REGISTER_MM0, extended.mmx_registers[0].value); - SetMMXRegister(X86_64_REGISTER_MM1, extended.mmx_registers[1].value); - SetMMXRegister(X86_64_REGISTER_MM2, extended.mmx_registers[2].value); - SetMMXRegister(X86_64_REGISTER_MM3, extended.mmx_registers[3].value); - SetMMXRegister(X86_64_REGISTER_MM4, extended.mmx_registers[4].value); - SetMMXRegister(X86_64_REGISTER_MM5, extended.mmx_registers[5].value); - SetMMXRegister(X86_64_REGISTER_MM6, extended.mmx_registers[6].value); - SetMMXRegister(X86_64_REGISTER_MM7, extended.mmx_registers[7].value); + SetMMXRegister(X86_64_REGISTER_MM0, extended.fp_fxsave.mmx[0].value); + SetMMXRegister(X86_64_REGISTER_MM1, extended.fp_fxsave.mmx[1].value); + SetMMXRegister(X86_64_REGISTER_MM2, extended.fp_fxsave.mmx[2].value); + SetMMXRegister(X86_64_REGISTER_MM3, extended.fp_fxsave.mmx[3].value); + SetMMXRegister(X86_64_REGISTER_MM4, extended.fp_fxsave.mmx[4].value); + SetMMXRegister(X86_64_REGISTER_MM5, extended.fp_fxsave.mmx[5].value); + SetMMXRegister(X86_64_REGISTER_MM6, extended.fp_fxsave.mmx[6].value); + SetMMXRegister(X86_64_REGISTER_MM7, extended.fp_fxsave.mmx[7].value); - SetXMMRegister(X86_64_REGISTER_XMM0, extended.xmm_registers[0].value); - SetXMMRegister(X86_64_REGISTER_XMM1, extended.xmm_registers[1].value); - SetXMMRegister(X86_64_REGISTER_XMM2, extended.xmm_registers[2].value); - SetXMMRegister(X86_64_REGISTER_XMM3, extended.xmm_registers[3].value); - SetXMMRegister(X86_64_REGISTER_XMM4, extended.xmm_registers[4].value); - SetXMMRegister(X86_64_REGISTER_XMM5, extended.xmm_registers[5].value); - SetXMMRegister(X86_64_REGISTER_XMM6, extended.xmm_registers[6].value); - SetXMMRegister(X86_64_REGISTER_XMM7, extended.xmm_registers[7].value); - SetXMMRegister(X86_64_REGISTER_XMM8, extended.xmm_registers[8].value); - SetXMMRegister(X86_64_REGISTER_XMM9, extended.xmm_registers[9].value); - SetXMMRegister(X86_64_REGISTER_XMM10, extended.xmm_registers[10].value); - SetXMMRegister(X86_64_REGISTER_XMM11, extended.xmm_registers[11].value); - SetXMMRegister(X86_64_REGISTER_XMM12, extended.xmm_registers[12].value); - SetXMMRegister(X86_64_REGISTER_XMM13, extended.xmm_registers[13].value); - SetXMMRegister(X86_64_REGISTER_XMM14, extended.xmm_registers[14].value); - SetXMMRegister(X86_64_REGISTER_XMM15, extended.xmm_registers[15].value); + // The YMM register value is split in two halves in the saved CPU context, + // so we have to reassemble it here. + // TODO check extended.xstate_hdr to see if the YMM values are present at + // all. + SetXMMRegister(X86_64_REGISTER_XMM0, extended.fp_ymm[0].value, + extended.fp_fxsave.xmm[0].value); + SetXMMRegister(X86_64_REGISTER_XMM1, extended.fp_ymm[1].value, + extended.fp_fxsave.xmm[1].value); + SetXMMRegister(X86_64_REGISTER_XMM2, extended.fp_ymm[2].value, + extended.fp_fxsave.xmm[2].value); + SetXMMRegister(X86_64_REGISTER_XMM3, extended.fp_ymm[3].value, + extended.fp_fxsave.xmm[3].value); + SetXMMRegister(X86_64_REGISTER_XMM4, extended.fp_ymm[4].value, + extended.fp_fxsave.xmm[4].value); + SetXMMRegister(X86_64_REGISTER_XMM5, extended.fp_ymm[5].value, + extended.fp_fxsave.xmm[5].value); + SetXMMRegister(X86_64_REGISTER_XMM6, extended.fp_ymm[6].value, + extended.fp_fxsave.xmm[6].value); + SetXMMRegister(X86_64_REGISTER_XMM7, extended.fp_ymm[7].value, + extended.fp_fxsave.xmm[7].value); + SetXMMRegister(X86_64_REGISTER_XMM8, extended.fp_ymm[8].value, + extended.fp_fxsave.xmm[8].value); + SetXMMRegister(X86_64_REGISTER_XMM9, extended.fp_ymm[9].value, + extended.fp_fxsave.xmm[9].value); + SetXMMRegister(X86_64_REGISTER_XMM10, extended.fp_ymm[10].value, + extended.fp_fxsave.xmm[10].value); + SetXMMRegister(X86_64_REGISTER_XMM11, extended.fp_ymm[11].value, + extended.fp_fxsave.xmm[11].value); + SetXMMRegister(X86_64_REGISTER_XMM12, extended.fp_ymm[12].value, + extended.fp_fxsave.xmm[12].value); + SetXMMRegister(X86_64_REGISTER_XMM13, extended.fp_ymm[13].value, + extended.fp_fxsave.xmm[13].value); + SetXMMRegister(X86_64_REGISTER_XMM14, extended.fp_ymm[14].value, + extended.fp_fxsave.xmm[14].value); + SetXMMRegister(X86_64_REGISTER_XMM15, extended.fp_ymm[15].value, + extended.fp_fxsave.xmm[15].value); fInterruptVector = state.vector; } @@ -160,21 +180,21 @@ CpuStateX8664::UpdateDebugState(void* state, size_t size) const x64State->ss = IntRegisterValue(X86_64_REGISTER_SS); for (int32 i = 0; i < 8; i++) { - *(long double*)(x64State->extended_registers.fp_registers[i].value) + *(long double*)(x64State->extended_registers.fp_fxsave.fp[i].value) = (long double)FloatRegisterValue(X86_64_REGISTER_ST0 + i); if (IsRegisterSet(X86_64_REGISTER_MM0 + i)) { - memcpy(&x64State->extended_registers.mmx_registers[i], + memcpy(&x64State->extended_registers.fp_fxsave.mmx[i], &fMMXRegisters[i], sizeof(x86_64_fp_register)); } } for (int32 i = 0; i < 16; i++) { if (IsRegisterSet(X86_64_REGISTER_XMM0 + i)) { - memcpy(&x64State->extended_registers.xmm_registers[i], + memcpy(&x64State->extended_registers.fp_fxsave.xmm[i], &fXMMRegisters[i], sizeof(x86_64_xmm_register)); } else { - memset(&x64State->extended_registers.xmm_registers[i], + memset(&x64State->extended_registers.fp_fxsave.xmm[i], 0, sizeof(x86_64_xmm_register)); } } @@ -372,12 +392,14 @@ CpuStateX8664::XMMRegisterValue(int32 index) const void -CpuStateX8664::SetXMMRegister(int32 index, const uint8* value) +CpuStateX8664::SetXMMRegister(int32 index, const uint8* highValue, const uint8* lowValue) { if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END) return; - memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value, value, + memcpy(&fXMMRegisters[index - X86_64_REGISTER_XMM0].value[0], lowValue, + sizeof(x86_64_xmm_register)); + memcpy(&fXMMRegisters[index - X86_64_REGISTER_XMM0].value[2], highValue, sizeof(x86_64_xmm_register)); fSetRegisters[index] = 1; } diff --git a/src/kits/debugger/arch/x86_64/CpuStateX8664.h b/src/kits/debugger/arch/x86_64/CpuStateX8664.h index da7ca8aa0f..8e4c83721b 100644 --- a/src/kits/debugger/arch/x86_64/CpuStateX8664.h +++ b/src/kits/debugger/arch/x86_64/CpuStateX8664.h @@ -99,6 +99,11 @@ enum { - X86_64_MMX_REGISTER_END) +struct x86_64_ymm_register { + unsigned long value[4]; +}; + + class CpuStateX8664 : public CpuState { public: CpuStateX8664(); @@ -128,6 +133,7 @@ public: uint64 IntRegisterValue(int32 index) const; void SetIntRegister(int32 index, uint64 value); +private: double FloatRegisterValue(int32 index) const; void SetFloatRegister(int32 index, double value); @@ -137,7 +143,7 @@ public: const void* XMMRegisterValue(int32 index) const; void SetXMMRegister(int32 index, - const uint8* value); + const uint8* highValue, const uint8* lowValue); void UnsetRegister(int32 index); @@ -148,7 +154,7 @@ private: uint64 fIntRegisters[X86_64_INT_REGISTER_COUNT]; double fFloatRegisters[X86_64_FP_REGISTER_COUNT]; x86_64_fp_register fMMXRegisters[X86_64_MMX_REGISTER_COUNT]; - x86_64_xmm_register fXMMRegisters[X86_64_XMM_REGISTER_COUNT]; + x86_64_ymm_register fXMMRegisters[X86_64_XMM_REGISTER_COUNT]; RegisterBitSet fSetRegisters; uint64 fInterruptVector; }; diff --git a/src/system/kernel/arch/x86/arch_user_debugger.cpp b/src/system/kernel/arch/x86/arch_user_debugger.cpp index 952c091924..f1d8dcc6b0 100644 --- a/src/system/kernel/arch/x86/arch_user_debugger.cpp +++ b/src/system/kernel/arch/x86/arch_user_debugger.cpp @@ -33,7 +33,9 @@ // TODO: Make those real error codes. -#ifndef __x86_64__ +#ifdef __x86_64__ +extern bool gHasXsave; +#else extern bool gHasSSE; #endif @@ -202,12 +204,21 @@ get_cpu_state(Thread* thread, iframe* frame, debug_cpu_state* cpuState) // For the floating point state to be correct the calling function must // not use these registers (not even indirectly). #ifdef __x86_64__ + memset(&cpuState->extended_registers, 0, + sizeof(cpuState->extended_registers)); + if (frame->fpu != nullptr) { - memcpy(&cpuState->extended_registers, frame->fpu, - sizeof(cpuState->extended_registers)); - } else { - memset(&cpuState->extended_registers, 0, - sizeof(cpuState->extended_registers)); + if (gHasXsave) { + // TODO check the xsave header to know the actual size of the + // register context depending on what is saved. For now we assume + // there is only the YMM AVX registers + memcpy(&cpuState->extended_registers, frame->fpu, + sizeof(cpuState->extended_registers)); + } else { + // Only the "legacy area" saved by fxsave is available + memcpy(&cpuState->extended_registers, frame->fpu, + sizeof(cpuState->extended_registers.fp_fxsave)); + } } #else Thread* thisThread = thread_get_current_thread();