180814287SRaphael Isemann //===-- EmulationStateARM.cpp ---------------------------------------------===//
23ac6711aSCaroline Tice //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63ac6711aSCaroline Tice //
73ac6711aSCaroline Tice //===----------------------------------------------------------------------===//
83ac6711aSCaroline Tice
93ac6711aSCaroline Tice #include "EmulationStateARM.h"
103ac6711aSCaroline Tice
1167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueArray.h"
1267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueDictionary.h"
133ac6711aSCaroline Tice #include "lldb/Target/RegisterContext.h"
14b9c1b51eSKate Stone #include "lldb/Target/StackFrame.h"
15d821c997SPavel Labath #include "lldb/Utility/RegisterValue.h"
16d821c997SPavel Labath #include "lldb/Utility/Scalar.h"
173ac6711aSCaroline Tice
183ac6711aSCaroline Tice #include "Utility/ARM_DWARF_Registers.h"
193ac6711aSCaroline Tice
203ac6711aSCaroline Tice using namespace lldb;
213ac6711aSCaroline Tice using namespace lldb_private;
223ac6711aSCaroline Tice
EmulationStateARM()239494c510SJonas Devlieghere EmulationStateARM::EmulationStateARM() : m_vfp_regs(), m_memory() {
243ac6711aSCaroline Tice ClearPseudoRegisters();
253ac6711aSCaroline Tice }
263ac6711aSCaroline Tice
27fd2433e1SJonas Devlieghere EmulationStateARM::~EmulationStateARM() = default;
283ac6711aSCaroline Tice
LoadPseudoRegistersFromFrame(StackFrame & frame)29b9c1b51eSKate Stone bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
307349bd90SGreg Clayton RegisterContext *reg_ctx = frame.GetRegisterContext().get();
313ac6711aSCaroline Tice bool success = true;
327349bd90SGreg Clayton uint32_t reg_num;
333ac6711aSCaroline Tice
34b9c1b51eSKate Stone for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
35b9c1b51eSKate Stone reg_num =
36b9c1b51eSKate Stone reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
377349bd90SGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
387349bd90SGreg Clayton RegisterValue reg_value;
39b9c1b51eSKate Stone if (reg_ctx->ReadRegister(reg_info, reg_value)) {
407349bd90SGreg Clayton m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
41b9c1b51eSKate Stone } else
423ac6711aSCaroline Tice success = false;
433ac6711aSCaroline Tice }
443ac6711aSCaroline Tice
45b9c1b51eSKate Stone for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
46b9c1b51eSKate Stone reg_num =
47b9c1b51eSKate Stone reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
487349bd90SGreg Clayton RegisterValue reg_value;
497349bd90SGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
507349bd90SGreg Clayton
51b9c1b51eSKate Stone if (reg_ctx->ReadRegister(reg_info, reg_value)) {
5291a2ad18SUlrich Weigand uint64_t value = reg_value.GetAsUInt64();
533ac6711aSCaroline Tice uint32_t idx = i - dwarf_d0;
54b9c1b51eSKate Stone if (i < 16) {
5591a2ad18SUlrich Weigand m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
5691a2ad18SUlrich Weigand m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
57b9c1b51eSKate Stone } else
5891a2ad18SUlrich Weigand m_vfp_regs.d_regs[idx - 16] = value;
59b9c1b51eSKate Stone } else
603ac6711aSCaroline Tice success = false;
613ac6711aSCaroline Tice }
623ac6711aSCaroline Tice
633ac6711aSCaroline Tice return success;
643ac6711aSCaroline Tice }
653ac6711aSCaroline Tice
StorePseudoRegisterValue(uint32_t reg_num,uint64_t value)66b9c1b51eSKate Stone bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
67b9c1b51eSKate Stone uint64_t value) {
6849a28fdaSDavide Italiano if (reg_num <= dwarf_cpsr)
693ac6711aSCaroline Tice m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
70b9c1b51eSKate Stone else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
713ac6711aSCaroline Tice uint32_t idx = reg_num - dwarf_s0;
7291a2ad18SUlrich Weigand m_vfp_regs.s_regs[idx] = (uint32_t)value;
73b9c1b51eSKate Stone } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
7491a2ad18SUlrich Weigand uint32_t idx = reg_num - dwarf_d0;
75b9c1b51eSKate Stone if (idx < 16) {
7691a2ad18SUlrich Weigand m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
7791a2ad18SUlrich Weigand m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
78b9c1b51eSKate Stone } else
7991a2ad18SUlrich Weigand m_vfp_regs.d_regs[idx - 16] = value;
80b9c1b51eSKate Stone } else
813ac6711aSCaroline Tice return false;
823ac6711aSCaroline Tice
833ac6711aSCaroline Tice return true;
843ac6711aSCaroline Tice }
853ac6711aSCaroline Tice
ReadPseudoRegisterValue(uint32_t reg_num,bool & success)86b9c1b51eSKate Stone uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
87b9c1b51eSKate Stone bool &success) {
883ac6711aSCaroline Tice uint64_t value = 0;
893ac6711aSCaroline Tice success = true;
903ac6711aSCaroline Tice
9149a28fdaSDavide Italiano if (reg_num <= dwarf_cpsr)
923ac6711aSCaroline Tice value = m_gpr[reg_num - dwarf_r0];
93b9c1b51eSKate Stone else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
943ac6711aSCaroline Tice uint32_t idx = reg_num - dwarf_s0;
9591a2ad18SUlrich Weigand value = m_vfp_regs.d_regs[idx];
96b9c1b51eSKate Stone } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
9791a2ad18SUlrich Weigand uint32_t idx = reg_num - dwarf_d0;
9891a2ad18SUlrich Weigand if (idx < 16)
99b9c1b51eSKate Stone value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
100e80dbfddSSlava Gurevich ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] << 32);
1013ac6711aSCaroline Tice else
10291a2ad18SUlrich Weigand value = m_vfp_regs.d_regs[idx - 16];
103b9c1b51eSKate Stone } else
1043ac6711aSCaroline Tice success = false;
1053ac6711aSCaroline Tice
1063ac6711aSCaroline Tice return value;
1073ac6711aSCaroline Tice }
1083ac6711aSCaroline Tice
ClearPseudoRegisters()109b9c1b51eSKate Stone void EmulationStateARM::ClearPseudoRegisters() {
1103ac6711aSCaroline Tice for (int i = 0; i < 17; ++i)
1113ac6711aSCaroline Tice m_gpr[i] = 0;
1123ac6711aSCaroline Tice
11391a2ad18SUlrich Weigand for (int i = 0; i < 32; ++i)
11491a2ad18SUlrich Weigand m_vfp_regs.s_regs[i] = 0;
1153ac6711aSCaroline Tice
1163ac6711aSCaroline Tice for (int i = 0; i < 16; ++i)
1173ac6711aSCaroline Tice m_vfp_regs.d_regs[i] = 0;
1183ac6711aSCaroline Tice }
1193ac6711aSCaroline Tice
ClearPseudoMemory()120b9c1b51eSKate Stone void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }
1213ac6711aSCaroline Tice
StoreToPseudoAddress(lldb::addr_t p_address,uint32_t value)122b9c1b51eSKate Stone bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
123b9c1b51eSKate Stone uint32_t value) {
1243ac6711aSCaroline Tice m_memory[p_address] = value;
1253ac6711aSCaroline Tice return true;
1263ac6711aSCaroline Tice }
1273ac6711aSCaroline Tice
ReadFromPseudoAddress(lldb::addr_t p_address,bool & success)128b9c1b51eSKate Stone uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address,
129b9c1b51eSKate Stone bool &success) {
1303ac6711aSCaroline Tice std::map<lldb::addr_t, uint32_t>::iterator pos;
1313ac6711aSCaroline Tice uint32_t ret_val = 0;
1323ac6711aSCaroline Tice
1333ac6711aSCaroline Tice success = true;
1343ac6711aSCaroline Tice pos = m_memory.find(p_address);
1353ac6711aSCaroline Tice if (pos != m_memory.end())
1363ac6711aSCaroline Tice ret_val = pos->second;
1373ac6711aSCaroline Tice else
1383ac6711aSCaroline Tice success = false;
1393ac6711aSCaroline Tice
1403ac6711aSCaroline Tice return ret_val;
1413ac6711aSCaroline Tice }
1423ac6711aSCaroline Tice
ReadPseudoMemory(EmulateInstruction * instruction,void * baton,const EmulateInstruction::Context & context,lldb::addr_t addr,void * dst,size_t length)143b9c1b51eSKate Stone size_t EmulationStateARM::ReadPseudoMemory(
144b9c1b51eSKate Stone EmulateInstruction *instruction, void *baton,
145b9c1b51eSKate Stone const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
146b9c1b51eSKate Stone size_t length) {
1473ac6711aSCaroline Tice if (!baton)
1483ac6711aSCaroline Tice return 0;
1493ac6711aSCaroline Tice
1503ac6711aSCaroline Tice bool success = true;
1513ac6711aSCaroline Tice EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
152b9c1b51eSKate Stone if (length <= 4) {
15391a2ad18SUlrich Weigand uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
1543ac6711aSCaroline Tice if (!success)
1553ac6711aSCaroline Tice return 0;
1563ac6711aSCaroline Tice
15791a2ad18SUlrich Weigand if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
15891a2ad18SUlrich Weigand value = llvm::ByteSwap_32(value);
1593ac6711aSCaroline Tice *((uint32_t *)dst) = value;
160b9c1b51eSKate Stone } else if (length == 8) {
16191a2ad18SUlrich Weigand uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
1623ac6711aSCaroline Tice if (!success)
1633ac6711aSCaroline Tice return 0;
1643ac6711aSCaroline Tice
16591a2ad18SUlrich Weigand uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
1663ac6711aSCaroline Tice if (!success)
1673ac6711aSCaroline Tice return 0;
1683ac6711aSCaroline Tice
169b9c1b51eSKate Stone if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
17091a2ad18SUlrich Weigand value1 = llvm::ByteSwap_32(value1);
17191a2ad18SUlrich Weigand value2 = llvm::ByteSwap_32(value2);
17291a2ad18SUlrich Weigand }
17391a2ad18SUlrich Weigand ((uint32_t *)dst)[0] = value1;
17491a2ad18SUlrich Weigand ((uint32_t *)dst)[1] = value2;
175b9c1b51eSKate Stone } else
1763ac6711aSCaroline Tice success = false;
1773ac6711aSCaroline Tice
1783ac6711aSCaroline Tice if (success)
1793ac6711aSCaroline Tice return length;
1803ac6711aSCaroline Tice
1813ac6711aSCaroline Tice return 0;
1823ac6711aSCaroline Tice }
1833ac6711aSCaroline Tice
WritePseudoMemory(EmulateInstruction * instruction,void * baton,const EmulateInstruction::Context & context,lldb::addr_t addr,const void * dst,size_t length)184b9c1b51eSKate Stone size_t EmulationStateARM::WritePseudoMemory(
185b9c1b51eSKate Stone EmulateInstruction *instruction, void *baton,
186b9c1b51eSKate Stone const EmulateInstruction::Context &context, lldb::addr_t addr,
187b9c1b51eSKate Stone const void *dst, size_t length) {
1883ac6711aSCaroline Tice if (!baton)
1893ac6711aSCaroline Tice return 0;
1903ac6711aSCaroline Tice
1913ac6711aSCaroline Tice EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
19291a2ad18SUlrich Weigand
193b9c1b51eSKate Stone if (length <= 4) {
1943724ae4eSJason Molenda uint32_t value;
1953724ae4eSJason Molenda memcpy (&value, dst, sizeof (uint32_t));
19691a2ad18SUlrich Weigand if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
19791a2ad18SUlrich Weigand value = llvm::ByteSwap_32(value);
19891a2ad18SUlrich Weigand
19991a2ad18SUlrich Weigand pseudo_state->StoreToPseudoAddress(addr, value);
2003ac6711aSCaroline Tice return length;
201b9c1b51eSKate Stone } else if (length == 8) {
2023724ae4eSJason Molenda uint32_t value1;
2033724ae4eSJason Molenda uint32_t value2;
2043724ae4eSJason Molenda memcpy (&value1, dst, sizeof (uint32_t));
205f76e099cSSaleem Abdulrasool memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t),
206f76e099cSSaleem Abdulrasool sizeof(uint32_t));
207b9c1b51eSKate Stone if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
20891a2ad18SUlrich Weigand value1 = llvm::ByteSwap_32(value1);
20991a2ad18SUlrich Weigand value2 = llvm::ByteSwap_32(value2);
21091a2ad18SUlrich Weigand }
21191a2ad18SUlrich Weigand
21291a2ad18SUlrich Weigand pseudo_state->StoreToPseudoAddress(addr, value1);
21391a2ad18SUlrich Weigand pseudo_state->StoreToPseudoAddress(addr + 4, value2);
21491a2ad18SUlrich Weigand return length;
21591a2ad18SUlrich Weigand }
2163ac6711aSCaroline Tice
2173ac6711aSCaroline Tice return 0;
2183ac6711aSCaroline Tice }
2193ac6711aSCaroline Tice
ReadPseudoRegister(EmulateInstruction * instruction,void * baton,const lldb_private::RegisterInfo * reg_info,lldb_private::RegisterValue & reg_value)220b9c1b51eSKate Stone bool EmulationStateARM::ReadPseudoRegister(
221b9c1b51eSKate Stone EmulateInstruction *instruction, void *baton,
2227349bd90SGreg Clayton const lldb_private::RegisterInfo *reg_info,
223b9c1b51eSKate Stone lldb_private::RegisterValue ®_value) {
2247349bd90SGreg Clayton if (!baton || !reg_info)
2253ac6711aSCaroline Tice return false;
2263ac6711aSCaroline Tice
2273ac6711aSCaroline Tice bool success = true;
2283ac6711aSCaroline Tice EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
2297349bd90SGreg Clayton const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
2307349bd90SGreg Clayton assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
231b9c1b51eSKate Stone uint64_t reg_uval =
232b9c1b51eSKate Stone pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);
2333ac6711aSCaroline Tice
2347349bd90SGreg Clayton if (success)
2357349bd90SGreg Clayton success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
2363ac6711aSCaroline Tice return success;
2373ac6711aSCaroline Tice }
2383ac6711aSCaroline Tice
WritePseudoRegister(EmulateInstruction * instruction,void * baton,const EmulateInstruction::Context & context,const lldb_private::RegisterInfo * reg_info,const lldb_private::RegisterValue & reg_value)239b9c1b51eSKate Stone bool EmulationStateARM::WritePseudoRegister(
240b9c1b51eSKate Stone EmulateInstruction *instruction, void *baton,
2413ac6711aSCaroline Tice const EmulateInstruction::Context &context,
2427349bd90SGreg Clayton const lldb_private::RegisterInfo *reg_info,
243b9c1b51eSKate Stone const lldb_private::RegisterValue ®_value) {
2447349bd90SGreg Clayton if (!baton || !reg_info)
2453ac6711aSCaroline Tice return false;
2463ac6711aSCaroline Tice
2473ac6711aSCaroline Tice EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
2487349bd90SGreg Clayton const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
2497349bd90SGreg Clayton assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
250b9c1b51eSKate Stone return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
251b9c1b51eSKate Stone reg_value.GetAsUInt64());
2523ac6711aSCaroline Tice }
2533ac6711aSCaroline Tice
CompareState(EmulationStateARM & other_state,Stream * out_stream)2543ebd5419SDavid Spickett bool EmulationStateARM::CompareState(EmulationStateARM &other_state,
2553ebd5419SDavid Spickett Stream *out_stream) {
2563ac6711aSCaroline Tice bool match = true;
2573ac6711aSCaroline Tice
258b9c1b51eSKate Stone for (int i = 0; match && i < 17; ++i) {
2593ebd5419SDavid Spickett if (m_gpr[i] != other_state.m_gpr[i]) {
2603ac6711aSCaroline Tice match = false;
2613ebd5419SDavid Spickett out_stream->Printf("r%d: 0x%x != 0x%x\n", i, m_gpr[i],
2623ebd5419SDavid Spickett other_state.m_gpr[i]);
2633ebd5419SDavid Spickett }
2643ac6711aSCaroline Tice }
2653ac6711aSCaroline Tice
266b9c1b51eSKate Stone for (int i = 0; match && i < 32; ++i) {
2673ebd5419SDavid Spickett if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i]) {
2683ac6711aSCaroline Tice match = false;
2693ebd5419SDavid Spickett out_stream->Printf("s%d: 0x%x != 0x%x\n", i, m_vfp_regs.s_regs[i],
2703ebd5419SDavid Spickett other_state.m_vfp_regs.s_regs[i]);
2713ebd5419SDavid Spickett }
2723ac6711aSCaroline Tice }
27391a2ad18SUlrich Weigand
274b9c1b51eSKate Stone for (int i = 0; match && i < 16; ++i) {
2753ebd5419SDavid Spickett if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i]) {
2763ac6711aSCaroline Tice match = false;
277*d0479cb2SDavid Spickett out_stream->Printf("d%d: 0x%" PRIx64 " != 0x%" PRIx64 "\n", i + 16,
278*d0479cb2SDavid Spickett m_vfp_regs.d_regs[i],
2793ebd5419SDavid Spickett other_state.m_vfp_regs.d_regs[i]);
2803ebd5419SDavid Spickett }
2813ac6711aSCaroline Tice }
2823ac6711aSCaroline Tice
28310c2bab5SDavid Spickett // other_state is the expected state. If it has memory, check it.
28410c2bab5SDavid Spickett if (!other_state.m_memory.empty() && m_memory != other_state.m_memory) {
28510c2bab5SDavid Spickett match = false;
28610c2bab5SDavid Spickett out_stream->Printf("memory does not match\n");
28710c2bab5SDavid Spickett out_stream->Printf("got memory:\n");
28810c2bab5SDavid Spickett for (auto p : m_memory)
289*d0479cb2SDavid Spickett out_stream->Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second);
29010c2bab5SDavid Spickett out_stream->Printf("expected memory:\n");
29110c2bab5SDavid Spickett for (auto p : other_state.m_memory)
292*d0479cb2SDavid Spickett out_stream->Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second);
29310c2bab5SDavid Spickett }
29410c2bab5SDavid Spickett
2953ac6711aSCaroline Tice return match;
2963ac6711aSCaroline Tice }
297de2fb9cfSCaroline Tice
LoadRegistersStateFromDictionary(OptionValueDictionary * reg_dict,char kind,int first_reg,int num)298290c4bc7SDavid Spickett bool EmulationStateARM::LoadRegistersStateFromDictionary(
299290c4bc7SDavid Spickett OptionValueDictionary *reg_dict, char kind, int first_reg, int num) {
300290c4bc7SDavid Spickett StreamString sstr;
301290c4bc7SDavid Spickett for (int i = 0; i < num; ++i) {
302290c4bc7SDavid Spickett sstr.Clear();
303290c4bc7SDavid Spickett sstr.Printf("%c%d", kind, i);
304290c4bc7SDavid Spickett OptionValueSP value_sp =
305290c4bc7SDavid Spickett reg_dict->GetValueForKey(ConstString(sstr.GetString()));
306290c4bc7SDavid Spickett if (value_sp.get() == nullptr)
307290c4bc7SDavid Spickett return false;
308290c4bc7SDavid Spickett uint64_t reg_value = value_sp->GetUInt64Value();
309290c4bc7SDavid Spickett StorePseudoRegisterValue(first_reg + i, reg_value);
310290c4bc7SDavid Spickett }
311290c4bc7SDavid Spickett
312290c4bc7SDavid Spickett return true;
313290c4bc7SDavid Spickett }
314290c4bc7SDavid Spickett
LoadStateFromDictionary(OptionValueDictionary * test_data)315b9c1b51eSKate Stone bool EmulationStateARM::LoadStateFromDictionary(
316b9c1b51eSKate Stone OptionValueDictionary *test_data) {
317de2fb9cfSCaroline Tice static ConstString memory_key("memory");
318de2fb9cfSCaroline Tice static ConstString registers_key("registers");
319de2fb9cfSCaroline Tice
320de2fb9cfSCaroline Tice if (!test_data)
321de2fb9cfSCaroline Tice return false;
322de2fb9cfSCaroline Tice
323de2fb9cfSCaroline Tice OptionValueSP value_sp = test_data->GetValueForKey(memory_key);
324de2fb9cfSCaroline Tice
325de2fb9cfSCaroline Tice // Load memory, if present.
326de2fb9cfSCaroline Tice
327248a1305SKonrad Kleine if (value_sp.get() != nullptr) {
328de2fb9cfSCaroline Tice static ConstString address_key("address");
329de2fb9cfSCaroline Tice static ConstString data_key("data");
330de2fb9cfSCaroline Tice uint64_t start_address = 0;
331de2fb9cfSCaroline Tice
33284c39663SGreg Clayton OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
333de2fb9cfSCaroline Tice value_sp = mem_dict->GetValueForKey(address_key);
334248a1305SKonrad Kleine if (value_sp.get() == nullptr)
335de2fb9cfSCaroline Tice return false;
336de2fb9cfSCaroline Tice else
337de2fb9cfSCaroline Tice start_address = value_sp->GetUInt64Value();
338de2fb9cfSCaroline Tice
339de2fb9cfSCaroline Tice value_sp = mem_dict->GetValueForKey(data_key);
34084c39663SGreg Clayton OptionValueArray *mem_array = value_sp->GetAsArray();
341de2fb9cfSCaroline Tice if (!mem_array)
342de2fb9cfSCaroline Tice return false;
343de2fb9cfSCaroline Tice
344de2fb9cfSCaroline Tice uint32_t num_elts = mem_array->GetSize();
345de2fb9cfSCaroline Tice uint32_t address = (uint32_t)start_address;
346de2fb9cfSCaroline Tice
347b9c1b51eSKate Stone for (uint32_t i = 0; i < num_elts; ++i) {
348de2fb9cfSCaroline Tice value_sp = mem_array->GetValueAtIndex(i);
349248a1305SKonrad Kleine if (value_sp.get() == nullptr)
350de2fb9cfSCaroline Tice return false;
351de2fb9cfSCaroline Tice uint64_t value = value_sp->GetUInt64Value();
35291a2ad18SUlrich Weigand StoreToPseudoAddress(address, value);
353de2fb9cfSCaroline Tice address = address + 4;
354de2fb9cfSCaroline Tice }
355de2fb9cfSCaroline Tice }
356de2fb9cfSCaroline Tice
357de2fb9cfSCaroline Tice value_sp = test_data->GetValueForKey(registers_key);
358248a1305SKonrad Kleine if (value_sp.get() == nullptr)
359de2fb9cfSCaroline Tice return false;
360de2fb9cfSCaroline Tice
361de2fb9cfSCaroline Tice // Load General Registers
362de2fb9cfSCaroline Tice
36384c39663SGreg Clayton OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
364290c4bc7SDavid Spickett if (!LoadRegistersStateFromDictionary(reg_dict, 'r', dwarf_r0, 16))
365de2fb9cfSCaroline Tice return false;
366de2fb9cfSCaroline Tice
367de2fb9cfSCaroline Tice static ConstString cpsr_name("cpsr");
368de2fb9cfSCaroline Tice value_sp = reg_dict->GetValueForKey(cpsr_name);
369248a1305SKonrad Kleine if (value_sp.get() == nullptr)
370de2fb9cfSCaroline Tice return false;
371de2fb9cfSCaroline Tice StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());
372de2fb9cfSCaroline Tice
373de2fb9cfSCaroline Tice // Load s/d Registers
374290c4bc7SDavid Spickett // To prevent you giving both types in a state and overwriting
375290c4bc7SDavid Spickett // one or the other, we'll expect to get either all S registers,
376290c4bc7SDavid Spickett // or all D registers. Not a mix of the two.
377290c4bc7SDavid Spickett bool found_s_registers =
378290c4bc7SDavid Spickett LoadRegistersStateFromDictionary(reg_dict, 's', dwarf_s0, 32);
379290c4bc7SDavid Spickett bool found_d_registers =
380290c4bc7SDavid Spickett LoadRegistersStateFromDictionary(reg_dict, 'd', dwarf_d0, 32);
381de2fb9cfSCaroline Tice
382290c4bc7SDavid Spickett return found_s_registers != found_d_registers;
383de2fb9cfSCaroline Tice }
384