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.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009-2012, Ingo Weinhold, [email protected].
|
||||
* Copyright 2011-2012, Rene Gollent, [email protected].
|
||||
* Copyright 2011-2014, Rene Gollent, [email protected].
|
||||
* 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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<X86_REGISTER_COUNT> 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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<X86_64_REGISTER_COUNT> 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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user