From a5fbc88f439ac3333dcce949e12bd6633b454e6b Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 4 Jan 2015 19:45:11 -0500 Subject: [PATCH] Debugger: Expose more x86{-64} registers. ArchitectureX86{-64}: - Implement helper functions for adding floating point and SIMD registers. - Add st0-st7 and mm0-mm7 to the list of exposed x86{-64} registers, along with their DWARF unwind mappings. - Add xmm0-xmm7 for x86, and xmm0-xmm15 for x86-64. CpuStateX86{-64}: - Implement helper functions for setting/retrieving floating point and SIMD register values. - Fill in values for st*, mm* and xmm* from debug_cpu_state. --- .../debugger/arch/x86/ArchitectureX86.cpp | 81 +++++++-- src/apps/debugger/arch/x86/ArchitectureX86.h | 7 +- src/apps/debugger/arch/x86/CpuStateX86.cpp | 158 +++++++++++++++- src/apps/debugger/arch/x86/CpuStateX86.h | 61 ++++++- .../arch/x86_64/ArchitectureX8664.cpp | 107 ++++++++++- .../debugger/arch/x86_64/ArchitectureX8664.h | 7 +- .../debugger/arch/x86_64/CpuStateX8664.cpp | 170 +++++++++++++++++- src/apps/debugger/arch/x86_64/CpuStateX8664.h | 69 ++++++- 8 files changed, 625 insertions(+), 35 deletions(-) diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index b0bec17137..4a000608f6 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2012, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -41,18 +41,32 @@ static const int32 kFromDwarfRegisters[] = { X86_REGISTER_EIP, -1, // eflags -1, // trap number - -1, // st(0) - -1, // st(1) - -1, // st(2) - -1, // st(3) - -1, // st(4) - -1, // st(5) - -1, // st(6) - -1, // st(7) + X86_REGISTER_ST0, + X86_REGISTER_ST1, + X86_REGISTER_ST2, + X86_REGISTER_ST3, + X86_REGISTER_ST4, + X86_REGISTER_ST5, + X86_REGISTER_ST6, + X86_REGISTER_ST7, -1, // ? -1, // ? - -1, -1, -1, -1, -1, -1, -1, -1, // SSE - -1, -1, -1, -1, -1, -1, -1, -1 // MMX + X86_REGISTER_XMM0, + X86_REGISTER_XMM1, + X86_REGISTER_XMM2, + X86_REGISTER_XMM3, + X86_REGISTER_XMM4, + X86_REGISTER_XMM5, + X86_REGISTER_XMM6, + X86_REGISTER_XMM7, + X86_REGISTER_MM0, + X86_REGISTER_MM1, + X86_REGISTER_MM2, + X86_REGISTER_MM3, + X86_REGISTER_MM4, + X86_REGISTER_MM5, + X86_REGISTER_MM6, + X86_REGISTER_MM7, }; static const int32 kFromDwarfRegisterCount = sizeof(kFromDwarfRegisters) / 4; @@ -169,6 +183,34 @@ ArchitectureX86::Init() REGISTER_TYPE_SPECIAL_PURPOSE, true); _AddIntegerRegister(X86_REGISTER_SS, "ss", B_UINT16_TYPE, REGISTER_TYPE_SPECIAL_PURPOSE, true); + + _AddFPRegister(X86_REGISTER_ST0, "st0"); + _AddFPRegister(X86_REGISTER_ST1, "st1"); + _AddFPRegister(X86_REGISTER_ST2, "st2"); + _AddFPRegister(X86_REGISTER_ST3, "st3"); + _AddFPRegister(X86_REGISTER_ST4, "st4"); + _AddFPRegister(X86_REGISTER_ST5, "st5"); + _AddFPRegister(X86_REGISTER_ST6, "st6"); + _AddFPRegister(X86_REGISTER_ST7, "st7"); + + _AddSIMDRegister(X86_REGISTER_MM0, "mm0", sizeof(uint64)); + _AddSIMDRegister(X86_REGISTER_MM1, "mm1", sizeof(uint64)); + _AddSIMDRegister(X86_REGISTER_MM2, "mm2", sizeof(uint64)); + _AddSIMDRegister(X86_REGISTER_MM3, "mm3", sizeof(uint64)); + _AddSIMDRegister(X86_REGISTER_MM4, "mm4", sizeof(uint64)); + _AddSIMDRegister(X86_REGISTER_MM5, "mm5", sizeof(uint64)); + _AddSIMDRegister(X86_REGISTER_MM6, "mm6", sizeof(uint64)); + _AddSIMDRegister(X86_REGISTER_MM7, "mm7", sizeof(uint64)); + + _AddSIMDRegister(X86_REGISTER_XMM0, "xmm0", sizeof(x86_xmm_register)); + _AddSIMDRegister(X86_REGISTER_XMM1, "xmm1", sizeof(x86_xmm_register)); + _AddSIMDRegister(X86_REGISTER_XMM2, "xmm2", sizeof(x86_xmm_register)); + _AddSIMDRegister(X86_REGISTER_XMM3, "xmm3", sizeof(x86_xmm_register)); + _AddSIMDRegister(X86_REGISTER_XMM4, "xmm4", sizeof(x86_xmm_register)); + _AddSIMDRegister(X86_REGISTER_XMM5, "xmm5", sizeof(x86_xmm_register)); + _AddSIMDRegister(X86_REGISTER_XMM6, "xmm6", sizeof(x86_xmm_register)); + _AddSIMDRegister(X86_REGISTER_XMM7, "xmm7", sizeof(x86_xmm_register)); + } catch (std::bad_alloc) { return B_NO_MEMORY; } @@ -707,6 +749,23 @@ ArchitectureX86::_AddIntegerRegister(int32 index, const char* name, } +void +ArchitectureX86::_AddFPRegister(int32 index, const char* name) +{ + _AddRegister(index, name, 8 * BVariant::SizeOfType(B_DOUBLE_TYPE), + B_DOUBLE_TYPE, REGISTER_TYPE_GENERAL_PURPOSE, true); +} + + +void +ArchitectureX86::_AddSIMDRegister(int32 index, const char* name, + uint32 byteSize) +{ + _AddRegister(index, name, byteSize * 8, B_RAW_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, true); +} + + bool ArchitectureX86::_HasFunctionPrologue(FunctionDebugInfo* function) const { diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index a672fb8a51..c0e6244f9f 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.h +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2013, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef ARCHITECTURE_X86_H @@ -86,7 +86,10 @@ private: void _AddIntegerRegister(int32 index, const char* name, uint32 valueType, register_type type, bool calleePreserved); - + void _AddFPRegister(int32 index, + const char* name); + void _AddSIMDRegister(int32 index, + const char* name, uint32 byteSize); bool _HasFunctionPrologue( FunctionDebugInfo* function) const; diff --git a/src/apps/debugger/arch/x86/CpuStateX86.cpp b/src/apps/debugger/arch/x86/CpuStateX86.cpp index 9ec0e156af..1b8f0d0dab 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.cpp +++ b/src/apps/debugger/arch/x86/CpuStateX86.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2013, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -42,6 +42,42 @@ CpuStateX86::CpuStateX86(const x86_debug_cpu_state& state) SetIntRegister(X86_REGISTER_GS, state.gs); SetIntRegister(X86_REGISTER_SS, state.user_ss); + const x86_extended_registers& extended = state.extended_registers; + SetFloatRegister(X86_REGISTER_ST0, + (double)(*(long double*)(extended.fp_registers[0].value))); + SetFloatRegister(X86_REGISTER_ST1, + (double)(*(long double*)(extended.fp_registers[1].value))); + SetFloatRegister(X86_REGISTER_ST2, + (double)(*(long double*)(extended.fp_registers[2].value))); + SetFloatRegister(X86_REGISTER_ST3, + (double)(*(long double*)(extended.fp_registers[3].value))); + SetFloatRegister(X86_REGISTER_ST4, + (double)(*(long double*)(extended.fp_registers[4].value))); + SetFloatRegister(X86_REGISTER_ST5, + (double)(*(long double*)(extended.fp_registers[5].value))); + SetFloatRegister(X86_REGISTER_ST6, + (double)(*(long double*)(extended.fp_registers[6].value))); + SetFloatRegister(X86_REGISTER_ST7, + (double)(*(long double*)(extended.fp_registers[7].value))); + + SetMMXRegister(X86_REGISTER_MM0, extended.mmx_registers[0].value); + SetMMXRegister(X86_REGISTER_MM1, extended.mmx_registers[1].value); + SetMMXRegister(X86_REGISTER_MM2, extended.mmx_registers[2].value); + SetMMXRegister(X86_REGISTER_MM3, extended.mmx_registers[3].value); + SetMMXRegister(X86_REGISTER_MM4, extended.mmx_registers[4].value); + SetMMXRegister(X86_REGISTER_MM5, extended.mmx_registers[5].value); + SetMMXRegister(X86_REGISTER_MM6, extended.mmx_registers[6].value); + SetMMXRegister(X86_REGISTER_MM7, extended.mmx_registers[7].value); + + SetXMMRegister(X86_REGISTER_XMM0, extended.xmm_registers[0].value); + SetXMMRegister(X86_REGISTER_XMM1, extended.xmm_registers[1].value); + SetXMMRegister(X86_REGISTER_XMM2, extended.xmm_registers[2].value); + SetXMMRegister(X86_REGISTER_XMM3, extended.xmm_registers[3].value); + SetXMMRegister(X86_REGISTER_XMM4, extended.xmm_registers[4].value); + SetXMMRegister(X86_REGISTER_XMM5, extended.xmm_registers[5].value); + SetXMMRegister(X86_REGISTER_XMM6, extended.xmm_registers[6].value); + SetXMMRegister(X86_REGISTER_XMM7, extended.xmm_registers[7].value); + fInterruptVector = state.vector; } @@ -60,6 +96,11 @@ CpuStateX86::Clone(CpuState*& _clone) const memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters)); + memcpy(newState->fFloatRegisters, fFloatRegisters, + sizeof(fFloatRegisters)); + memcpy(newState->fMMXRegisters, fMMXRegisters, sizeof(fMMXRegisters)); + memcpy(newState->fXMMRegisters, fXMMRegisters, sizeof(fXMMRegisters)); + newState->fSetRegisters = fSetRegisters; newState->fInterruptVector = fInterruptVector; @@ -94,6 +135,24 @@ CpuStateX86::UpdateDebugState(void* state, size_t size) const x86State->user_ss = IntRegisterValue(X86_REGISTER_SS); x86State->vector = fInterruptVector; + for (int32 i = 0; i < 8; i++) { + *(long double*)(x86State->extended_registers.fp_registers[i].value) + = (long double)FloatRegisterValue(X86_REGISTER_ST0 + i); + + if (IsRegisterSet(X86_REGISTER_MM0 + i)) { + memcpy(&x86State->extended_registers.mmx_registers[i], + &fMMXRegisters[i], sizeof(x86_fp_register)); + } + + if (IsRegisterSet(X86_REGISTER_XMM0 + i)) { + memcpy(&x86State->extended_registers.xmm_registers[i], + &fXMMRegisters[i], sizeof(x86_xmm_register)); + } else { + memset(&x86State->extended_registers.xmm_registers[i], + 0, sizeof(x86_xmm_register)); + } + } + return B_OK; } @@ -136,13 +195,29 @@ CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value) const if (!IsRegisterSet(index)) return false; - if (index >= X86_INT_REGISTER_END) + if (index >= X86_XMM_REGISTER_END) return false; - if (reg->BitSize() == 16) - _value.SetTo((uint16)fIntRegisters[index]); - else - _value.SetTo(fIntRegisters[index]); + if (BVariant::TypeIsInteger(reg->ValueType())) { + if (reg->BitSize() == 16) + _value.SetTo((uint16)fIntRegisters[index]); + else + _value.SetTo(fIntRegisters[index]); + } else if (BVariant::TypeIsFloat(reg->ValueType())) { + index -= X86_REGISTER_ST0; + if (reg->ValueType() == B_FLOAT_TYPE) + _value.SetTo((float)fFloatRegisters[index]); + else + _value.SetTo(fFloatRegisters[index]); + } else { + if (index >= X86_REGISTER_MM0 && index < X86_REGISTER_XMM0) { + index -= X86_REGISTER_MM0; + _value.SetTo(fMMXRegisters[index].value); + } else { + index -= X86_REGISTER_XMM0; + _value.SetTo(fXMMRegisters[index].value); + } + } return true; } @@ -189,6 +264,77 @@ CpuStateX86::SetIntRegister(int32 index, uint32 value) } +double +CpuStateX86::FloatRegisterValue(int32 index) const +{ + if (index < X86_REGISTER_ST0 || index >= X86_FP_REGISTER_END + || !IsRegisterSet(index)) { + return 0.0; + } + + return fFloatRegisters[index - X86_REGISTER_ST0]; +} + + +void +CpuStateX86::SetFloatRegister(int32 index, double value) +{ + if (index < X86_REGISTER_ST0 || index >= X86_FP_REGISTER_END) + return; + + fFloatRegisters[index - X86_REGISTER_ST0] = value; + fSetRegisters[index] = 1; +} + + +const void* +CpuStateX86::MMXRegisterValue(int32 index) const +{ + if (index < X86_REGISTER_MM0 || index >= X86_MMX_REGISTER_END + || !IsRegisterSet(index)) { + return 0; + } + + return fMMXRegisters[index - X86_REGISTER_MM0].value; +} + + +void +CpuStateX86::SetMMXRegister(int32 index, const uint8* value) +{ + if (index < X86_REGISTER_MM0 || index >= X86_MMX_REGISTER_END) + return; + + memcpy(fMMXRegisters[index - X86_REGISTER_MM0].value, value, + sizeof(uint64)); + fSetRegisters[index] = 1; +} + + +const void* +CpuStateX86::XMMRegisterValue(int32 index) const +{ + if (index < X86_REGISTER_XMM0 || index >= X86_XMM_REGISTER_END + || !IsRegisterSet(index)) { + return NULL; + } + + return fXMMRegisters[index - X86_REGISTER_XMM0].value; +} + + +void +CpuStateX86::SetXMMRegister(int32 index, const uint8* value) +{ + if (index < X86_REGISTER_XMM0 || index >= X86_XMM_REGISTER_END) + return; + + memcpy(fXMMRegisters[index - X86_REGISTER_XMM0].value, value, + sizeof(x86_xmm_register)); + fSetRegisters[index] = 1; +} + + void CpuStateX86::UnsetRegister(int32 index) { diff --git a/src/apps/debugger/arch/x86/CpuStateX86.h b/src/apps/debugger/arch/x86/CpuStateX86.h index d32e68c081..a87cc3064a 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.h +++ b/src/apps/debugger/arch/x86/CpuStateX86.h @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2013, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef CPU_STATE_X86_H @@ -34,10 +34,50 @@ enum { X86_REGISTER_SS, X86_INT_REGISTER_END, + + X86_REGISTER_ST0, + X86_REGISTER_ST1, + X86_REGISTER_ST2, + X86_REGISTER_ST3, + X86_REGISTER_ST4, + X86_REGISTER_ST5, + X86_REGISTER_ST6, + X86_REGISTER_ST7, + + X86_FP_REGISTER_END, + + X86_REGISTER_MM0, + X86_REGISTER_MM1, + X86_REGISTER_MM2, + X86_REGISTER_MM3, + X86_REGISTER_MM4, + X86_REGISTER_MM5, + X86_REGISTER_MM6, + X86_REGISTER_MM7, + + X86_MMX_REGISTER_END, + + X86_REGISTER_XMM0, + X86_REGISTER_XMM1, + X86_REGISTER_XMM2, + X86_REGISTER_XMM3, + X86_REGISTER_XMM4, + X86_REGISTER_XMM5, + X86_REGISTER_XMM6, + X86_REGISTER_XMM7, + + X86_XMM_REGISTER_END, + X86_REGISTER_COUNT }; +#define X86_INT_REGISTER_COUNT X86_INT_REGISTER_END +#define X86_FP_REGISTER_COUNT (X86_FP_REGISTER_END - X86_INT_REGISTER_END) +#define X86_MMX_REGISTER_COUNT (X86_MMX_REGISTER_END - X86_FP_REGISTER_END) +#define X86_XMM_REGISTER_COUNT (X86_XMM_REGISTER_END - X86_MMX_REGISTER_END) + + class CpuStateX86 : public CpuState { public: CpuStateX86(); @@ -63,15 +103,32 @@ public: { return fInterruptVector; } bool IsRegisterSet(int32 index) const; + uint32 IntRegisterValue(int32 index) const; void SetIntRegister(int32 index, uint32 value); + + double FloatRegisterValue(int32 index) const; + void SetFloatRegister(int32 index, double value); + + const void* MMXRegisterValue(int32 index) const; + void SetMMXRegister(int32 index, + const uint8* value); + + const void* XMMRegisterValue(int32 index) const; + void SetXMMRegister(int32 index, + const uint8* value); + void UnsetRegister(int32 index); private: typedef std::bitset RegisterBitSet; private: - uint32 fIntRegisters[X86_REGISTER_COUNT]; + uint32 fIntRegisters[X86_INT_REGISTER_COUNT]; + double fFloatRegisters[X86_FP_REGISTER_COUNT]; + x86_fp_register fMMXRegisters[X86_MMX_REGISTER_COUNT]; + x86_xmm_register fXMMRegisters[X86_XMM_REGISTER_COUNT]; + RegisterBitSet fSetRegisters; uint32 fInterruptVector; }; diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp index 73bd4a5651..2581cd1682 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp @@ -1,7 +1,7 @@ /* * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2013, Rene Gollent, rene@gollent.com. + * Copyright 2011-2015, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -48,10 +48,38 @@ static const int32 kFromDwarfRegisters[] = { X86_64_REGISTER_R14, X86_64_REGISTER_R15, X86_64_REGISTER_RIP, - -1, -1, -1, -1, -1, -1, -1, -1, // xmm0-xmm7 - -1, -1, -1, -1, -1, -1, -1, -1, // xmm8-xmm15 - -1, -1, -1, -1, -1, -1, -1, -1, // st0-st7 - -1, -1, -1, -1, -1, -1, -1, -1, // mm0-mm7 + X86_64_REGISTER_XMM0, + X86_64_REGISTER_XMM1, + X86_64_REGISTER_XMM2, + X86_64_REGISTER_XMM3, + X86_64_REGISTER_XMM4, + X86_64_REGISTER_XMM5, + X86_64_REGISTER_XMM6, + X86_64_REGISTER_XMM7, + X86_64_REGISTER_XMM8, + X86_64_REGISTER_XMM9, + X86_64_REGISTER_XMM10, + X86_64_REGISTER_XMM11, + X86_64_REGISTER_XMM12, + X86_64_REGISTER_XMM13, + X86_64_REGISTER_XMM14, + X86_64_REGISTER_XMM15, + X86_64_REGISTER_ST0, + X86_64_REGISTER_ST1, + X86_64_REGISTER_ST2, + X86_64_REGISTER_ST3, + X86_64_REGISTER_ST4, + X86_64_REGISTER_ST5, + X86_64_REGISTER_ST6, + X86_64_REGISTER_ST7, + X86_64_REGISTER_MM0, + X86_64_REGISTER_MM1, + X86_64_REGISTER_MM2, + X86_64_REGISTER_MM3, + X86_64_REGISTER_MM4, + X86_64_REGISTER_MM5, + X86_64_REGISTER_MM6, + X86_64_REGISTER_MM7, -1, // rflags X86_64_REGISTER_ES, X86_64_REGISTER_CS, @@ -193,6 +221,58 @@ ArchitectureX8664::Init() REGISTER_TYPE_SPECIAL_PURPOSE, true); _AddIntegerRegister(X86_64_REGISTER_SS, "ss", B_UINT16_TYPE, REGISTER_TYPE_SPECIAL_PURPOSE, true); + + _AddFPRegister(X86_64_REGISTER_ST0, "st0"); + _AddFPRegister(X86_64_REGISTER_ST1, "st1"); + _AddFPRegister(X86_64_REGISTER_ST2, "st2"); + _AddFPRegister(X86_64_REGISTER_ST3, "st3"); + _AddFPRegister(X86_64_REGISTER_ST4, "st4"); + _AddFPRegister(X86_64_REGISTER_ST5, "st5"); + _AddFPRegister(X86_64_REGISTER_ST6, "st6"); + _AddFPRegister(X86_64_REGISTER_ST7, "st7"); + + _AddSIMDRegister(X86_64_REGISTER_MM0, "mm0", sizeof(uint64)); + _AddSIMDRegister(X86_64_REGISTER_MM1, "mm1", sizeof(uint64)); + _AddSIMDRegister(X86_64_REGISTER_MM2, "mm2", sizeof(uint64)); + _AddSIMDRegister(X86_64_REGISTER_MM3, "mm3", sizeof(uint64)); + _AddSIMDRegister(X86_64_REGISTER_MM4, "mm4", sizeof(uint64)); + _AddSIMDRegister(X86_64_REGISTER_MM5, "mm5", sizeof(uint64)); + _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)); + } catch (std::bad_alloc) { return B_NO_MEMORY; } @@ -729,6 +809,23 @@ ArchitectureX8664::_AddIntegerRegister(int32 index, const char* name, } +void +ArchitectureX8664::_AddFPRegister(int32 index, const char* name) +{ + _AddRegister(index, name, 8 * BVariant::SizeOfType(B_DOUBLE_TYPE), + B_DOUBLE_TYPE, REGISTER_TYPE_GENERAL_PURPOSE, true); +} + + +void +ArchitectureX8664::_AddSIMDRegister(int32 index, const char* name, + uint32 byteSize) +{ + _AddRegister(index, name, byteSize * 8, B_RAW_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, true); +} + + bool ArchitectureX8664::_HasFunctionPrologue(FunctionDebugInfo* function) const { diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.h b/src/apps/debugger/arch/x86_64/ArchitectureX8664.h index a5d2775d85..33da8bc6e7 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.h +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.h @@ -1,7 +1,7 @@ /* * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2012, Rene Gollent, rene@gollent.com. + * Copyright 2011-2015, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef ARCHITECTURE_X86_64_H @@ -86,7 +86,10 @@ private: void _AddIntegerRegister(int32 index, const char* name, uint32 valueType, register_type type, bool calleePreserved); - + void _AddFPRegister(int32 index, + const char* name); + void _AddSIMDRegister(int32 index, + const char* name, uint32 byteSize); bool _HasFunctionPrologue( FunctionDebugInfo* function) const; private: diff --git a/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp b/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp index 13e45d30a8..c36edaf281 100644 --- a/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp +++ b/src/apps/debugger/arch/x86_64/CpuStateX8664.cpp @@ -50,6 +50,51 @@ 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; + + SetFloatRegister(X86_64_REGISTER_ST0, + (double)(*(long double*)(extended.fp_registers[0].value))); + SetFloatRegister(X86_64_REGISTER_ST1, + (double)(*(long double*)(extended.fp_registers[1].value))); + SetFloatRegister(X86_64_REGISTER_ST2, + (double)(*(long double*)(extended.fp_registers[2].value))); + SetFloatRegister(X86_64_REGISTER_ST3, + (double)(*(long double*)(extended.fp_registers[3].value))); + SetFloatRegister(X86_64_REGISTER_ST4, + (double)(*(long double*)(extended.fp_registers[4].value))); + SetFloatRegister(X86_64_REGISTER_ST5, + (double)(*(long double*)(extended.fp_registers[5].value))); + SetFloatRegister(X86_64_REGISTER_ST6, + (double)(*(long double*)(extended.fp_registers[6].value))); + SetFloatRegister(X86_64_REGISTER_ST7, + (double)(*(long double*)(extended.fp_registers[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); + + 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); + fInterruptVector = state.vector; } @@ -68,7 +113,13 @@ CpuStateX8664::Clone(CpuState*& _clone) const memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters)); + memcpy(newState->fFloatRegisters, fFloatRegisters, + sizeof(fFloatRegisters)); + memcpy(newState->fMMXRegisters, fMMXRegisters, sizeof(fMMXRegisters)); + memcpy(newState->fXMMRegisters, fXMMRegisters, sizeof(fXMMRegisters)); + newState->fSetRegisters = fSetRegisters; + newState->fInterruptVector = fInterruptVector; _clone = newState; @@ -108,6 +159,26 @@ CpuStateX8664::UpdateDebugState(void* state, size_t size) const x64State->gs = IntRegisterValue(X86_64_REGISTER_GS); 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)FloatRegisterValue(X86_64_REGISTER_ST0 + i); + + if (IsRegisterSet(X86_64_REGISTER_MM0 + i)) { + memcpy(&x64State->extended_registers.mmx_registers[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], + &fXMMRegisters[i], sizeof(x86_64_xmm_register)); + } else { + memset(&x64State->extended_registers.xmm_registers[i], + 0, sizeof(x86_64_xmm_register)); + } + } + return B_OK; } @@ -150,13 +221,29 @@ CpuStateX8664::GetRegisterValue(const Register* reg, BVariant& _value) const if (!IsRegisterSet(index)) return false; - if (index >= X86_64_INT_REGISTER_END) + if (index >= X86_64_XMM_REGISTER_END) return false; - if (reg->BitSize() == 16) - _value.SetTo((uint16)fIntRegisters[index]); - else - _value.SetTo(fIntRegisters[index]); + if (BVariant::TypeIsInteger(reg->ValueType())) { + if (reg->BitSize() == 16) + _value.SetTo((uint16)fIntRegisters[index]); + else + _value.SetTo(fIntRegisters[index]); + } else if (BVariant::TypeIsFloat(reg->ValueType())) { + index -= X86_64_REGISTER_ST0; + if (reg->ValueType() == B_FLOAT_TYPE) + _value.SetTo((float)fFloatRegisters[index]); + else + _value.SetTo(fFloatRegisters[index]); + } else { + if (index >= X86_64_REGISTER_MM0 && index < X86_64_REGISTER_XMM0) { + index -= X86_64_REGISTER_MM0; + _value.SetTo(fMMXRegisters[index].value); + } else { + index -= X86_64_REGISTER_XMM0; + _value.SetTo(fXMMRegisters[index].value); + } + } return true; } @@ -166,7 +253,7 @@ bool CpuStateX8664::SetRegisterValue(const Register* reg, const BVariant& value) { int32 index = reg->Index(); - if (index >= X86_64_INT_REGISTER_END) + if (index >= X86_64_XMM_REGISTER_END) return false; fIntRegisters[index] = value.ToUInt64(); @@ -203,6 +290,77 @@ CpuStateX8664::SetIntRegister(int32 index, uint64 value) } +double +CpuStateX8664::FloatRegisterValue(int32 index) const +{ + if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END + || !IsRegisterSet(index)) { + return 0.0; + } + + return fFloatRegisters[index - X86_64_REGISTER_ST0]; +} + + +void +CpuStateX8664::SetFloatRegister(int32 index, double value) +{ + if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END) + return; + + fFloatRegisters[index - X86_64_REGISTER_ST0] = value; + fSetRegisters[index] = 1; +} + + +const void* +CpuStateX8664::MMXRegisterValue(int32 index) const +{ + if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END + || !IsRegisterSet(index)) { + return 0; + } + + return fMMXRegisters[index - X86_64_REGISTER_MM0].value; +} + + +void +CpuStateX8664::SetMMXRegister(int32 index, const uint8* value) +{ + if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END) + return; + + memcpy(fMMXRegisters[index - X86_64_REGISTER_MM0].value, value, + sizeof(uint64)); + fSetRegisters[index] = 1; +} + + +const void* +CpuStateX8664::XMMRegisterValue(int32 index) const +{ + if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END + || !IsRegisterSet(index)) { + return NULL; + } + + return fXMMRegisters[index - X86_64_REGISTER_XMM0].value; +} + + +void +CpuStateX8664::SetXMMRegister(int32 index, const uint8* value) +{ + if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END) + return; + + memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value, value, + sizeof(x86_64_xmm_register)); + fSetRegisters[index] = 1; +} + + void CpuStateX8664::UnsetRegister(int32 index) { diff --git a/src/apps/debugger/arch/x86_64/CpuStateX8664.h b/src/apps/debugger/arch/x86_64/CpuStateX8664.h index e30c588f66..da7ca8aa0f 100644 --- a/src/apps/debugger/arch/x86_64/CpuStateX8664.h +++ b/src/apps/debugger/arch/x86_64/CpuStateX8664.h @@ -44,10 +44,61 @@ enum { X86_64_REGISTER_SS, X86_64_INT_REGISTER_END, + + X86_64_REGISTER_ST0, + X86_64_REGISTER_ST1, + X86_64_REGISTER_ST2, + X86_64_REGISTER_ST3, + X86_64_REGISTER_ST4, + X86_64_REGISTER_ST5, + X86_64_REGISTER_ST6, + X86_64_REGISTER_ST7, + + X86_64_FP_REGISTER_END, + + X86_64_REGISTER_MM0, + X86_64_REGISTER_MM1, + X86_64_REGISTER_MM2, + X86_64_REGISTER_MM3, + X86_64_REGISTER_MM4, + X86_64_REGISTER_MM5, + X86_64_REGISTER_MM6, + X86_64_REGISTER_MM7, + + X86_64_MMX_REGISTER_END, + + X86_64_REGISTER_XMM0, + X86_64_REGISTER_XMM1, + X86_64_REGISTER_XMM2, + X86_64_REGISTER_XMM3, + X86_64_REGISTER_XMM4, + X86_64_REGISTER_XMM5, + X86_64_REGISTER_XMM6, + X86_64_REGISTER_XMM7, + X86_64_REGISTER_XMM8, + X86_64_REGISTER_XMM9, + X86_64_REGISTER_XMM10, + X86_64_REGISTER_XMM11, + X86_64_REGISTER_XMM12, + X86_64_REGISTER_XMM13, + X86_64_REGISTER_XMM14, + X86_64_REGISTER_XMM15, + + X86_64_XMM_REGISTER_END, + X86_64_REGISTER_COUNT }; +#define X86_64_INT_REGISTER_COUNT X86_64_INT_REGISTER_END +#define X86_64_FP_REGISTER_COUNT (X86_64_FP_REGISTER_END \ + - X86_64_INT_REGISTER_END) +#define X86_64_MMX_REGISTER_COUNT (X86_64_MMX_REGISTER_END \ + - X86_64_FP_REGISTER_END) +#define X86_64_XMM_REGISTER_COUNT (X86_64_XMM_REGISTER_END \ + - X86_64_MMX_REGISTER_END) + + class CpuStateX8664 : public CpuState { public: CpuStateX8664(); @@ -73,15 +124,31 @@ public: { return fInterruptVector; } bool IsRegisterSet(int32 index) const; + uint64 IntRegisterValue(int32 index) const; void SetIntRegister(int32 index, uint64 value); + + double FloatRegisterValue(int32 index) const; + void SetFloatRegister(int32 index, double value); + + const void* MMXRegisterValue(int32 index) const; + void SetMMXRegister(int32 index, + const uint8* value); + + const void* XMMRegisterValue(int32 index) const; + void SetXMMRegister(int32 index, + const uint8* value); + void UnsetRegister(int32 index); private: typedef std::bitset RegisterBitSet; private: - uint64 fIntRegisters[X86_64_REGISTER_COUNT]; + 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]; RegisterBitSet fSetRegisters; uint64 fInterruptVector; };