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/RegisterContext.h"
17 #include "lldb/Target/StackFrame.h"
18 
19 #include "Utility/ARM_DWARF_Registers.h"
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 
24 EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
25   ClearPseudoRegisters();
26 }
27 
28 EmulationStateARM::~EmulationStateARM() {}
29 
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 
67 bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
68                                                  uint64_t value) {
69   if ((dwarf_r0 <= reg_num) && (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 
87 uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
88                                                     bool &success) {
89   uint64_t value = 0;
90   success = true;
91 
92   if ((dwarf_r0 <= reg_num) && (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 
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 
121 void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
122 
123 bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
124                                              uint32_t value) {
125   m_memory[p_address] = value;
126   return true;
127 }
128 
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 
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 
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 = *((const uint32_t *)dst);
196     if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
197       value = llvm::ByteSwap_32(value);
198 
199     pseudo_state->StoreToPseudoAddress(addr, value);
200     return length;
201   } else if (length == 8) {
202     uint32_t value1 = ((const uint32_t *)dst)[0];
203     uint32_t value2 = ((const uint32_t *)dst)[1];
204     if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
205       value1 = llvm::ByteSwap_32(value1);
206       value2 = llvm::ByteSwap_32(value2);
207     }
208 
209     pseudo_state->StoreToPseudoAddress(addr, value1);
210     pseudo_state->StoreToPseudoAddress(addr + 4, value2);
211     return length;
212   }
213 
214   return 0;
215 }
216 
217 bool EmulationStateARM::ReadPseudoRegister(
218     EmulateInstruction *instruction, void *baton,
219     const lldb_private::RegisterInfo *reg_info,
220     lldb_private::RegisterValue &reg_value) {
221   if (!baton || !reg_info)
222     return false;
223 
224   bool success = true;
225   EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
226   const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
227   assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
228   uint64_t reg_uval =
229       pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
230 
231   if (success)
232     success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
233   return success;
234 }
235 
236 bool EmulationStateARM::WritePseudoRegister(
237     EmulateInstruction *instruction, void *baton,
238     const EmulateInstruction::Context &context,
239     const lldb_private::RegisterInfo *reg_info,
240     const lldb_private::RegisterValue &reg_value) {
241   if (!baton || !reg_info)
242     return false;
243 
244   EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
245   const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
246   assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
247   return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
248                                                 reg_value.GetAsUInt64());
249 }
250 
251 bool EmulationStateARM::CompareState(EmulationStateARM &other_state) {
252   bool match = true;
253 
254   for (int i = 0; match && i < 17; ++i) {
255     if (m_gpr[i] != other_state.m_gpr[i])
256       match = false;
257   }
258 
259   for (int i = 0; match && i < 32; ++i) {
260     if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
261       match = false;
262   }
263 
264   for (int i = 0; match && i < 16; ++i) {
265     if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
266       match = false;
267   }
268 
269   return match;
270 }
271 
272 bool EmulationStateARM::LoadStateFromDictionary(
273     OptionValueDictionary *test_data) {
274   static ConstString memory_key("memory");
275   static ConstString registers_key("registers");
276 
277   if (!test_data)
278     return false;
279 
280   OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
281 
282   // Load memory, if present.
283 
284   if (value_sp.get() != NULL) {
285     static ConstString address_key("address");
286     static ConstString data_key("data");
287     uint64_t start_address = 0;
288 
289     OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
290     value_sp = mem_dict->GetValueForKey(address_key);
291     if (value_sp.get() == NULL)
292       return false;
293     else
294       start_address = value_sp->GetUInt64Value();
295 
296     value_sp = mem_dict->GetValueForKey(data_key);
297     OptionValueArray *mem_array = value_sp->GetAsArray();
298     if (!mem_array)
299       return false;
300 
301     uint32_t num_elts = mem_array->GetSize();
302     uint32_t address = (uint32_t)start_address;
303 
304     for (uint32_t i = 0; i < num_elts; ++i) {
305       value_sp = mem_array->GetValueAtIndex(i);
306       if (value_sp.get() == NULL)
307         return false;
308       uint64_t value = value_sp->GetUInt64Value();
309       StoreToPseudoAddress(address, value);
310       address = address + 4;
311     }
312   }
313 
314   value_sp = test_data->GetValueForKey(registers_key);
315   if (value_sp.get() == NULL)
316     return false;
317 
318   // Load General Registers
319 
320   OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
321 
322   StreamString sstr;
323   for (int i = 0; i < 16; ++i) {
324     sstr.Clear();
325     sstr.Printf("r%d", i);
326     ConstString reg_name(sstr.GetData());
327     value_sp = reg_dict->GetValueForKey(reg_name);
328     if (value_sp.get() == NULL)
329       return false;
330     uint64_t reg_value = value_sp->GetUInt64Value();
331     StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
332   }
333 
334   static ConstString cpsr_name("cpsr");
335   value_sp = reg_dict->GetValueForKey(cpsr_name);
336   if (value_sp.get() == NULL)
337     return false;
338   StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
339 
340   // Load s/d Registers
341   for (int i = 0; i < 32; ++i) {
342     sstr.Clear();
343     sstr.Printf("s%d", i);
344     ConstString reg_name(sstr.GetData());
345     value_sp = reg_dict->GetValueForKey(reg_name);
346     if (value_sp.get() == NULL)
347       return false;
348     uint64_t reg_value = value_sp->GetUInt64Value();
349     StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
350   }
351 
352   return true;
353 }
354