2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Copyright 2011-2013, Rene Gollent, rene@gollent.com.
5 * Distributed under the terms of the MIT License.
8 #include "CpuStateX8664.h"
17 CpuStateX8664::CpuStateX8664()
24 CpuStateX8664::CpuStateX8664(const x86_64_debug_cpu_state
& state
)
29 SetIntRegister(X86_64_REGISTER_RIP
, state
.rip
);
30 SetIntRegister(X86_64_REGISTER_RSP
, state
.rsp
);
31 SetIntRegister(X86_64_REGISTER_RBP
, state
.rbp
);
32 SetIntRegister(X86_64_REGISTER_RAX
, state
.rax
);
33 SetIntRegister(X86_64_REGISTER_RBX
, state
.rbx
);
34 SetIntRegister(X86_64_REGISTER_RCX
, state
.rcx
);
35 SetIntRegister(X86_64_REGISTER_RDX
, state
.rdx
);
36 SetIntRegister(X86_64_REGISTER_RSI
, state
.rsi
);
37 SetIntRegister(X86_64_REGISTER_RDI
, state
.rdi
);
38 SetIntRegister(X86_64_REGISTER_R8
, state
.r8
);
39 SetIntRegister(X86_64_REGISTER_R9
, state
.r9
);
40 SetIntRegister(X86_64_REGISTER_R10
, state
.r10
);
41 SetIntRegister(X86_64_REGISTER_R11
, state
.r11
);
42 SetIntRegister(X86_64_REGISTER_R12
, state
.r12
);
43 SetIntRegister(X86_64_REGISTER_R13
, state
.r13
);
44 SetIntRegister(X86_64_REGISTER_R14
, state
.r14
);
45 SetIntRegister(X86_64_REGISTER_R15
, state
.r15
);
46 SetIntRegister(X86_64_REGISTER_CS
, state
.cs
);
47 SetIntRegister(X86_64_REGISTER_DS
, state
.ds
);
48 SetIntRegister(X86_64_REGISTER_ES
, state
.es
);
49 SetIntRegister(X86_64_REGISTER_FS
, state
.fs
);
50 SetIntRegister(X86_64_REGISTER_GS
, state
.gs
);
51 SetIntRegister(X86_64_REGISTER_SS
, state
.ss
);
53 const x86_64_extended_registers
& extended
= state
.extended_registers
;
55 SetFloatRegister(X86_64_REGISTER_ST0
,
56 (double)(*(long double*)(extended
.fp_registers
[0].value
)));
57 SetFloatRegister(X86_64_REGISTER_ST1
,
58 (double)(*(long double*)(extended
.fp_registers
[1].value
)));
59 SetFloatRegister(X86_64_REGISTER_ST2
,
60 (double)(*(long double*)(extended
.fp_registers
[2].value
)));
61 SetFloatRegister(X86_64_REGISTER_ST3
,
62 (double)(*(long double*)(extended
.fp_registers
[3].value
)));
63 SetFloatRegister(X86_64_REGISTER_ST4
,
64 (double)(*(long double*)(extended
.fp_registers
[4].value
)));
65 SetFloatRegister(X86_64_REGISTER_ST5
,
66 (double)(*(long double*)(extended
.fp_registers
[5].value
)));
67 SetFloatRegister(X86_64_REGISTER_ST6
,
68 (double)(*(long double*)(extended
.fp_registers
[6].value
)));
69 SetFloatRegister(X86_64_REGISTER_ST7
,
70 (double)(*(long double*)(extended
.fp_registers
[7].value
)));
72 SetMMXRegister(X86_64_REGISTER_MM0
, extended
.mmx_registers
[0].value
);
73 SetMMXRegister(X86_64_REGISTER_MM1
, extended
.mmx_registers
[1].value
);
74 SetMMXRegister(X86_64_REGISTER_MM2
, extended
.mmx_registers
[2].value
);
75 SetMMXRegister(X86_64_REGISTER_MM3
, extended
.mmx_registers
[3].value
);
76 SetMMXRegister(X86_64_REGISTER_MM4
, extended
.mmx_registers
[4].value
);
77 SetMMXRegister(X86_64_REGISTER_MM5
, extended
.mmx_registers
[5].value
);
78 SetMMXRegister(X86_64_REGISTER_MM6
, extended
.mmx_registers
[6].value
);
79 SetMMXRegister(X86_64_REGISTER_MM7
, extended
.mmx_registers
[7].value
);
81 SetXMMRegister(X86_64_REGISTER_XMM0
, extended
.xmm_registers
[0].value
);
82 SetXMMRegister(X86_64_REGISTER_XMM1
, extended
.xmm_registers
[1].value
);
83 SetXMMRegister(X86_64_REGISTER_XMM2
, extended
.xmm_registers
[2].value
);
84 SetXMMRegister(X86_64_REGISTER_XMM3
, extended
.xmm_registers
[3].value
);
85 SetXMMRegister(X86_64_REGISTER_XMM4
, extended
.xmm_registers
[4].value
);
86 SetXMMRegister(X86_64_REGISTER_XMM5
, extended
.xmm_registers
[5].value
);
87 SetXMMRegister(X86_64_REGISTER_XMM6
, extended
.xmm_registers
[6].value
);
88 SetXMMRegister(X86_64_REGISTER_XMM7
, extended
.xmm_registers
[7].value
);
89 SetXMMRegister(X86_64_REGISTER_XMM8
, extended
.xmm_registers
[8].value
);
90 SetXMMRegister(X86_64_REGISTER_XMM9
, extended
.xmm_registers
[9].value
);
91 SetXMMRegister(X86_64_REGISTER_XMM10
, extended
.xmm_registers
[10].value
);
92 SetXMMRegister(X86_64_REGISTER_XMM11
, extended
.xmm_registers
[11].value
);
93 SetXMMRegister(X86_64_REGISTER_XMM12
, extended
.xmm_registers
[12].value
);
94 SetXMMRegister(X86_64_REGISTER_XMM13
, extended
.xmm_registers
[13].value
);
95 SetXMMRegister(X86_64_REGISTER_XMM14
, extended
.xmm_registers
[14].value
);
96 SetXMMRegister(X86_64_REGISTER_XMM15
, extended
.xmm_registers
[15].value
);
98 fInterruptVector
= state
.vector
;
102 CpuStateX8664::~CpuStateX8664()
108 CpuStateX8664::Clone(CpuState
*& _clone
) const
110 CpuStateX8664
* newState
= new(std::nothrow
) CpuStateX8664();
111 if (newState
== NULL
)
115 memcpy(newState
->fIntRegisters
, fIntRegisters
, sizeof(fIntRegisters
));
116 memcpy(newState
->fFloatRegisters
, fFloatRegisters
,
117 sizeof(fFloatRegisters
));
118 memcpy(newState
->fMMXRegisters
, fMMXRegisters
, sizeof(fMMXRegisters
));
119 memcpy(newState
->fXMMRegisters
, fXMMRegisters
, sizeof(fXMMRegisters
));
121 newState
->fSetRegisters
= fSetRegisters
;
122 newState
->fInterruptVector
= fInterruptVector
;
131 CpuStateX8664::UpdateDebugState(void* state
, size_t size
) const
133 if (size
!= sizeof(x86_64_debug_cpu_state
))
136 x86_64_debug_cpu_state
* x64State
= (x86_64_debug_cpu_state
*)state
;
138 x64State
->rip
= InstructionPointer();
139 x64State
->rsp
= StackPointer();
140 x64State
->rbp
= StackFramePointer();
141 x64State
->rax
= IntRegisterValue(X86_64_REGISTER_RAX
);
142 x64State
->rbx
= IntRegisterValue(X86_64_REGISTER_RBX
);
143 x64State
->rcx
= IntRegisterValue(X86_64_REGISTER_RCX
);
144 x64State
->rdx
= IntRegisterValue(X86_64_REGISTER_RDX
);
145 x64State
->rsi
= IntRegisterValue(X86_64_REGISTER_RSI
);
146 x64State
->rdi
= IntRegisterValue(X86_64_REGISTER_RDI
);
147 x64State
->r8
= IntRegisterValue(X86_64_REGISTER_R8
);
148 x64State
->r9
= IntRegisterValue(X86_64_REGISTER_R9
);
149 x64State
->r10
= IntRegisterValue(X86_64_REGISTER_R10
);
150 x64State
->r11
= IntRegisterValue(X86_64_REGISTER_R11
);
151 x64State
->r12
= IntRegisterValue(X86_64_REGISTER_R12
);
152 x64State
->r13
= IntRegisterValue(X86_64_REGISTER_R13
);
153 x64State
->r14
= IntRegisterValue(X86_64_REGISTER_R14
);
154 x64State
->r15
= IntRegisterValue(X86_64_REGISTER_R15
);
155 x64State
->cs
= IntRegisterValue(X86_64_REGISTER_CS
);
156 x64State
->ds
= IntRegisterValue(X86_64_REGISTER_DS
);
157 x64State
->es
= IntRegisterValue(X86_64_REGISTER_ES
);
158 x64State
->fs
= IntRegisterValue(X86_64_REGISTER_FS
);
159 x64State
->gs
= IntRegisterValue(X86_64_REGISTER_GS
);
160 x64State
->ss
= IntRegisterValue(X86_64_REGISTER_SS
);
162 for (int32 i
= 0; i
< 8; i
++) {
163 *(long double*)(x64State
->extended_registers
.fp_registers
[i
].value
)
164 = (long double)FloatRegisterValue(X86_64_REGISTER_ST0
+ i
);
166 if (IsRegisterSet(X86_64_REGISTER_MM0
+ i
)) {
167 memcpy(&x64State
->extended_registers
.mmx_registers
[i
],
168 &fMMXRegisters
[i
], sizeof(x86_64_fp_register
));
172 for (int32 i
= 0; i
< 16; i
++) {
173 if (IsRegisterSet(X86_64_REGISTER_XMM0
+ i
)) {
174 memcpy(&x64State
->extended_registers
.xmm_registers
[i
],
175 &fXMMRegisters
[i
], sizeof(x86_64_xmm_register
));
177 memset(&x64State
->extended_registers
.xmm_registers
[i
],
178 0, sizeof(x86_64_xmm_register
));
187 CpuStateX8664::InstructionPointer() const
189 return IsRegisterSet(X86_64_REGISTER_RIP
)
190 ? IntRegisterValue(X86_64_REGISTER_RIP
) : 0;
195 CpuStateX8664::SetInstructionPointer(target_addr_t address
)
197 SetIntRegister(X86_64_REGISTER_RIP
, address
);
202 CpuStateX8664::StackFramePointer() const
204 return IsRegisterSet(X86_64_REGISTER_RBP
)
205 ? IntRegisterValue(X86_64_REGISTER_RBP
) : 0;
210 CpuStateX8664::StackPointer() const
212 return IsRegisterSet(X86_64_REGISTER_RSP
)
213 ? IntRegisterValue(X86_64_REGISTER_RSP
) : 0;
218 CpuStateX8664::GetRegisterValue(const Register
* reg
, BVariant
& _value
) const
220 int32 index
= reg
->Index();
221 if (!IsRegisterSet(index
))
224 if (index
>= X86_64_XMM_REGISTER_END
)
227 if (BVariant::TypeIsInteger(reg
->ValueType())) {
228 if (reg
->BitSize() == 16)
229 _value
.SetTo((uint16
)fIntRegisters
[index
]);
231 _value
.SetTo(fIntRegisters
[index
]);
232 } else if (BVariant::TypeIsFloat(reg
->ValueType())) {
233 index
-= X86_64_REGISTER_ST0
;
234 if (reg
->ValueType() == B_FLOAT_TYPE
)
235 _value
.SetTo((float)fFloatRegisters
[index
]);
237 _value
.SetTo(fFloatRegisters
[index
]);
239 if (index
>= X86_64_REGISTER_MM0
&& index
< X86_64_REGISTER_XMM0
) {
240 index
-= X86_64_REGISTER_MM0
;
241 _value
.SetTo(fMMXRegisters
[index
].value
);
243 index
-= X86_64_REGISTER_XMM0
;
244 _value
.SetTo(fXMMRegisters
[index
].value
);
253 CpuStateX8664::SetRegisterValue(const Register
* reg
, const BVariant
& value
)
255 int32 index
= reg
->Index();
256 if (index
>= X86_64_XMM_REGISTER_END
)
259 if (index
< X86_64_INT_REGISTER_END
)
260 fIntRegisters
[index
] = value
.ToUInt64();
261 else if (index
>= X86_64_REGISTER_ST0
&& index
< X86_64_FP_REGISTER_END
)
262 fFloatRegisters
[index
- X86_64_REGISTER_ST0
] = value
.ToDouble();
263 else if (index
>= X86_64_REGISTER_MM0
&& index
< X86_64_MMX_REGISTER_END
) {
264 if (value
.Size() > sizeof(int64
))
266 memset(&fMMXRegisters
[index
- X86_64_REGISTER_MM0
], 0,
267 sizeof(x86_64_fp_register
));
268 memcpy(fMMXRegisters
[index
- X86_64_REGISTER_MM0
].value
,
269 value
.ToPointer(), value
.Size());
270 } else if (index
>= X86_64_REGISTER_XMM0
271 && index
< X86_64_XMM_REGISTER_END
) {
272 if (value
.Size() > sizeof(x86_64_xmm_register
))
275 memset(&fXMMRegisters
[index
- X86_64_REGISTER_XMM0
], 0,
276 sizeof(x86_64_xmm_register
));
277 memcpy(fXMMRegisters
[index
- X86_64_REGISTER_XMM0
].value
,
278 value
.ToPointer(), value
.Size());
282 fSetRegisters
[index
] = 1;
288 CpuStateX8664::IsRegisterSet(int32 index
) const
290 return index
>= 0 && index
< X86_64_REGISTER_COUNT
&& fSetRegisters
[index
];
295 CpuStateX8664::IntRegisterValue(int32 index
) const
297 if (!IsRegisterSet(index
) || index
>= X86_64_INT_REGISTER_END
)
300 return fIntRegisters
[index
];
305 CpuStateX8664::SetIntRegister(int32 index
, uint64 value
)
307 if (index
< 0 || index
>= X86_64_INT_REGISTER_END
)
310 fIntRegisters
[index
] = value
;
311 fSetRegisters
[index
] = 1;
316 CpuStateX8664::FloatRegisterValue(int32 index
) const
318 if (index
< X86_64_REGISTER_ST0
|| index
>= X86_64_FP_REGISTER_END
319 || !IsRegisterSet(index
)) {
323 return fFloatRegisters
[index
- X86_64_REGISTER_ST0
];
328 CpuStateX8664::SetFloatRegister(int32 index
, double value
)
330 if (index
< X86_64_REGISTER_ST0
|| index
>= X86_64_FP_REGISTER_END
)
333 fFloatRegisters
[index
- X86_64_REGISTER_ST0
] = value
;
334 fSetRegisters
[index
] = 1;
339 CpuStateX8664::MMXRegisterValue(int32 index
) const
341 if (index
< X86_64_REGISTER_MM0
|| index
>= X86_64_MMX_REGISTER_END
342 || !IsRegisterSet(index
)) {
346 return fMMXRegisters
[index
- X86_64_REGISTER_MM0
].value
;
351 CpuStateX8664::SetMMXRegister(int32 index
, const uint8
* value
)
353 if (index
< X86_64_REGISTER_MM0
|| index
>= X86_64_MMX_REGISTER_END
)
356 memcpy(fMMXRegisters
[index
- X86_64_REGISTER_MM0
].value
, value
,
358 fSetRegisters
[index
] = 1;
363 CpuStateX8664::XMMRegisterValue(int32 index
) const
365 if (index
< X86_64_REGISTER_XMM0
|| index
>= X86_64_XMM_REGISTER_END
366 || !IsRegisterSet(index
)) {
370 return fXMMRegisters
[index
- X86_64_REGISTER_XMM0
].value
;
375 CpuStateX8664::SetXMMRegister(int32 index
, const uint8
* value
)
377 if (index
< X86_64_REGISTER_XMM0
|| index
>= X86_64_XMM_REGISTER_END
)
380 memcpy(fXMMRegisters
[index
- X86_64_REGISTER_XMM0
].value
, value
,
381 sizeof(x86_64_xmm_register
));
382 fSetRegisters
[index
] = 1;
387 CpuStateX8664::UnsetRegister(int32 index
)
389 if (index
< 0 || index
>= X86_64_REGISTER_COUNT
)
392 fSetRegisters
[index
] = 0;