1/*
2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Copyright 2011, Rene Gollent, rene@gollent.com.
5 * Distributed under the terms of the MIT License.
6 */
7
8#include "CpuStateX8664.h"
9
10#include "Register.h"
11
12
13CpuStateX8664::CpuStateX8664()
14	:
15	fSetRegisters()
16{
17}
18
19
20CpuStateX8664::CpuStateX8664(const x86_64_debug_cpu_state& state)
21	:
22	fSetRegisters()
23{
24	SetIntRegister(X86_64_REGISTER_RIP, state.rip);
25	SetIntRegister(X86_64_REGISTER_RSP, state.rsp);
26	SetIntRegister(X86_64_REGISTER_RBP, state.rbp);
27	SetIntRegister(X86_64_REGISTER_RAX, state.rax);
28	SetIntRegister(X86_64_REGISTER_RBX, state.rbx);
29	SetIntRegister(X86_64_REGISTER_RCX, state.rcx);
30	SetIntRegister(X86_64_REGISTER_RDX, state.rdx);
31	SetIntRegister(X86_64_REGISTER_RSI, state.rsi);
32	SetIntRegister(X86_64_REGISTER_RDI, state.rdi);
33	SetIntRegister(X86_64_REGISTER_R8, state.r8);
34	SetIntRegister(X86_64_REGISTER_R9, state.r9);
35	SetIntRegister(X86_64_REGISTER_R10, state.r10);
36	SetIntRegister(X86_64_REGISTER_R11, state.r11);
37	SetIntRegister(X86_64_REGISTER_R12, state.r12);
38	SetIntRegister(X86_64_REGISTER_R13, state.r13);
39	SetIntRegister(X86_64_REGISTER_R14, state.r14);
40	SetIntRegister(X86_64_REGISTER_R15, state.r15);
41	SetIntRegister(X86_64_REGISTER_CS, state.cs);
42	SetIntRegister(X86_64_REGISTER_DS, state.ds);
43	SetIntRegister(X86_64_REGISTER_ES, state.es);
44	SetIntRegister(X86_64_REGISTER_FS, state.fs);
45	SetIntRegister(X86_64_REGISTER_GS, state.gs);
46	SetIntRegister(X86_64_REGISTER_SS, state.ss);
47}
48
49
50CpuStateX8664::~CpuStateX8664()
51{
52}
53
54
55target_addr_t
56CpuStateX8664::InstructionPointer() const
57{
58	return IsRegisterSet(X86_64_REGISTER_RIP)
59		? IntRegisterValue(X86_64_REGISTER_RIP) : 0;
60}
61
62
63target_addr_t
64CpuStateX8664::StackFramePointer() const
65{
66	return IsRegisterSet(X86_64_REGISTER_RBP)
67		? IntRegisterValue(X86_64_REGISTER_RBP) : 0;
68}
69
70
71target_addr_t
72CpuStateX8664::StackPointer() const
73{
74	return IsRegisterSet(X86_64_REGISTER_RSP)
75		? IntRegisterValue(X86_64_REGISTER_RSP) : 0;
76}
77
78
79bool
80CpuStateX8664::GetRegisterValue(const Register* reg, BVariant& _value) const
81{
82	int32 index = reg->Index();
83	if (!IsRegisterSet(index))
84		return false;
85
86	if (index >= X86_64_INT_REGISTER_END)
87		return false;
88
89	if (reg->BitSize() == 16)
90		_value.SetTo((uint16)fIntRegisters[index]);
91	else
92		_value.SetTo(fIntRegisters[index]);
93
94	return true;
95}
96
97
98bool
99CpuStateX8664::SetRegisterValue(const Register* reg, const BVariant& value)
100{
101	int32 index = reg->Index();
102	if (index >= X86_64_INT_REGISTER_END)
103		return false;
104
105	fIntRegisters[index] = value.ToUInt64();
106	fSetRegisters[index] = 1;
107	return true;
108}
109
110
111bool
112CpuStateX8664::IsRegisterSet(int32 index) const
113{
114	return index >= 0 && index < X86_64_REGISTER_COUNT && fSetRegisters[index];
115}
116
117
118uint64
119CpuStateX8664::IntRegisterValue(int32 index) const
120{
121	if (!IsRegisterSet(index) || index >= X86_64_INT_REGISTER_END)
122		return 0;
123
124	return fIntRegisters[index];
125}
126
127
128void
129CpuStateX8664::SetIntRegister(int32 index, uint64 value)
130{
131	if (index < 0 || index >= X86_64_INT_REGISTER_END)
132		return;
133
134	fIntRegisters[index] = value;
135	fSetRegisters[index] = 1;
136}
137
138
139void
140CpuStateX8664::UnsetRegister(int32 index)
141{
142	if (index < 0 || index >= X86_64_REGISTER_COUNT)
143		return;
144
145	fSetRegisters[index] = 0;
146}
147