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/StackFrame.h" 17 #include "lldb/Target/RegisterContext.h" 18 19 #include "Utility/ARM_DWARF_Registers.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 EmulationStateARM::EmulationStateARM () : 25 m_gpr (), 26 m_vfp_regs (), 27 m_memory () 28 { 29 ClearPseudoRegisters(); 30 } 31 32 EmulationStateARM::~EmulationStateARM () 33 { 34 } 35 36 bool 37 EmulationStateARM::LoadPseudoRegistersFromFrame (StackFrame &frame) 38 { 39 RegisterContext *reg_ctx = frame.GetRegisterContext().get(); 40 bool success = true; 41 uint32_t reg_num; 42 43 for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) 44 { 45 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i); 46 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 47 RegisterValue reg_value; 48 if (reg_ctx->ReadRegister (reg_info, reg_value)) 49 { 50 m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32(); 51 } 52 else 53 success = false; 54 } 55 56 for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) 57 { 58 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i); 59 RegisterValue reg_value; 60 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); 61 62 if (reg_ctx->ReadRegister (reg_info, reg_value)) 63 { 64 uint64_t value = reg_value.GetAsUInt64(); 65 uint32_t idx = i - dwarf_d0; 66 if (i < 16) 67 { 68 m_vfp_regs.s_regs[idx * 2] = (uint32_t)value; 69 m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32); 70 } 71 else 72 m_vfp_regs.d_regs[idx - 16] = value; 73 } 74 else 75 success = false; 76 } 77 78 return success; 79 } 80 81 bool 82 EmulationStateARM::StorePseudoRegisterValue (uint32_t reg_num, uint64_t value) 83 { 84 if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr)) 85 m_gpr[reg_num - dwarf_r0] = (uint32_t) value; 86 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) 87 { 88 uint32_t idx = reg_num - dwarf_s0; 89 m_vfp_regs.s_regs[idx] = (uint32_t)value; 90 } 91 else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) 92 { 93 uint32_t idx = reg_num - dwarf_d0; 94 if (idx < 16) 95 { 96 m_vfp_regs.s_regs[idx * 2] = (uint32_t)value; 97 m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32); 98 } 99 else 100 m_vfp_regs.d_regs[idx - 16] = value; 101 } 102 else 103 return false; 104 105 return true; 106 } 107 108 uint64_t 109 EmulationStateARM::ReadPseudoRegisterValue (uint32_t reg_num, bool &success) 110 { 111 uint64_t value = 0; 112 success = true; 113 114 if ((dwarf_r0 <= reg_num) && (reg_num <= dwarf_cpsr)) 115 value = m_gpr[reg_num - dwarf_r0]; 116 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) 117 { 118 uint32_t idx = reg_num - dwarf_s0; 119 value = m_vfp_regs.d_regs[idx]; 120 } 121 else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) 122 { 123 uint32_t idx = reg_num - dwarf_d0; 124 if (idx < 16) 125 value = (uint64_t)m_vfp_regs.s_regs[idx * 2] | ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] >> 32); 126 else 127 value = m_vfp_regs.d_regs[idx - 16]; 128 } 129 else 130 success = false; 131 132 return value; 133 } 134 135 void 136 EmulationStateARM::ClearPseudoRegisters () 137 { 138 for (int i = 0; i < 17; ++i) 139 m_gpr[i] = 0; 140 141 for (int i = 0; i < 32; ++i) 142 m_vfp_regs.s_regs[i] = 0; 143 144 for (int i = 0; i < 16; ++i) 145 m_vfp_regs.d_regs[i] = 0; 146 } 147 148 void 149 EmulationStateARM::ClearPseudoMemory () 150 { 151 m_memory.clear(); 152 } 153 154 bool 155 EmulationStateARM::StoreToPseudoAddress (lldb::addr_t p_address, uint32_t value) 156 { 157 m_memory[p_address] = value; 158 return true; 159 } 160 161 uint32_t 162 EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, bool &success) 163 { 164 std::map<lldb::addr_t,uint32_t>::iterator pos; 165 uint32_t ret_val = 0; 166 167 success = true; 168 pos = m_memory.find(p_address); 169 if (pos != m_memory.end()) 170 ret_val = pos->second; 171 else 172 success = false; 173 174 return ret_val; 175 } 176 177 size_t 178 EmulationStateARM::ReadPseudoMemory (EmulateInstruction *instruction, 179 void *baton, 180 const EmulateInstruction::Context &context, 181 lldb::addr_t addr, 182 void *dst, 183 size_t length) 184 { 185 if (!baton) 186 return 0; 187 188 bool success = true; 189 EmulationStateARM *pseudo_state = (EmulationStateARM *) baton; 190 if (length <= 4) 191 { 192 uint32_t value = pseudo_state->ReadFromPseudoAddress (addr, success); 193 if (!success) 194 return 0; 195 196 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 197 value = llvm::ByteSwap_32 (value); 198 *((uint32_t *) dst) = value; 199 } 200 else if (length == 8) 201 { 202 uint32_t value1 = pseudo_state->ReadFromPseudoAddress (addr, success); 203 if (!success) 204 return 0; 205 206 uint32_t value2 = pseudo_state->ReadFromPseudoAddress (addr + 4, success); 207 if (!success) 208 return 0; 209 210 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 211 { 212 value1 = llvm::ByteSwap_32 (value1); 213 value2 = llvm::ByteSwap_32 (value2); 214 } 215 ((uint32_t *) dst)[0] = value1; 216 ((uint32_t *) dst)[1] = value2; 217 } 218 else 219 success = false; 220 221 if (success) 222 return length; 223 224 return 0; 225 } 226 227 size_t 228 EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction, 229 void *baton, 230 const EmulateInstruction::Context &context, 231 lldb::addr_t addr, 232 const void *dst, 233 size_t length) 234 { 235 if (!baton) 236 return 0; 237 238 EmulationStateARM *pseudo_state = (EmulationStateARM *) baton; 239 240 if (length <= 4) 241 { 242 uint32_t value = *((const uint32_t *) dst); 243 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 244 value = llvm::ByteSwap_32 (value); 245 246 pseudo_state->StoreToPseudoAddress (addr, value); 247 return length; 248 } 249 else if (length == 8) 250 { 251 uint32_t value1 = ((const uint32_t *) dst)[0]; 252 uint32_t value2 = ((const uint32_t *) dst)[1]; 253 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 254 { 255 value1 = llvm::ByteSwap_32 (value1); 256 value2 = llvm::ByteSwap_32 (value2); 257 } 258 259 pseudo_state->StoreToPseudoAddress (addr, value1); 260 pseudo_state->StoreToPseudoAddress (addr + 4, value2); 261 return length; 262 } 263 264 return 0; 265 } 266 267 bool 268 EmulationStateARM::ReadPseudoRegister (EmulateInstruction *instruction, 269 void *baton, 270 const lldb_private::RegisterInfo *reg_info, 271 lldb_private::RegisterValue ®_value) 272 { 273 if (!baton || !reg_info) 274 return false; 275 276 bool success = true; 277 EmulationStateARM *pseudo_state = (EmulationStateARM *) baton; 278 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF]; 279 assert (dwarf_reg_num != LLDB_INVALID_REGNUM); 280 uint64_t reg_uval = pseudo_state->ReadPseudoRegisterValue (dwarf_reg_num, success); 281 282 if (success) 283 success = reg_value.SetUInt(reg_uval, reg_info->byte_size); 284 return success; 285 286 } 287 288 bool 289 EmulationStateARM::WritePseudoRegister (EmulateInstruction *instruction, 290 void *baton, 291 const EmulateInstruction::Context &context, 292 const lldb_private::RegisterInfo *reg_info, 293 const lldb_private::RegisterValue ®_value) 294 { 295 if (!baton || !reg_info) 296 return false; 297 298 EmulationStateARM *pseudo_state = (EmulationStateARM *) baton; 299 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF]; 300 assert (dwarf_reg_num != LLDB_INVALID_REGNUM); 301 return pseudo_state->StorePseudoRegisterValue (dwarf_reg_num, reg_value.GetAsUInt64()); 302 } 303 304 bool 305 EmulationStateARM::CompareState (EmulationStateARM &other_state) 306 { 307 bool match = true; 308 309 for (int i = 0; match && i < 17; ++i) 310 { 311 if (m_gpr[i] != other_state.m_gpr[i]) 312 match = false; 313 } 314 315 for (int i = 0; match && i < 32; ++i) 316 { 317 if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i]) 318 match = false; 319 } 320 321 for (int i = 0; match && i < 16; ++i) 322 { 323 if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i]) 324 match = false; 325 } 326 327 return match; 328 } 329 330 bool 331 EmulationStateARM::LoadStateFromDictionary (OptionValueDictionary *test_data) 332 { 333 static ConstString memory_key ("memory"); 334 static ConstString registers_key ("registers"); 335 336 if (!test_data) 337 return false; 338 339 OptionValueSP value_sp = test_data->GetValueForKey (memory_key); 340 341 // Load memory, if present. 342 343 if (value_sp.get() != NULL) 344 { 345 static ConstString address_key ("address"); 346 static ConstString data_key ("data"); 347 uint64_t start_address = 0; 348 349 OptionValueDictionary *mem_dict = value_sp->GetAsDictionary(); 350 value_sp = mem_dict->GetValueForKey (address_key); 351 if (value_sp.get() == NULL) 352 return false; 353 else 354 start_address = value_sp->GetUInt64Value (); 355 356 value_sp = mem_dict->GetValueForKey (data_key); 357 OptionValueArray *mem_array = value_sp->GetAsArray(); 358 if (!mem_array) 359 return false; 360 361 uint32_t num_elts = mem_array->GetSize(); 362 uint32_t address = (uint32_t) start_address; 363 364 for (uint32_t i = 0; i < num_elts; ++i) 365 { 366 value_sp = mem_array->GetValueAtIndex (i); 367 if (value_sp.get() == NULL) 368 return false; 369 uint64_t value = value_sp->GetUInt64Value(); 370 StoreToPseudoAddress (address, value); 371 address = address + 4; 372 } 373 } 374 375 value_sp = test_data->GetValueForKey (registers_key); 376 if (value_sp.get() == NULL) 377 return false; 378 379 380 // Load General Registers 381 382 OptionValueDictionary *reg_dict = value_sp->GetAsDictionary (); 383 384 StreamString sstr; 385 for (int i = 0; i < 16; ++i) 386 { 387 sstr.Clear(); 388 sstr.Printf ("r%d", i); 389 ConstString reg_name (sstr.GetData()); 390 value_sp = reg_dict->GetValueForKey (reg_name); 391 if (value_sp.get() == NULL) 392 return false; 393 uint64_t reg_value = value_sp->GetUInt64Value(); 394 StorePseudoRegisterValue (dwarf_r0 + i, reg_value); 395 } 396 397 static ConstString cpsr_name ("cpsr"); 398 value_sp = reg_dict->GetValueForKey (cpsr_name); 399 if (value_sp.get() == NULL) 400 return false; 401 StorePseudoRegisterValue (dwarf_cpsr, value_sp->GetUInt64Value()); 402 403 // Load s/d Registers 404 for (int i = 0; i < 32; ++i) 405 { 406 sstr.Clear(); 407 sstr.Printf ("s%d", i); 408 ConstString reg_name (sstr.GetData()); 409 value_sp = reg_dict->GetValueForKey (reg_name); 410 if (value_sp.get() == NULL) 411 return false; 412 uint64_t reg_value = value_sp->GetUInt64Value(); 413 StorePseudoRegisterValue (dwarf_s0 + i, reg_value); 414 } 415 416 return true; 417 } 418 419