]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Instruction / ARM / EmulationStateARM.cpp
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
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 (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 (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;
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
221 bool EmulationStateARM::ReadPseudoRegister(
222     EmulateInstruction *instruction, void *baton,
223     const lldb_private::RegisterInfo *reg_info,
224     lldb_private::RegisterValue &reg_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
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 &reg_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
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
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 }