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