LLDB  mainline
EmulationStateARM.cpp
Go to the documentation of this file.
1 //===-- EmulationStateARM.cpp -----------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "EmulationStateARM.h"
10 
14 #include "lldb/Target/StackFrame.h"
16 #include "lldb/Utility/Scalar.h"
17 
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
25 }
26 
28 
30  RegisterContext *reg_ctx = frame.GetRegisterContext().get();
31  bool success = true;
32  uint32_t reg_num;
33 
34  for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
35  reg_num =
37  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
38  RegisterValue reg_value;
39  if (reg_ctx->ReadRegister(reg_info, reg_value)) {
40  m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
41  } else
42  success = false;
43  }
44 
45  for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
46  reg_num =
48  RegisterValue reg_value;
49  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
50 
51  if (reg_ctx->ReadRegister(reg_info, reg_value)) {
52  uint64_t value = reg_value.GetAsUInt64();
53  uint32_t idx = i - dwarf_d0;
54  if (i < 16) {
55  m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
56  m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
57  } else
58  m_vfp_regs.d_regs[idx - 16] = value;
59  } else
60  success = false;
61  }
62 
63  return success;
64 }
65 
67  uint64_t value) {
68  if (reg_num <= dwarf_cpsr)
69  m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
70  else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
71  uint32_t idx = reg_num - dwarf_s0;
72  m_vfp_regs.s_regs[idx] = (uint32_t)value;
73  } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
74  uint32_t idx = reg_num - dwarf_d0;
75  if (idx < 16) {
76  m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
77  m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
78  } else
79  m_vfp_regs.d_regs[idx - 16] = value;
80  } else
81  return false;
82 
83  return true;
84 }
85 
87  bool &success) {
88  uint64_t value = 0;
89  success = true;
90 
91  if (reg_num <= dwarf_cpsr)
92  value = m_gpr[reg_num - dwarf_r0];
93  else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
94  uint32_t idx = reg_num - dwarf_s0;
95  value = m_vfp_regs.d_regs[idx];
96  } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
97  uint32_t idx = reg_num - dwarf_d0;
98  if (idx < 16)
99  value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
100  ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32);
101  else
102  value = m_vfp_regs.d_regs[idx - 16];
103  } else
104  success = false;
105 
106  return value;
107 }
108 
110  for (int i = 0; i < 17; ++i)
111  m_gpr[i] = 0;
112 
113  for (int i = 0; i < 32; ++i)
114  m_vfp_regs.s_regs[i] = 0;
115 
116  for (int i = 0; i < 16; ++i)
117  m_vfp_regs.d_regs[i] = 0;
118 }
119 
120 void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
121 
123  uint32_t value) {
124  m_memory[p_address] = value;
125  return true;
126 }
127 
129  bool &success) {
130  std::map<lldb::addr_t, uint32_t>::iterator pos;
131  uint32_t ret_val = 0;
132 
133  success = true;
134  pos = m_memory.find(p_address);
135  if (pos != m_memory.end())
136  ret_val = pos->second;
137  else
138  success = false;
139 
140  return ret_val;
141 }
142 
144  EmulateInstruction *instruction, void *baton,
145  const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
146  size_t length) {
147  if (!baton)
148  return 0;
149 
150  bool success = true;
151  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
152  if (length <= 4) {
153  uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
154  if (!success)
155  return 0;
156 
158  value = llvm::ByteSwap_32(value);
159  *((uint32_t *)dst) = value;
160  } else if (length == 8) {
161  uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
162  if (!success)
163  return 0;
164 
165  uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
166  if (!success)
167  return 0;
168 
170  value1 = llvm::ByteSwap_32(value1);
171  value2 = llvm::ByteSwap_32(value2);
172  }
173  ((uint32_t *)dst)[0] = value1;
174  ((uint32_t *)dst)[1] = value2;
175  } else
176  success = false;
177 
178  if (success)
179  return length;
180 
181  return 0;
182 }
183 
185  EmulateInstruction *instruction, void *baton,
186  const EmulateInstruction::Context &context, lldb::addr_t addr,
187  const void *dst, size_t length) {
188  if (!baton)
189  return 0;
190 
191  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
192 
193  if (length <= 4) {
194  uint32_t value;
195  memcpy (&value, dst, sizeof (uint32_t));
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;
203  uint32_t value2;
204  memcpy (&value1, dst, sizeof (uint32_t));
205  memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t),
206  sizeof(uint32_t));
208  value1 = llvm::ByteSwap_32(value1);
209  value2 = llvm::ByteSwap_32(value2);
210  }
211 
212  pseudo_state->StoreToPseudoAddress(addr, value1);
213  pseudo_state->StoreToPseudoAddress(addr + 4, value2);
214  return length;
215  }
216 
217  return 0;
218 }
219 
221  EmulateInstruction *instruction, void *baton,
222  const lldb_private::RegisterInfo *reg_info,
223  lldb_private::RegisterValue &reg_value) {
224  if (!baton || !reg_info)
225  return false;
226 
227  bool success = true;
228  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
229  const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
230  assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
231  uint64_t reg_uval =
232  pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
233 
234  if (success)
235  success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
236  return success;
237 }
238 
240  EmulateInstruction *instruction, void *baton,
241  const EmulateInstruction::Context &context,
242  const lldb_private::RegisterInfo *reg_info,
243  const lldb_private::RegisterValue &reg_value) {
244  if (!baton || !reg_info)
245  return false;
246 
247  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
248  const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
249  assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
250  return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
251  reg_value.GetAsUInt64());
252 }
253 
255  bool match = true;
256 
257  for (int i = 0; match && i < 17; ++i) {
258  if (m_gpr[i] != other_state.m_gpr[i])
259  match = false;
260  }
261 
262  for (int i = 0; match && i < 32; ++i) {
263  if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
264  match = false;
265  }
266 
267  for (int i = 0; match && i < 16; ++i) {
268  if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
269  match = false;
270  }
271 
272  return match;
273 }
274 
276  OptionValueDictionary *test_data) {
277  static ConstString memory_key("memory");
278  static ConstString registers_key("registers");
279 
280  if (!test_data)
281  return false;
282 
283  OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
284 
285  // Load memory, if present.
286 
287  if (value_sp.get() != NULL) {
288  static ConstString address_key("address");
289  static ConstString data_key("data");
290  uint64_t start_address = 0;
291 
292  OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
293  value_sp = mem_dict->GetValueForKey(address_key);
294  if (value_sp.get() == NULL)
295  return false;
296  else
297  start_address = value_sp->GetUInt64Value();
298 
299  value_sp = mem_dict->GetValueForKey(data_key);
300  OptionValueArray *mem_array = value_sp->GetAsArray();
301  if (!mem_array)
302  return false;
303 
304  uint32_t num_elts = mem_array->GetSize();
305  uint32_t address = (uint32_t)start_address;
306 
307  for (uint32_t i = 0; i < num_elts; ++i) {
308  value_sp = mem_array->GetValueAtIndex(i);
309  if (value_sp.get() == NULL)
310  return false;
311  uint64_t value = value_sp->GetUInt64Value();
312  StoreToPseudoAddress(address, value);
313  address = address + 4;
314  }
315  }
316 
317  value_sp = test_data->GetValueForKey(registers_key);
318  if (value_sp.get() == NULL)
319  return false;
320 
321  // Load General Registers
322 
323  OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
324 
325  StreamString sstr;
326  for (int i = 0; i < 16; ++i) {
327  sstr.Clear();
328  sstr.Printf("r%d", i);
329  ConstString reg_name(sstr.GetString());
330  value_sp = reg_dict->GetValueForKey(reg_name);
331  if (value_sp.get() == NULL)
332  return false;
333  uint64_t reg_value = value_sp->GetUInt64Value();
334  StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
335  }
336 
337  static ConstString cpsr_name("cpsr");
338  value_sp = reg_dict->GetValueForKey(cpsr_name);
339  if (value_sp.get() == NULL)
340  return false;
341  StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
342 
343  // Load s/d Registers
344  for (int i = 0; i < 32; ++i) {
345  sstr.Clear();
346  sstr.Printf("s%d", i);
347  ConstString reg_name(sstr.GetString());
348  value_sp = reg_dict->GetValueForKey(reg_name);
349  if (value_sp.get() == NULL)
350  return false;
351  uint64_t reg_value = value_sp->GetUInt64Value();
352  StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
353  }
354 
355  return true;
356 }
static bool WritePseudoRegister(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &reg_value)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
bool LoadStateFromDictionary(lldb_private::OptionValueDictionary *test_data)
bool LoadPseudoRegistersFromFrame(lldb_private::StackFrame &frame)
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)=0
Convert from a given register numbering scheme to the lldb register numbering scheme.
static size_t ReadPseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, lldb::addr_t addr, void *dst, size_t length)
"lldb/Core/EmulateInstruction.h" A class that allows emulation of CPU opcodes.
bool StoreToPseudoAddress(lldb::addr_t p_address, uint32_t value)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
static bool ReadPseudoRegister(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &reg_value)
bool SetUInt(uint64_t uint, uint32_t byte_size)
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
uint32_t ReadFromPseudoAddress(lldb::addr_t p_address, bool &success)
OptionValueDictionary * GetAsDictionary()
bool StorePseudoRegisterValue(uint32_t reg_num, uint64_t value)
llvm::StringRef GetString() const
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
static size_t WritePseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, lldb::addr_t addr, const void *dst, size_t length)
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
uint64_t addr_t
Definition: lldb-types.h:83
A uniqued constant string class.
Definition: ConstString.h:38
Definition: SBAddress.h:15
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
uint64_t ReadPseudoRegisterValue(uint32_t reg_num, bool &success)
bool CompareState(EmulationStateARM &other_state)
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
lldb::OptionValueSP GetValueForKey(ConstString key) const
OptionValueArray * GetAsArray()
lldb::OptionValueSP GetValueAtIndex(size_t idx) const
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90