1/*
2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2011, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7#include "CpuStateX86.h"
8
9#include "Register.h"
10
11
12CpuStateX86::CpuStateX86()
13	:
14	fSetRegisters(),
15	fInterruptVector(0)
16{
17}
18
19
20CpuStateX86::CpuStateX86(const x86_debug_cpu_state& state)
21	:
22	fSetRegisters(),
23	fInterruptVector(0)
24{
25	SetIntRegister(X86_REGISTER_EIP, state.eip);
26	SetIntRegister(X86_REGISTER_ESP, state.user_esp);
27	SetIntRegister(X86_REGISTER_EBP, state.ebp);
28	SetIntRegister(X86_REGISTER_EAX, state.eax);
29	SetIntRegister(X86_REGISTER_EBX, state.ebx);
30	SetIntRegister(X86_REGISTER_ECX, state.ecx);
31	SetIntRegister(X86_REGISTER_EDX, state.edx);
32	SetIntRegister(X86_REGISTER_ESI, state.esi);
33	SetIntRegister(X86_REGISTER_EDI, state.edi);
34	SetIntRegister(X86_REGISTER_CS, state.cs);
35	SetIntRegister(X86_REGISTER_DS, state.ds);
36	SetIntRegister(X86_REGISTER_ES, state.es);
37	SetIntRegister(X86_REGISTER_FS, state.fs);
38	SetIntRegister(X86_REGISTER_GS, state.gs);
39	SetIntRegister(X86_REGISTER_SS, state.user_ss);
40
41	fInterruptVector = state.vector;
42}
43
44
45CpuStateX86::~CpuStateX86()
46{
47}
48
49
50target_addr_t
51CpuStateX86::InstructionPointer() const
52{
53	return IsRegisterSet(X86_REGISTER_EIP)
54		? IntRegisterValue(X86_REGISTER_EIP) : 0;
55}
56
57
58target_addr_t
59CpuStateX86::StackFramePointer() const
60{
61	return IsRegisterSet(X86_REGISTER_EBP)
62		? IntRegisterValue(X86_REGISTER_EBP) : 0;
63}
64
65
66target_addr_t
67CpuStateX86::StackPointer() const
68{
69	return IsRegisterSet(X86_REGISTER_ESP)
70		? IntRegisterValue(X86_REGISTER_ESP) : 0;
71}
72
73
74bool
75CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value) const
76{
77	int32 index = reg->Index();
78	if (!IsRegisterSet(index))
79		return false;
80
81	if (index >= X86_INT_REGISTER_END)
82		return false;
83
84	if (reg->BitSize() == 16)
85		_value.SetTo((uint16)fIntRegisters[index]);
86	else
87		_value.SetTo(fIntRegisters[index]);
88
89	return true;
90}
91
92
93bool
94CpuStateX86::SetRegisterValue(const Register* reg, const BVariant& value)
95{
96	int32 index = reg->Index();
97	if (index >= X86_INT_REGISTER_END)
98		return false;
99
100	fIntRegisters[index] = value.ToUInt32();
101	fSetRegisters[index] = 1;
102	return true;
103}
104
105
106bool
107CpuStateX86::IsRegisterSet(int32 index) const
108{
109	return index >= 0 && index < X86_REGISTER_COUNT && fSetRegisters[index];
110}
111
112
113uint32
114CpuStateX86::IntRegisterValue(int32 index) const
115{
116	if (!IsRegisterSet(index) || index >= X86_INT_REGISTER_END)
117		return 0;
118
119	return fIntRegisters[index];
120}
121
122
123void
124CpuStateX86::SetIntRegister(int32 index, uint32 value)
125{
126	if (index < 0 || index >= X86_INT_REGISTER_END)
127		return;
128
129	fIntRegisters[index] = value;
130	fSetRegisters[index] = 1;
131}
132
133
134void
135CpuStateX86::UnsetRegister(int32 index)
136{
137	if (index < 0 || index >= X86_REGISTER_COUNT)
138		return;
139
140	fSetRegisters[index] = 0;
141}
142