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 ®_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 ®_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 } 358