1 //===-- EmulationStateARM.cpp ---------------------------------------------===// 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 11 #include "lldb/Interpreter/OptionValueArray.h" 12 #include "lldb/Interpreter/OptionValueDictionary.h" 13 #include "lldb/Target/RegisterContext.h" 14 #include "lldb/Target/StackFrame.h" 15 #include "lldb/Utility/RegisterValue.h" 16 #include "lldb/Utility/Scalar.h" 17 18 #include "Utility/ARM_DWARF_Registers.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 23 EmulationStateARM::EmulationStateARM() : m_vfp_regs(), m_memory() { 24 ClearPseudoRegisters(); 25 } 26 27 EmulationStateARM::~EmulationStateARM() = default; 28 29 bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num, 30 uint64_t value) { 31 if (reg_num <= dwarf_cpsr) 32 m_gpr[reg_num - dwarf_r0] = (uint32_t)value; 33 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) { 34 uint32_t idx = reg_num - dwarf_s0; 35 m_vfp_regs.s_regs[idx] = (uint32_t)value; 36 } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) { 37 uint32_t idx = reg_num - dwarf_d0; 38 if (idx < 16) { 39 m_vfp_regs.s_regs[idx * 2] = (uint32_t)value; 40 m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32); 41 } else 42 m_vfp_regs.d_regs[idx - 16] = value; 43 } else 44 return false; 45 46 return true; 47 } 48 49 uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num, 50 bool &success) { 51 uint64_t value = 0; 52 success = true; 53 54 if (reg_num <= dwarf_cpsr) 55 value = m_gpr[reg_num - dwarf_r0]; 56 else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) { 57 uint32_t idx = reg_num - dwarf_s0; 58 value = m_vfp_regs.s_regs[idx]; 59 } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) { 60 uint32_t idx = reg_num - dwarf_d0; 61 if (idx < 16) 62 value = (uint64_t)m_vfp_regs.s_regs[idx * 2] | 63 ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] << 32); 64 else 65 value = m_vfp_regs.d_regs[idx - 16]; 66 } else 67 success = false; 68 69 return value; 70 } 71 72 void EmulationStateARM::ClearPseudoRegisters() { 73 for (int i = 0; i < 17; ++i) 74 m_gpr[i] = 0; 75 76 for (int i = 0; i < 32; ++i) 77 m_vfp_regs.s_regs[i] = 0; 78 79 for (int i = 0; i < 16; ++i) 80 m_vfp_regs.d_regs[i] = 0; 81 } 82 83 void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); } 84 85 bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address, 86 uint32_t value) { 87 m_memory[p_address] = value; 88 return true; 89 } 90 91 uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address, 92 bool &success) { 93 std::map<lldb::addr_t, uint32_t>::iterator pos; 94 uint32_t ret_val = 0; 95 96 success = true; 97 pos = m_memory.find(p_address); 98 if (pos != m_memory.end()) 99 ret_val = pos->second; 100 else 101 success = false; 102 103 return ret_val; 104 } 105 106 size_t EmulationStateARM::ReadPseudoMemory( 107 EmulateInstruction *instruction, void *baton, 108 const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst, 109 size_t length) { 110 if (!baton) 111 return 0; 112 113 bool success = true; 114 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton; 115 if (length <= 4) { 116 uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success); 117 if (!success) 118 return 0; 119 120 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 121 value = llvm::byteswap<uint32_t>(value); 122 *((uint32_t *)dst) = value; 123 } else if (length == 8) { 124 uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success); 125 if (!success) 126 return 0; 127 128 uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success); 129 if (!success) 130 return 0; 131 132 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) { 133 value1 = llvm::byteswap<uint32_t>(value1); 134 value2 = llvm::byteswap<uint32_t>(value2); 135 } 136 ((uint32_t *)dst)[0] = value1; 137 ((uint32_t *)dst)[1] = value2; 138 } else 139 success = false; 140 141 if (success) 142 return length; 143 144 return 0; 145 } 146 147 size_t EmulationStateARM::WritePseudoMemory( 148 EmulateInstruction *instruction, void *baton, 149 const EmulateInstruction::Context &context, lldb::addr_t addr, 150 const void *dst, size_t length) { 151 if (!baton) 152 return 0; 153 154 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton; 155 156 if (length <= 4) { 157 uint32_t value; 158 memcpy (&value, dst, sizeof (uint32_t)); 159 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) 160 value = llvm::byteswap<uint32_t>(value); 161 162 pseudo_state->StoreToPseudoAddress(addr, value); 163 return length; 164 } else if (length == 8) { 165 uint32_t value1; 166 uint32_t value2; 167 memcpy (&value1, dst, sizeof (uint32_t)); 168 memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t), 169 sizeof(uint32_t)); 170 if (endian::InlHostByteOrder() == lldb::eByteOrderBig) { 171 value1 = llvm::byteswap<uint32_t>(value1); 172 value2 = llvm::byteswap<uint32_t>(value2); 173 } 174 175 pseudo_state->StoreToPseudoAddress(addr, value1); 176 pseudo_state->StoreToPseudoAddress(addr + 4, value2); 177 return length; 178 } 179 180 return 0; 181 } 182 183 bool EmulationStateARM::ReadPseudoRegister( 184 EmulateInstruction *instruction, void *baton, 185 const lldb_private::RegisterInfo *reg_info, 186 lldb_private::RegisterValue ®_value) { 187 if (!baton || !reg_info) 188 return false; 189 190 bool success = true; 191 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton; 192 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF]; 193 assert(dwarf_reg_num != LLDB_INVALID_REGNUM); 194 uint64_t reg_uval = 195 pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success); 196 197 if (success) 198 success = reg_value.SetUInt(reg_uval, reg_info->byte_size); 199 return success; 200 } 201 202 bool EmulationStateARM::WritePseudoRegister( 203 EmulateInstruction *instruction, void *baton, 204 const EmulateInstruction::Context &context, 205 const lldb_private::RegisterInfo *reg_info, 206 const lldb_private::RegisterValue ®_value) { 207 if (!baton || !reg_info) 208 return false; 209 210 EmulationStateARM *pseudo_state = (EmulationStateARM *)baton; 211 const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF]; 212 assert(dwarf_reg_num != LLDB_INVALID_REGNUM); 213 return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num, 214 reg_value.GetAsUInt64()); 215 } 216 217 bool EmulationStateARM::CompareState(EmulationStateARM &other_state, 218 Stream &out_stream) { 219 bool match = true; 220 221 for (int i = 0; match && i < 17; ++i) { 222 if (m_gpr[i] != other_state.m_gpr[i]) { 223 match = false; 224 out_stream.Printf("r%d: 0x%x != 0x%x\n", i, m_gpr[i], 225 other_state.m_gpr[i]); 226 } 227 } 228 229 for (int i = 0; match && i < 32; ++i) { 230 if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i]) { 231 match = false; 232 out_stream.Printf("s%d: 0x%x != 0x%x\n", i, m_vfp_regs.s_regs[i], 233 other_state.m_vfp_regs.s_regs[i]); 234 } 235 } 236 237 for (int i = 0; match && i < 16; ++i) { 238 if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i]) { 239 match = false; 240 out_stream.Printf("d%d: 0x%" PRIx64 " != 0x%" PRIx64 "\n", i + 16, 241 m_vfp_regs.d_regs[i], other_state.m_vfp_regs.d_regs[i]); 242 } 243 } 244 245 // other_state is the expected state. If it has memory, check it. 246 if (!other_state.m_memory.empty() && m_memory != other_state.m_memory) { 247 match = false; 248 out_stream.Printf("memory does not match\n"); 249 out_stream.Printf("got memory:\n"); 250 for (auto p : m_memory) 251 out_stream.Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second); 252 out_stream.Printf("expected memory:\n"); 253 for (auto p : other_state.m_memory) 254 out_stream.Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second); 255 } 256 257 return match; 258 } 259 260 bool EmulationStateARM::LoadRegistersStateFromDictionary( 261 OptionValueDictionary *reg_dict, char kind, int first_reg, int num) { 262 StreamString sstr; 263 for (int i = 0; i < num; ++i) { 264 sstr.Clear(); 265 sstr.Printf("%c%d", kind, i); 266 OptionValueSP value_sp = reg_dict->GetValueForKey(sstr.GetString()); 267 if (value_sp.get() == nullptr) 268 return false; 269 uint64_t reg_value = value_sp->GetValueAs<uint64_t>().value_or(0); 270 StorePseudoRegisterValue(first_reg + i, reg_value); 271 } 272 273 return true; 274 } 275 276 bool EmulationStateARM::LoadStateFromDictionary( 277 OptionValueDictionary *test_data) { 278 static constexpr llvm::StringLiteral memory_key("memory"); 279 static constexpr llvm::StringLiteral 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() != nullptr) { 289 static constexpr llvm::StringLiteral address_key("address"); 290 static constexpr llvm::StringLiteral 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() == nullptr) 296 return false; 297 else 298 start_address = value_sp->GetValueAs<uint64_t>().value_or(0); 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() == nullptr) 311 return false; 312 uint64_t value = value_sp->GetValueAs<uint64_t>().value_or(0); 313 StoreToPseudoAddress(address, value); 314 address = address + 4; 315 } 316 } 317 318 value_sp = test_data->GetValueForKey(registers_key); 319 if (value_sp.get() == nullptr) 320 return false; 321 322 // Load General Registers 323 324 OptionValueDictionary *reg_dict = value_sp->GetAsDictionary(); 325 if (!LoadRegistersStateFromDictionary(reg_dict, 'r', dwarf_r0, 16)) 326 return false; 327 328 static constexpr llvm::StringLiteral cpsr_name("cpsr"); 329 value_sp = reg_dict->GetValueForKey(cpsr_name); 330 if (value_sp.get() == nullptr) 331 return false; 332 StorePseudoRegisterValue(dwarf_cpsr, 333 value_sp->GetValueAs<uint64_t>().value_or(0)); 334 335 // Load s/d Registers 336 // To prevent you giving both types in a state and overwriting 337 // one or the other, we'll expect to get either all S registers, 338 // or all D registers. Not a mix of the two. 339 bool found_s_registers = 340 LoadRegistersStateFromDictionary(reg_dict, 's', dwarf_s0, 32); 341 bool found_d_registers = 342 LoadRegistersStateFromDictionary(reg_dict, 'd', dwarf_d0, 32); 343 344 return found_s_registers != found_d_registers; 345 } 346