1 //===-- EmulationStateARM.cpp -----------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "EmulationStateARM.h"
11
12 #include "lldb/Interpreter/OptionValueArray.h"
13 #include "lldb/Interpreter/OptionValueDictionary.h"
14 #include "lldb/Target/RegisterContext.h"
15 #include "lldb/Target/StackFrame.h"
16 #include "lldb/Utility/RegisterValue.h"
17 #include "lldb/Utility/Scalar.h"
18
19 #include "Utility/ARM_DWARF_Registers.h"
20
21 using namespace lldb;
22 using namespace lldb_private;
23
EmulationStateARM()24 EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
25 ClearPseudoRegisters();
26 }
27
~EmulationStateARM()28 EmulationStateARM::~EmulationStateARM() {}
29
LoadPseudoRegistersFromFrame(StackFrame & frame)30 bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
31 RegisterContext *reg_ctx = frame.GetRegisterContext().get();
32 bool success = true;
33 uint32_t reg_num;
34
35 for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
36 reg_num =
37 reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
38 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
39 RegisterValue reg_value;
40 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
41 m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
42 } else
43 success = false;
44 }
45
46 for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
47 reg_num =
48 reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
49 RegisterValue reg_value;
50 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
51
52 if (reg_ctx->ReadRegister(reg_info, reg_value)) {
53 uint64_t value = reg_value.GetAsUInt64();
54 uint32_t idx = i - dwarf_d0;
55 if (i < 16) {
56 m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
57 m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
58 } else
59 m_vfp_regs.d_regs[idx - 16] = value;
60 } else
61 success = false;
62 }
63
64 return success;
65 }
66
StorePseudoRegisterValue(uint32_t reg_num,uint64_t value)67 bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
68 uint64_t value) {
69 if (reg_num <= dwarf_cpsr)
70 m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
71 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
72 uint32_t idx = reg_num - dwarf_s0;
73 m_vfp_regs.s_regs[idx] = (uint32_t)value;
74 } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
75 uint32_t idx = reg_num - dwarf_d0;
76 if (idx < 16) {
77 m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
78 m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
79 } else
80 m_vfp_regs.d_regs[idx - 16] = value;
81 } else
82 return false;
83
84 return true;
85 }
86
ReadPseudoRegisterValue(uint32_t reg_num,bool & success)87 uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
88 bool &success) {
89 uint64_t value = 0;
90 success = true;
91
92 if (reg_num <= dwarf_cpsr)
93 value = m_gpr[reg_num - dwarf_r0];
94 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
95 uint32_t idx = reg_num - dwarf_s0;
96 value = m_vfp_regs.d_regs[idx];
97 } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
98 uint32_t idx = reg_num - dwarf_d0;
99 if (idx < 16)
100 value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
101 ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
102 else
103 value = m_vfp_regs.d_regs[idx - 16];
104 } else
105 success = false;
106
107 return value;
108 }
109
ClearPseudoRegisters()110 void EmulationStateARM::ClearPseudoRegisters() {
111 for (int i = 0; i < 17; ++i)
112 m_gpr[i] = 0;
113
114 for (int i = 0; i < 32; ++i)
115 m_vfp_regs.s_regs[i] = 0;
116
117 for (int i = 0; i < 16; ++i)
118 m_vfp_regs.d_regs[i] = 0;
119 }
120
ClearPseudoMemory()121 void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
122
StoreToPseudoAddress(lldb::addr_t p_address,uint32_t value)123 bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
124 uint32_t value) {
125 m_memory[p_address] = value;
126 return true;
127 }
128
ReadFromPseudoAddress(lldb::addr_t p_address,bool & success)129 uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address,
130 bool &success) {
131 std::map<lldb::addr_t, uint32_t>::iterator pos;
132 uint32_t ret_val = 0;
133
134 success = true;
135 pos = m_memory.find(p_address);
136 if (pos != m_memory.end())
137 ret_val = pos->second;
138 else
139 success = false;
140
141 return ret_val;
142 }
143
ReadPseudoMemory(EmulateInstruction * instruction,void * baton,const EmulateInstruction::Context & context,lldb::addr_t addr,void * dst,size_t length)144 size_t EmulationStateARM::ReadPseudoMemory(
145 EmulateInstruction *instruction, void *baton,
146 const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
147 size_t length) {
148 if (!baton)
149 return 0;
150
151 bool success = true;
152 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
153 if (length <= 4) {
154 uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
155 if (!success)
156 return 0;
157
158 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
159 value = llvm::ByteSwap_32(value);
160 *((uint32_t *)dst) = value;
161 } else if (length == 8) {
162 uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
163 if (!success)
164 return 0;
165
166 uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
167 if (!success)
168 return 0;
169
170 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
171 value1 = llvm::ByteSwap_32(value1);
172 value2 = llvm::ByteSwap_32(value2);
173 }
174 ((uint32_t *)dst)[0] = value1;
175 ((uint32_t *)dst)[1] = value2;
176 } else
177 success = false;
178
179 if (success)
180 return length;
181
182 return 0;
183 }
184
WritePseudoMemory(EmulateInstruction * instruction,void * baton,const EmulateInstruction::Context & context,lldb::addr_t addr,const void * dst,size_t length)185 size_t EmulationStateARM::WritePseudoMemory(
186 EmulateInstruction *instruction, void *baton,
187 const EmulateInstruction::Context &context, lldb::addr_t addr,
188 const void *dst, size_t length) {
189 if (!baton)
190 return 0;
191
192 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
193
194 if (length <= 4) {
195 uint32_t value;
196 memcpy (&value, dst, sizeof (uint32_t));
197 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
198 value = llvm::ByteSwap_32(value);
199
200 pseudo_state->StoreToPseudoAddress(addr, value);
201 return length;
202 } else if (length == 8) {
203 uint32_t value1;
204 uint32_t value2;
205 memcpy (&value1, dst, sizeof (uint32_t));
206 memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t),
207 sizeof(uint32_t));
208 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
209 value1 = llvm::ByteSwap_32(value1);
210 value2 = llvm::ByteSwap_32(value2);
211 }
212
213 pseudo_state->StoreToPseudoAddress(addr, value1);
214 pseudo_state->StoreToPseudoAddress(addr + 4, value2);
215 return length;
216 }
217
218 return 0;
219 }
220
ReadPseudoRegister(EmulateInstruction * instruction,void * baton,const lldb_private::RegisterInfo * reg_info,lldb_private::RegisterValue & reg_value)221 bool EmulationStateARM::ReadPseudoRegister(
222 EmulateInstruction *instruction, void *baton,
223 const lldb_private::RegisterInfo *reg_info,
224 lldb_private::RegisterValue ®_value) {
225 if (!baton || !reg_info)
226 return false;
227
228 bool success = true;
229 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
230 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
231 assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
232 uint64_t reg_uval =
233 pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
234
235 if (success)
236 success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
237 return success;
238 }
239
WritePseudoRegister(EmulateInstruction * instruction,void * baton,const EmulateInstruction::Context & context,const lldb_private::RegisterInfo * reg_info,const lldb_private::RegisterValue & reg_value)240 bool EmulationStateARM::WritePseudoRegister(
241 EmulateInstruction *instruction, void *baton,
242 const EmulateInstruction::Context &context,
243 const lldb_private::RegisterInfo *reg_info,
244 const lldb_private::RegisterValue ®_value) {
245 if (!baton || !reg_info)
246 return false;
247
248 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
249 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
250 assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
251 return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
252 reg_value.GetAsUInt64());
253 }
254
CompareState(EmulationStateARM & other_state)255 bool EmulationStateARM::CompareState(EmulationStateARM &other_state) {
256 bool match = true;
257
258 for (int i = 0; match && i < 17; ++i) {
259 if (m_gpr[i] != other_state.m_gpr[i])
260 match = false;
261 }
262
263 for (int i = 0; match && i < 32; ++i) {
264 if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
265 match = false;
266 }
267
268 for (int i = 0; match && i < 16; ++i) {
269 if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
270 match = false;
271 }
272
273 return match;
274 }
275
LoadStateFromDictionary(OptionValueDictionary * test_data)276 bool EmulationStateARM::LoadStateFromDictionary(
277 OptionValueDictionary *test_data) {
278 static ConstString memory_key("memory");
279 static ConstString registers_key("registers");
280
281 if (!test_data)
282 return false;
283
284 OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
285
286 // Load memory, if present.
287
288 if (value_sp.get() != NULL) {
289 static ConstString address_key("address");
290 static ConstString data_key("data");
291 uint64_t start_address = 0;
292
293 OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
294 value_sp = mem_dict->GetValueForKey(address_key);
295 if (value_sp.get() == NULL)
296 return false;
297 else
298 start_address = value_sp->GetUInt64Value();
299
300 value_sp = mem_dict->GetValueForKey(data_key);
301 OptionValueArray *mem_array = value_sp->GetAsArray();
302 if (!mem_array)
303 return false;
304
305 uint32_t num_elts = mem_array->GetSize();
306 uint32_t address = (uint32_t)start_address;
307
308 for (uint32_t i = 0; i < num_elts; ++i) {
309 value_sp = mem_array->GetValueAtIndex(i);
310 if (value_sp.get() == NULL)
311 return false;
312 uint64_t value = value_sp->GetUInt64Value();
313 StoreToPseudoAddress(address, value);
314 address = address + 4;
315 }
316 }
317
318 value_sp = test_data->GetValueForKey(registers_key);
319 if (value_sp.get() == NULL)
320 return false;
321
322 // Load General Registers
323
324 OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
325
326 StreamString sstr;
327 for (int i = 0; i < 16; ++i) {
328 sstr.Clear();
329 sstr.Printf("r%d", i);
330 ConstString reg_name(sstr.GetString());
331 value_sp = reg_dict->GetValueForKey(reg_name);
332 if (value_sp.get() == NULL)
333 return false;
334 uint64_t reg_value = value_sp->GetUInt64Value();
335 StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
336 }
337
338 static ConstString cpsr_name("cpsr");
339 value_sp = reg_dict->GetValueForKey(cpsr_name);
340 if (value_sp.get() == NULL)
341 return false;
342 StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
343
344 // Load s/d Registers
345 for (int i = 0; i < 32; ++i) {
346 sstr.Clear();
347 sstr.Printf("s%d", i);
348 ConstString reg_name(sstr.GetString());
349 value_sp = reg_dict->GetValueForKey(reg_name);
350 if (value_sp.get() == NULL)
351 return false;
352 uint64_t reg_value = value_sp->GetUInt64Value();
353 StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
354 }
355
356 return true;
357 }
358