EmulateInstructionARM.cpp revision 82f16aa9f19678ffa20b92a8df926e933940d34d
1//===-- EmulateInstructionARM.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 <stdlib.h> 11 12#include "EmulateInstructionARM.h" 13#include "lldb/Core/ConstString.h" 14 15#include "Plugins/Process/Utility/ARMDefines.h" 16#include "Plugins/Process/Utility/ARMUtils.h" 17#include "Utility/ARM_DWARF_Registers.h" 18 19#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 20 // and CountTrailingZeros_32 function 21 22using namespace lldb; 23using namespace lldb_private; 24 25static inline uint32_t Align(uint32_t val, uint32_t alignment) 26{ 27 return alignment * (val / alignment); 28} 29 30//---------------------------------------------------------------------- 31// 32// ITSession implementation 33// 34//---------------------------------------------------------------------- 35 36// A8.6.50 37// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 38static unsigned short CountITSize(unsigned ITMask) { 39 // First count the trailing zeros of the IT mask. 40 unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 41 if (TZ > 3) 42 { 43 printf("Encoding error: IT Mask '0000'\n"); 44 return 0; 45 } 46 return (4 - TZ); 47} 48 49// Init ITState. Note that at least one bit is always 1 in mask. 50bool ITSession::InitIT(unsigned short bits7_0) 51{ 52 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 53 if (ITCounter == 0) 54 return false; 55 56 // A8.6.50 IT 57 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 58 if (FirstCond == 0xF) 59 { 60 printf("Encoding error: IT FirstCond '1111'\n"); 61 return false; 62 } 63 if (FirstCond == 0xE && ITCounter != 1) 64 { 65 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 66 return false; 67 } 68 69 ITState = bits7_0; 70 return true; 71} 72 73// Update ITState if necessary. 74void ITSession::ITAdvance() 75{ 76 assert(ITCounter); 77 --ITCounter; 78 if (ITCounter == 0) 79 ITState = 0; 80 else 81 { 82 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 83 SetBits32(ITState, 4, 0, NewITState4_0); 84 } 85} 86 87// Return true if we're inside an IT Block. 88bool ITSession::InITBlock() 89{ 90 return ITCounter != 0; 91} 92 93// Return true if we're the last instruction inside an IT Block. 94bool ITSession::LastInITBlock() 95{ 96 return ITCounter == 1; 97} 98 99// Get condition bits for the current thumb instruction. 100uint32_t ITSession::GetCond() 101{ 102 if (InITBlock()) 103 return Bits32(ITState, 7, 4); 104 else 105 return COND_AL; 106} 107 108// ARM constants used during decoding 109#define REG_RD 0 110#define LDM_REGLIST 1 111#define PC_REG 15 112#define PC_REGLIST_BIT 0x8000 113 114#define ARMv4 (1u << 0) 115#define ARMv4T (1u << 1) 116#define ARMv5T (1u << 2) 117#define ARMv5TE (1u << 3) 118#define ARMv5TEJ (1u << 4) 119#define ARMv6 (1u << 5) 120#define ARMv6K (1u << 6) 121#define ARMv6T2 (1u << 7) 122#define ARMv7 (1u << 8) 123#define ARMv8 (1u << 9) 124#define ARMvAll (0xffffffffu) 125 126#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 127#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 128#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 129 130//---------------------------------------------------------------------- 131// 132// EmulateInstructionARM implementation 133// 134//---------------------------------------------------------------------- 135 136void 137EmulateInstructionARM::Initialize () 138{ 139} 140 141void 142EmulateInstructionARM::Terminate () 143{ 144} 145 146// Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 147bool 148EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 149{ 150 EmulateInstruction::Context context; 151 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 152 context.SetNoArgs (); 153 154 uint32_t random_data = rand (); 155 const uint32_t addr_byte_size = GetAddressByteSize(); 156 157 if (!WriteMemoryUnsigned (context, address, random_data, addr_byte_size)) 158 return false; 159 160 return true; 161} 162 163// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 164bool 165EmulateInstructionARM::WriteBits32Unknown (int n) 166{ 167 EmulateInstruction::Context context; 168 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 169 context.SetNoArgs (); 170 171 bool success; 172 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 173 174 if (!success) 175 return false; 176 177 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 178 return false; 179 180 return true; 181} 182 183// Push Multiple Registers stores multiple registers to the stack, storing to 184// consecutive memory locations ending just below the address in SP, and updates 185// SP to point to the start of the stored data. 186bool 187EmulateInstructionARM::EmulatePush (ARMEncoding encoding) 188{ 189#if 0 190 // ARM pseudo code... 191 if (ConditionPassed()) 192 { 193 EncodingSpecificOperations(); 194 NullCheckIfThumbEE(13); 195 address = SP - 4*BitCount(registers); 196 197 for (i = 0 to 14) 198 { 199 if (registers<i> == ’1’) 200 { 201 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 202 MemA[address,4] = bits(32) UNKNOWN; 203 else 204 MemA[address,4] = R[i]; 205 address = address + 4; 206 } 207 } 208 209 if (registers<15> == ’1’) // Only possible for encoding A1 or A2 210 MemA[address,4] = PCStoreValue(); 211 212 SP = SP - 4*BitCount(registers); 213 } 214#endif 215 216 bool success = false; 217 const uint32_t opcode = OpcodeAsUnsigned (&success); 218 if (!success) 219 return false; 220 221 if (ConditionPassed()) 222 { 223 const uint32_t addr_byte_size = GetAddressByteSize(); 224 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 225 if (!success) 226 return false; 227 uint32_t registers = 0; 228 uint32_t Rt; // the source register 229 switch (encoding) { 230 case eEncodingT1: 231 registers = Bits32(opcode, 7, 0); 232 // The M bit represents LR. 233 if (Bit32(opcode, 8)) 234 registers |= (1u << 14); 235 // if BitCount(registers) < 1 then UNPREDICTABLE; 236 if (BitCount(registers) < 1) 237 return false; 238 break; 239 case eEncodingT2: 240 // Ignore bits 15 & 13. 241 registers = Bits32(opcode, 15, 0) & ~0xa000; 242 // if BitCount(registers) < 2 then UNPREDICTABLE; 243 if (BitCount(registers) < 2) 244 return false; 245 break; 246 case eEncodingT3: 247 Rt = Bits32(opcode, 15, 12); 248 // if BadReg(t) then UNPREDICTABLE; 249 if (BadReg(Rt)) 250 return false; 251 registers = (1u << Rt); 252 break; 253 case eEncodingA1: 254 registers = Bits32(opcode, 15, 0); 255 // Instead of return false, let's handle the following case as well, 256 // which amounts to pushing one reg onto the full descending stacks. 257 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 258 break; 259 case eEncodingA2: 260 Rt = Bits32(opcode, 15, 12); 261 // if t == 13 then UNPREDICTABLE; 262 if (Rt == dwarf_sp) 263 return false; 264 registers = (1u << Rt); 265 break; 266 default: 267 return false; 268 } 269 addr_t sp_offset = addr_byte_size * BitCount (registers); 270 addr_t addr = sp - sp_offset; 271 uint32_t i; 272 273 EmulateInstruction::Context context; 274 context.type = EmulateInstruction::eContextPushRegisterOnStack; 275 Register dwarf_reg; 276 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 277 for (i=0; i<15; ++i) 278 { 279 if (BitIsSet (registers, i)) 280 { 281 dwarf_reg.num = dwarf_r0 + i; 282 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 283 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 284 if (!success) 285 return false; 286 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 287 return false; 288 addr += addr_byte_size; 289 } 290 } 291 292 if (BitIsSet (registers, 15)) 293 { 294 dwarf_reg.num = dwarf_pc; 295 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 296 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 297 if (!success) 298 return false; 299 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 300 return false; 301 } 302 303 context.type = EmulateInstruction::eContextAdjustStackPointer; 304 context.SetImmediateSigned (-sp_offset); 305 306 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 307 return false; 308 } 309 return true; 310} 311 312// Pop Multiple Registers loads multiple registers from the stack, loading from 313// consecutive memory locations staring at the address in SP, and updates 314// SP to point just above the loaded data. 315bool 316EmulateInstructionARM::EmulatePop (ARMEncoding encoding) 317{ 318#if 0 319 // ARM pseudo code... 320 if (ConditionPassed()) 321 { 322 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 323 address = SP; 324 for i = 0 to 14 325 if registers<i> == ‘1’ then 326 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 327 if registers<15> == ‘1’ then 328 if UnalignedAllowed then 329 LoadWritePC(MemU[address,4]); 330 else 331 LoadWritePC(MemA[address,4]); 332 if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 333 if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 334 } 335#endif 336 337 bool success = false; 338 const uint32_t opcode = OpcodeAsUnsigned (&success); 339 if (!success) 340 return false; 341 342 if (ConditionPassed()) 343 { 344 const uint32_t addr_byte_size = GetAddressByteSize(); 345 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 346 if (!success) 347 return false; 348 uint32_t registers = 0; 349 uint32_t Rt; // the destination register 350 switch (encoding) { 351 case eEncodingT1: 352 registers = Bits32(opcode, 7, 0); 353 // The P bit represents PC. 354 if (Bit32(opcode, 8)) 355 registers |= (1u << 15); 356 // if BitCount(registers) < 1 then UNPREDICTABLE; 357 if (BitCount(registers) < 1) 358 return false; 359 break; 360 case eEncodingT2: 361 // Ignore bit 13. 362 registers = Bits32(opcode, 15, 0) & ~0x2000; 363 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 364 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 365 return false; 366 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 367 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 368 return false; 369 break; 370 case eEncodingT3: 371 Rt = Bits32(opcode, 15, 12); 372 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 373 if (Rt == 13) 374 return false; 375 if (Rt == 15 && InITBlock() && !LastInITBlock()) 376 return false; 377 registers = (1u << Rt); 378 break; 379 case eEncodingA1: 380 registers = Bits32(opcode, 15, 0); 381 // Instead of return false, let's handle the following case as well, 382 // which amounts to popping one reg from the full descending stacks. 383 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 384 385 // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 386 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 387 return false; 388 break; 389 case eEncodingA2: 390 Rt = Bits32(opcode, 15, 12); 391 // if t == 13 then UNPREDICTABLE; 392 if (Rt == dwarf_sp) 393 return false; 394 registers = (1u << Rt); 395 break; 396 default: 397 return false; 398 } 399 addr_t sp_offset = addr_byte_size * BitCount (registers); 400 addr_t addr = sp; 401 uint32_t i, data; 402 403 EmulateInstruction::Context context; 404 context.type = EmulateInstruction::eContextPopRegisterOffStack; 405 Register dwarf_reg; 406 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 407 for (i=0; i<15; ++i) 408 { 409 if (BitIsSet (registers, i)) 410 { 411 dwarf_reg.num = dwarf_r0 + i; 412 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 413 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 414 if (!success) 415 return false; 416 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 417 return false; 418 addr += addr_byte_size; 419 } 420 } 421 422 if (BitIsSet (registers, 15)) 423 { 424 dwarf_reg.num = dwarf_pc; 425 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 426 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 427 if (!success) 428 return false; 429 // In ARMv5T and above, this is an interworking branch. 430 if (!LoadWritePC(context, data, dwarf_reg)) 431 return false; 432 addr += addr_byte_size; 433 } 434 435 context.type = EmulateInstruction::eContextAdjustStackPointer; 436 context.SetImmediateSigned (sp_offset); 437 438 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 439 return false; 440 } 441 return true; 442} 443 444// Set r7 or ip to point to saved value residing within the stack. 445// ADD (SP plus immediate) 446bool 447EmulateInstructionARM::EmulateAddRdSPImmediate (ARMEncoding encoding) 448{ 449#if 0 450 // ARM pseudo code... 451 if (ConditionPassed()) 452 { 453 EncodingSpecificOperations(); 454 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 455 if d == 15 then 456 ALUWritePC(result); // setflags is always FALSE here 457 else 458 R[d] = result; 459 if setflags then 460 APSR.N = result<31>; 461 APSR.Z = IsZeroBit(result); 462 APSR.C = carry; 463 APSR.V = overflow; 464 } 465#endif 466 467 bool success = false; 468 const uint32_t opcode = OpcodeAsUnsigned (&success); 469 if (!success) 470 return false; 471 472 if (ConditionPassed()) 473 { 474 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 475 if (!success) 476 return false; 477 uint32_t Rd; // the destination register 478 uint32_t imm32; 479 switch (encoding) { 480 case eEncodingT1: 481 Rd = 7; 482 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 483 break; 484 case eEncodingA1: 485 Rd = Bits32(opcode, 15, 12); 486 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 487 break; 488 default: 489 return false; 490 } 491 addr_t sp_offset = imm32; 492 addr_t addr = sp + sp_offset; // a pointer to the stack area 493 494 EmulateInstruction::Context context; 495 context.type = EmulateInstruction::eContextRegisterPlusOffset; 496 Register sp_reg; 497 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 498 context.SetRegisterPlusOffset (sp_reg, sp_offset); 499 500 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 501 return false; 502 } 503 return true; 504} 505 506// Set r7 or ip to the current stack pointer. 507// MOV (register) 508bool 509EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding) 510{ 511#if 0 512 // ARM pseudo code... 513 if (ConditionPassed()) 514 { 515 EncodingSpecificOperations(); 516 result = R[m]; 517 if d == 15 then 518 ALUWritePC(result); // setflags is always FALSE here 519 else 520 R[d] = result; 521 if setflags then 522 APSR.N = result<31>; 523 APSR.Z = IsZeroBit(result); 524 // APSR.C unchanged 525 // APSR.V unchanged 526 } 527#endif 528 529 bool success = false; 530 //const uint32_t opcode = OpcodeAsUnsigned (&success); 531 //if (!success) 532 // return false; 533 534 if (ConditionPassed()) 535 { 536 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 537 if (!success) 538 return false; 539 uint32_t Rd; // the destination register 540 switch (encoding) { 541 case eEncodingT1: 542 Rd = 7; 543 break; 544 case eEncodingA1: 545 Rd = 12; 546 break; 547 default: 548 return false; 549 } 550 551 EmulateInstruction::Context context; 552 context.type = EmulateInstruction::eContextRegisterPlusOffset; 553 Register sp_reg; 554 sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 555 context.SetRegisterPlusOffset (sp_reg, 0); 556 557 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 558 return false; 559 } 560 return true; 561} 562 563// Move from high register (r8-r15) to low register (r0-r7). 564// MOV (register) 565bool 566EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding) 567{ 568 return EmulateMovRdRm (encoding); 569} 570 571// Move from register to register. 572// MOV (register) 573bool 574EmulateInstructionARM::EmulateMovRdRm (ARMEncoding encoding) 575{ 576#if 0 577 // ARM pseudo code... 578 if (ConditionPassed()) 579 { 580 EncodingSpecificOperations(); 581 result = R[m]; 582 if d == 15 then 583 ALUWritePC(result); // setflags is always FALSE here 584 else 585 R[d] = result; 586 if setflags then 587 APSR.N = result<31>; 588 APSR.Z = IsZeroBit(result); 589 // APSR.C unchanged 590 // APSR.V unchanged 591 } 592#endif 593 594 bool success = false; 595 const uint32_t opcode = OpcodeAsUnsigned (&success); 596 if (!success) 597 return false; 598 599 if (ConditionPassed()) 600 { 601 uint32_t Rm; // the source register 602 uint32_t Rd; // the destination register 603 bool setflags; 604 switch (encoding) { 605 case eEncodingT1: 606 Rm = Bits32(opcode, 6, 3); 607 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 1); 608 setflags = false; 609 break; 610 case eEncodingT2: 611 Rm = Bits32(opcode, 5, 3); 612 Rd = Bits32(opcode, 2, 1); 613 setflags = true; 614 break; 615 default: 616 return false; 617 } 618 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 619 if (!success) 620 return false; 621 622 // The context specifies that Rm is to be moved into Rd. 623 EmulateInstruction::Context context; 624 context.type = EmulateInstruction::eContextRegisterPlusOffset; 625 Register dwarf_reg; 626 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 627 context.SetRegisterPlusOffset (dwarf_reg, 0); 628 629 if (Rd == 15) 630 { 631 if (!ALUWritePC (context, reg_value, dwarf_reg)) 632 return false; 633 } 634 else 635 { 636 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value)) 637 return false; 638 if (setflags) 639 { 640 m_new_inst_cpsr = m_inst_cpsr; 641 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(reg_value, CPSR_N)); 642 SetBit32(m_new_inst_cpsr, CPSR_Z, reg_value == 0 ? 1 : 0); 643 if (m_new_inst_cpsr != m_inst_cpsr) 644 { 645 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 646 return false; 647 } 648 } 649 } 650 } 651 return true; 652} 653 654// Move (immediate) writes an immediate value to the destination register. It 655// can optionally update the condition flags based on the value. 656// MOV (immediate) 657bool 658EmulateInstructionARM::EmulateMovRdImm (ARMEncoding encoding) 659{ 660#if 0 661 // ARM pseudo code... 662 if (ConditionPassed()) 663 { 664 EncodingSpecificOperations(); 665 result = imm32; 666 if d == 15 then // Can only occur for ARM encoding 667 ALUWritePC(result); // setflags is always FALSE here 668 else 669 R[d] = result; 670 if setflags then 671 APSR.N = result<31>; 672 APSR.Z = IsZeroBit(result); 673 APSR.C = carry; 674 // APSR.V unchanged 675 } 676#endif 677 bool success = false; 678 const uint32_t opcode = OpcodeAsUnsigned (&success); 679 if (!success) 680 return false; 681 682 if (ConditionPassed()) 683 { 684 uint32_t Rd; // the destination register 685 uint32_t imm12; // some intermediate result 686 uint32_t imm32; // the immediate value to be written to Rd 687 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 688 bool setflags; 689 switch (encoding) { 690 case eEncodingT1: 691 Rd = Bits32(opcode, 11, 8); 692 setflags = !InITBlock(); 693 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 694 carry = Bit32(m_inst_cpsr, CPSR_C); 695 break; 696 case eEncodingT2: 697 Rd = Bits32(opcode, 15, 12); 698 setflags = BitIsSet(opcode, 20); 699 imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0); 700 imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 701 if (BadReg(Rd)) 702 return false; 703 break; 704 default: 705 return false; 706 } 707 uint32_t result = imm32; 708 709 // The context specifies that an immediate is to be moved into Rd. 710 EmulateInstruction::Context context; 711 context.type = EmulateInstruction::eContextImmediate; 712 context.SetNoArgs (); 713 714 Register dummy_reg; 715 dummy_reg.SetRegister (eRegisterKindDWARF, dwarf_r0); 716 717 if (Rd == 15) 718 { 719 if (!ALUWritePC (context, result, dummy_reg)) 720 return false; 721 } 722 else 723 { 724 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 725 return false; 726 if (setflags) 727 { 728 m_new_inst_cpsr = m_inst_cpsr; 729 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 730 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 731 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 732 if (m_new_inst_cpsr != m_inst_cpsr) 733 { 734 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 735 return false; 736 } 737 } 738 } 739 } 740 return true; 741} 742 743// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 744// the destination register. It can optionally update the condition flags based 745// on the value. 746// MVN (immediate) 747bool 748EmulateInstructionARM::EmulateMvnRdImm (ARMEncoding encoding) 749{ 750#if 0 751 // ARM pseudo code... 752 if (ConditionPassed()) 753 { 754 EncodingSpecificOperations(); 755 result = NOT(imm32); 756 if d == 15 then // Can only occur for ARM encoding 757 ALUWritePC(result); // setflags is always FALSE here 758 else 759 R[d] = result; 760 if setflags then 761 APSR.N = result<31>; 762 APSR.Z = IsZeroBit(result); 763 APSR.C = carry; 764 // APSR.V unchanged 765 } 766#endif 767 bool success = false; 768 const uint32_t opcode = OpcodeAsUnsigned (&success); 769 if (!success) 770 return false; 771 772 if (ConditionPassed()) 773 { 774 uint32_t Rd; // the destination register 775 uint32_t imm12; // the first operand to ThumbExpandImm_C or ARMExpandImm_C 776 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 777 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 778 bool setflags; 779 switch (encoding) { 780 case eEncodingT1: 781 Rd = Bits32(opcode, 11, 8); 782 setflags = BitIsSet(opcode, 20); 783 imm12 = Bit32(opcode, 26) << 11 | Bits32(opcode, 14, 12) << 8 | Bits32(opcode, 7, 0); 784 imm32 = ThumbExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 785 break; 786 case eEncodingA1: 787 Rd = Bits32(opcode, 15, 12); 788 setflags = BitIsSet(opcode, 20); 789 imm12 = Bits32(opcode, 11, 0); 790 imm32 = ARMExpandImm_C(imm12, Bit32(m_inst_cpsr, CPSR_C), carry); 791 break; 792 default: 793 return false; 794 } 795 uint32_t result = ~imm32; 796 797 // The context specifies that an immediate is to be moved into Rd. 798 EmulateInstruction::Context context; 799 context.type = EmulateInstruction::eContextImmediate; 800 context.SetNoArgs (); 801 802 if (Rd == 15) 803 { 804 Register dummy_reg; 805 if (!ALUWritePC (context, result, dummy_reg)) 806 return false; 807 } 808 else 809 { 810 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 811 return false; 812 if (setflags) 813 { 814 m_new_inst_cpsr = m_inst_cpsr; 815 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 816 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 817 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 818 if (m_new_inst_cpsr != m_inst_cpsr) 819 { 820 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 821 return false; 822 } 823 } 824 } 825 } 826 return true; 827} 828 829// PC relative immediate load into register, possibly followed by ADD (SP plus register). 830// LDR (literal) 831bool 832EmulateInstructionARM::EmulateLDRRtPCRelative (ARMEncoding encoding) 833{ 834#if 0 835 // ARM pseudo code... 836 if (ConditionPassed()) 837 { 838 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 839 base = Align(PC,4); 840 address = if add then (base + imm32) else (base - imm32); 841 data = MemU[address,4]; 842 if t == 15 then 843 if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 844 elsif UnalignedSupport() || address<1:0> = ‘00’ then 845 R[t] = data; 846 else // Can only apply before ARMv7 847 if CurrentInstrSet() == InstrSet_ARM then 848 R[t] = ROR(data, 8*UInt(address<1:0>)); 849 else 850 R[t] = bits(32) UNKNOWN; 851 } 852#endif 853 854 bool success = false; 855 const uint32_t opcode = OpcodeAsUnsigned (&success); 856 if (!success) 857 return false; 858 859 if (ConditionPassed()) 860 { 861 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 862 if (!success) 863 return false; 864 865 // PC relative immediate load context 866 EmulateInstruction::Context context; 867 context.type = EmulateInstruction::eContextRegisterPlusOffset; 868 Register pc_reg; 869 pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 870 context.SetRegisterPlusOffset (pc_reg, 0); 871 872 uint32_t Rt; // the destination register 873 uint32_t imm32; // immediate offset from the PC 874 bool add; // +imm32 or -imm32? 875 addr_t base; // the base address 876 addr_t address; // the PC relative address 877 uint32_t data; // the literal data value from the PC relative load 878 switch (encoding) { 879 case eEncodingT1: 880 Rt = Bits32(opcode, 10, 8); 881 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 882 add = true; 883 base = Align(pc + 4, 4); 884 context.SetRegisterPlusOffset (pc_reg, 4 + imm32); 885 break; 886 case eEncodingT2: 887 Rt = Bits32(opcode, 15, 12); 888 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 889 add = BitIsSet(opcode, 23); 890 if (Rt == 15 && InITBlock() && !LastInITBlock()) 891 return false; 892 base = Align(pc + 4, 4); 893 context.SetRegisterPlusOffset (pc_reg, 4 + imm32); 894 break; 895 default: 896 return false; 897 } 898 899 if (add) 900 address = base + imm32; 901 else 902 address = base - imm32; 903 data = ReadMemoryUnsigned(context, address, 4, 0, &success); 904 if (!success) 905 return false; 906 907 if (Rt == 15) 908 { 909 if (Bits32(address, 1, 0) == 0) 910 { 911 // In ARMv5T and above, this is an interworking branch. 912 if (!LoadWritePC(context, data, pc_reg)) 913 return false; 914 } 915 else 916 return false; 917 } 918 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 919 { 920 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 921 return false; 922 } 923 else // We don't handle ARM for now. 924 return false; 925 926 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 927 return false; 928 } 929 return true; 930} 931 932// An add operation to adjust the SP. 933// ADD (SP plus immediate) 934bool 935EmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding) 936{ 937#if 0 938 // ARM pseudo code... 939 if (ConditionPassed()) 940 { 941 EncodingSpecificOperations(); 942 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 943 if d == 15 then // Can only occur for ARM encoding 944 ALUWritePC(result); // setflags is always FALSE here 945 else 946 R[d] = result; 947 if setflags then 948 APSR.N = result<31>; 949 APSR.Z = IsZeroBit(result); 950 APSR.C = carry; 951 APSR.V = overflow; 952 } 953#endif 954 955 bool success = false; 956 const uint32_t opcode = OpcodeAsUnsigned (&success); 957 if (!success) 958 return false; 959 960 if (ConditionPassed()) 961 { 962 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 963 if (!success) 964 return false; 965 uint32_t imm32; // the immediate operand 966 switch (encoding) { 967 case eEncodingT2: 968 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 969 break; 970 default: 971 return false; 972 } 973 addr_t sp_offset = imm32; 974 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 975 976 EmulateInstruction::Context context; 977 context.type = EmulateInstruction::eContextAdjustStackPointer; 978 context.SetImmediateSigned (sp_offset); 979 980 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 981 return false; 982 } 983 return true; 984} 985 986// An add operation to adjust the SP. 987// ADD (SP plus register) 988bool 989EmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding) 990{ 991#if 0 992 // ARM pseudo code... 993 if (ConditionPassed()) 994 { 995 EncodingSpecificOperations(); 996 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 997 (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 998 if d == 15 then 999 ALUWritePC(result); // setflags is always FALSE here 1000 else 1001 R[d] = result; 1002 if setflags then 1003 APSR.N = result<31>; 1004 APSR.Z = IsZeroBit(result); 1005 APSR.C = carry; 1006 APSR.V = overflow; 1007 } 1008#endif 1009 1010 bool success = false; 1011 const uint32_t opcode = OpcodeAsUnsigned (&success); 1012 if (!success) 1013 return false; 1014 1015 if (ConditionPassed()) 1016 { 1017 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1018 if (!success) 1019 return false; 1020 uint32_t Rm; // the second operand 1021 switch (encoding) { 1022 case eEncodingT2: 1023 Rm = Bits32(opcode, 6, 3); 1024 break; 1025 default: 1026 return false; 1027 } 1028 int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1029 if (!success) 1030 return false; 1031 1032 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1033 1034 EmulateInstruction::Context context; 1035 context.type = EmulateInstruction::eContextAdjustStackPointer; 1036 context.SetImmediateSigned (reg_value); 1037 1038 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1039 return false; 1040 } 1041 return true; 1042} 1043 1044// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1045// at a PC-relative address, and changes instruction set from ARM to Thumb, or 1046// from Thumb to ARM. 1047// BLX (immediate) 1048bool 1049EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 1050{ 1051#if 0 1052 // ARM pseudo code... 1053 if (ConditionPassed()) 1054 { 1055 EncodingSpecificOperations(); 1056 if CurrentInstrSet() == InstrSet_ARM then 1057 LR = PC - 4; 1058 else 1059 LR = PC<31:1> : '1'; 1060 if targetInstrSet == InstrSet_ARM then 1061 targetAddress = Align(PC,4) + imm32; 1062 else 1063 targetAddress = PC + imm32; 1064 SelectInstrSet(targetInstrSet); 1065 BranchWritePC(targetAddress); 1066 } 1067#endif 1068 1069 bool success = false; 1070 const uint32_t opcode = OpcodeAsUnsigned (&success); 1071 if (!success) 1072 return false; 1073 1074 if (ConditionPassed()) 1075 { 1076 EmulateInstruction::Context context; 1077 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1078 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1079 if (!success) 1080 return false; 1081 addr_t lr; // next instruction address 1082 addr_t target; // target address 1083 int32_t imm32; // PC-relative offset 1084 switch (encoding) { 1085 case eEncodingT1: 1086 { 1087 lr = (pc + 4) | 1u; // return address 1088 uint32_t S = Bit32(opcode, 26); 1089 uint32_t imm10 = Bits32(opcode, 25, 16); 1090 uint32_t J1 = Bit32(opcode, 13); 1091 uint32_t J2 = Bit32(opcode, 11); 1092 uint32_t imm11 = Bits32(opcode, 10, 0); 1093 uint32_t I1 = !(J1 ^ S); 1094 uint32_t I2 = !(J2 ^ S); 1095 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1096 imm32 = llvm::SignExtend32<25>(imm25); 1097 target = pc + 4 + imm32; 1098 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1099 if (InITBlock() && !LastInITBlock()) 1100 return false; 1101 break; 1102 } 1103 case eEncodingT2: 1104 { 1105 lr = (pc + 4) | 1u; // return address 1106 uint32_t S = Bit32(opcode, 26); 1107 uint32_t imm10H = Bits32(opcode, 25, 16); 1108 uint32_t J1 = Bit32(opcode, 13); 1109 uint32_t J2 = Bit32(opcode, 11); 1110 uint32_t imm10L = Bits32(opcode, 10, 1); 1111 uint32_t I1 = !(J1 ^ S); 1112 uint32_t I2 = !(J2 ^ S); 1113 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1114 imm32 = llvm::SignExtend32<25>(imm25); 1115 target = Align(pc + 4, 4) + imm32; 1116 context.SetModeAndImmediateSigned (eModeARM, 4 + imm32); 1117 if (InITBlock() && !LastInITBlock()) 1118 return false; 1119 break; 1120 } 1121 case eEncodingA1: 1122 lr = pc + 4; // return address 1123 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1124 target = Align(pc + 8, 4) + imm32; 1125 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1126 break; 1127 case eEncodingA2: 1128 lr = pc + 4; // return address 1129 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1130 target = pc + 8 + imm32; 1131 context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32); 1132 break; 1133 default: 1134 return false; 1135 } 1136 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1137 return false; 1138 if (!BranchWritePC(context, target)) 1139 return false; 1140 } 1141 return true; 1142} 1143 1144// Branch with Link and Exchange (register) calls a subroutine at an address and 1145// instruction set specified by a register. 1146// BLX (register) 1147bool 1148EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 1149{ 1150#if 0 1151 // ARM pseudo code... 1152 if (ConditionPassed()) 1153 { 1154 EncodingSpecificOperations(); 1155 target = R[m]; 1156 if CurrentInstrSet() == InstrSet_ARM then 1157 next_instr_addr = PC - 4; 1158 LR = next_instr_addr; 1159 else 1160 next_instr_addr = PC - 2; 1161 LR = next_instr_addr<31:1> : ‘1’; 1162 BXWritePC(target); 1163 } 1164#endif 1165 1166 bool success = false; 1167 const uint32_t opcode = OpcodeAsUnsigned (&success); 1168 if (!success) 1169 return false; 1170 1171 if (ConditionPassed()) 1172 { 1173 EmulateInstruction::Context context; 1174 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1175 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1176 addr_t lr; // next instruction address 1177 if (!success) 1178 return false; 1179 uint32_t Rm; // the register with the target address 1180 switch (encoding) { 1181 case eEncodingT1: 1182 lr = (pc + 2) | 1u; // return address 1183 Rm = Bits32(opcode, 6, 3); 1184 // if m == 15 then UNPREDICTABLE; 1185 if (Rm == 15) 1186 return false; 1187 if (InITBlock() && !LastInITBlock()) 1188 return false; 1189 break; 1190 case eEncodingA1: 1191 lr = pc + 4; // return address 1192 Rm = Bits32(opcode, 3, 0); 1193 // if m == 15 then UNPREDICTABLE; 1194 if (Rm == 15) 1195 return false; 1196 break; 1197 default: 1198 return false; 1199 } 1200 addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1201 if (!success) 1202 return false; 1203 Register dwarf_reg; 1204 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1205 context.SetRegister (dwarf_reg); 1206 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1207 return false; 1208 if (!BXWritePC(context, target, dwarf_reg)) 1209 return false; 1210 } 1211 return true; 1212} 1213 1214// Branch and Exchange causes a branch to an address and instruction set specified by a register. 1215// BX 1216bool 1217EmulateInstructionARM::EmulateBXRm (ARMEncoding encoding) 1218{ 1219#if 0 1220 // ARM pseudo code... 1221 if (ConditionPassed()) 1222 { 1223 EncodingSpecificOperations(); 1224 BXWritePC(R[m]); 1225 } 1226#endif 1227 1228 bool success = false; 1229 const uint32_t opcode = OpcodeAsUnsigned (&success); 1230 if (!success) 1231 return false; 1232 1233 if (ConditionPassed()) 1234 { 1235 EmulateInstruction::Context context; 1236 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1237 uint32_t Rm; // the register with the target address 1238 switch (encoding) { 1239 case eEncodingT1: 1240 Rm = Bits32(opcode, 6, 3); 1241 if (InITBlock() && !LastInITBlock()) 1242 return false; 1243 break; 1244 case eEncodingA1: 1245 Rm = Bits32(opcode, 3, 0); 1246 break; 1247 default: 1248 return false; 1249 } 1250 addr_t target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1251 if (!success) 1252 return false; 1253 1254 Register dwarf_reg; 1255 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); 1256 if (!BXWritePC(context, target, dwarf_reg)) 1257 return false; 1258 } 1259 return true; 1260} 1261 1262// Set r7 to point to some ip offset. 1263// SUB (immediate) 1264bool 1265EmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding) 1266{ 1267#if 0 1268 // ARM pseudo code... 1269 if (ConditionPassed()) 1270 { 1271 EncodingSpecificOperations(); 1272 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1273 if d == 15 then // Can only occur for ARM encoding 1274 ALUWritePC(result); // setflags is always FALSE here 1275 else 1276 R[d] = result; 1277 if setflags then 1278 APSR.N = result<31>; 1279 APSR.Z = IsZeroBit(result); 1280 APSR.C = carry; 1281 APSR.V = overflow; 1282 } 1283#endif 1284 1285 bool success = false; 1286 const uint32_t opcode = OpcodeAsUnsigned (&success); 1287 if (!success) 1288 return false; 1289 1290 if (ConditionPassed()) 1291 { 1292 const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success); 1293 if (!success) 1294 return false; 1295 uint32_t imm32; 1296 switch (encoding) { 1297 case eEncodingA1: 1298 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1299 break; 1300 default: 1301 return false; 1302 } 1303 addr_t ip_offset = imm32; 1304 addr_t addr = ip - ip_offset; // the adjusted ip value 1305 1306 EmulateInstruction::Context context; 1307 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1308 Register dwarf_reg; 1309 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12); 1310 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1311 1312 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1313 return false; 1314 } 1315 return true; 1316} 1317 1318// Set ip to point to some stack offset. 1319// SUB (SP minus immediate) 1320bool 1321EmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding) 1322{ 1323#if 0 1324 // ARM pseudo code... 1325 if (ConditionPassed()) 1326 { 1327 EncodingSpecificOperations(); 1328 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1329 if d == 15 then // Can only occur for ARM encoding 1330 ALUWritePC(result); // setflags is always FALSE here 1331 else 1332 R[d] = result; 1333 if setflags then 1334 APSR.N = result<31>; 1335 APSR.Z = IsZeroBit(result); 1336 APSR.C = carry; 1337 APSR.V = overflow; 1338 } 1339#endif 1340 1341 bool success = false; 1342 const uint32_t opcode = OpcodeAsUnsigned (&success); 1343 if (!success) 1344 return false; 1345 1346 if (ConditionPassed()) 1347 { 1348 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1349 if (!success) 1350 return false; 1351 uint32_t imm32; 1352 switch (encoding) { 1353 case eEncodingA1: 1354 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1355 break; 1356 default: 1357 return false; 1358 } 1359 addr_t sp_offset = imm32; 1360 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1361 1362 EmulateInstruction::Context context; 1363 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1364 Register dwarf_reg; 1365 dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 1366 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1367 1368 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1369 return false; 1370 } 1371 return true; 1372} 1373 1374// A sub operation to adjust the SP -- allocate space for local storage. 1375bool 1376EmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding) 1377{ 1378#if 0 1379 // ARM pseudo code... 1380 if (ConditionPassed()) 1381 { 1382 EncodingSpecificOperations(); 1383 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1384 if d == 15 then // Can only occur for ARM encoding 1385 ALUWritePC(result); // setflags is always FALSE here 1386 else 1387 R[d] = result; 1388 if setflags then 1389 APSR.N = result<31>; 1390 APSR.Z = IsZeroBit(result); 1391 APSR.C = carry; 1392 APSR.V = overflow; 1393 } 1394#endif 1395 1396 bool success = false; 1397 const uint32_t opcode = OpcodeAsUnsigned (&success); 1398 if (!success) 1399 return false; 1400 1401 if (ConditionPassed()) 1402 { 1403 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1404 if (!success) 1405 return false; 1406 uint32_t imm32; 1407 switch (encoding) { 1408 case eEncodingT1: 1409 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1410 case eEncodingT2: 1411 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1412 break; 1413 case eEncodingT3: 1414 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1415 break; 1416 case eEncodingA1: 1417 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1418 break; 1419 default: 1420 return false; 1421 } 1422 addr_t sp_offset = imm32; 1423 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1424 1425 EmulateInstruction::Context context; 1426 context.type = EmulateInstruction::eContextAdjustStackPointer; 1427 context.SetImmediateSigned (-sp_offset); 1428 1429 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1430 return false; 1431 } 1432 return true; 1433} 1434 1435// A store operation to the stack that also updates the SP. 1436bool 1437EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1438{ 1439#if 0 1440 // ARM pseudo code... 1441 if (ConditionPassed()) 1442 { 1443 EncodingSpecificOperations(); 1444 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1445 address = if index then offset_addr else R[n]; 1446 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1447 if wback then R[n] = offset_addr; 1448 } 1449#endif 1450 1451 bool success = false; 1452 const uint32_t opcode = OpcodeAsUnsigned (&success); 1453 if (!success) 1454 return false; 1455 1456 if (ConditionPassed()) 1457 { 1458 const uint32_t addr_byte_size = GetAddressByteSize(); 1459 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1460 if (!success) 1461 return false; 1462 uint32_t Rt; // the source register 1463 uint32_t imm12; 1464 switch (encoding) { 1465 case eEncodingA1: 1466 Rt = Bits32(opcode, 15, 12); 1467 imm12 = Bits32(opcode, 11, 0); 1468 break; 1469 default: 1470 return false; 1471 } 1472 addr_t sp_offset = imm12; 1473 addr_t addr = sp - sp_offset; 1474 1475 EmulateInstruction::Context context; 1476 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1477 Register dwarf_reg; 1478 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1479 if (Rt != 15) 1480 { 1481 dwarf_reg.num = dwarf_r0 + Rt; 1482 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1483 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1484 if (!success) 1485 return false; 1486 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 1487 return false; 1488 } 1489 else 1490 { 1491 dwarf_reg.num = dwarf_pc; 1492 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1493 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1494 if (!success) 1495 return false; 1496 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 1497 return false; 1498 } 1499 1500 context.type = EmulateInstruction::eContextAdjustStackPointer; 1501 context.SetImmediateSigned (-sp_offset); 1502 1503 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1504 return false; 1505 } 1506 return true; 1507} 1508 1509// Vector Push stores multiple extension registers to the stack. 1510// It also updates SP to point to the start of the stored data. 1511bool 1512EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1513{ 1514#if 0 1515 // ARM pseudo code... 1516 if (ConditionPassed()) 1517 { 1518 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1519 address = SP - imm32; 1520 SP = SP - imm32; 1521 if single_regs then 1522 for r = 0 to regs-1 1523 MemA[address,4] = S[d+r]; address = address+4; 1524 else 1525 for r = 0 to regs-1 1526 // Store as two word-aligned words in the correct order for current endianness. 1527 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1528 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1529 address = address+8; 1530 } 1531#endif 1532 1533 bool success = false; 1534 const uint32_t opcode = OpcodeAsUnsigned (&success); 1535 if (!success) 1536 return false; 1537 1538 if (ConditionPassed()) 1539 { 1540 const uint32_t addr_byte_size = GetAddressByteSize(); 1541 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1542 if (!success) 1543 return false; 1544 bool single_regs; 1545 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1546 uint32_t imm32; // stack offset 1547 uint32_t regs; // number of registers 1548 switch (encoding) { 1549 case eEncodingT1: 1550 case eEncodingA1: 1551 single_regs = false; 1552 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1553 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1554 // If UInt(imm8) is odd, see "FSTMX". 1555 regs = Bits32(opcode, 7, 0) / 2; 1556 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1557 if (regs == 0 || regs > 16 || (d + regs) > 32) 1558 return false; 1559 break; 1560 case eEncodingT2: 1561 case eEncodingA2: 1562 single_regs = true; 1563 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1564 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1565 regs = Bits32(opcode, 7, 0); 1566 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1567 if (regs == 0 || regs > 16 || (d + regs) > 32) 1568 return false; 1569 break; 1570 default: 1571 return false; 1572 } 1573 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1574 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1575 addr_t sp_offset = imm32; 1576 addr_t addr = sp - sp_offset; 1577 uint32_t i; 1578 1579 EmulateInstruction::Context context; 1580 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1581 Register dwarf_reg; 1582 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1583 for (i=d; i<regs; ++i) 1584 { 1585 dwarf_reg.num = start_reg + i; 1586 context.SetRegisterPlusOffset ( dwarf_reg, addr - sp); 1587 // uint64_t to accommodate 64-bit registers. 1588 uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success); 1589 if (!success) 1590 return false; 1591 if (!WriteMemoryUnsigned (context, addr, reg_value, reg_byte_size)) 1592 return false; 1593 addr += reg_byte_size; 1594 } 1595 1596 context.type = EmulateInstruction::eContextAdjustStackPointer; 1597 context.SetImmediateSigned (-sp_offset); 1598 1599 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1600 return false; 1601 } 1602 return true; 1603} 1604 1605// Vector Pop loads multiple extension registers from the stack. 1606// It also updates SP to point just above the loaded data. 1607bool 1608EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1609{ 1610#if 0 1611 // ARM pseudo code... 1612 if (ConditionPassed()) 1613 { 1614 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1615 address = SP; 1616 SP = SP + imm32; 1617 if single_regs then 1618 for r = 0 to regs-1 1619 S[d+r] = MemA[address,4]; address = address+4; 1620 else 1621 for r = 0 to regs-1 1622 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1623 // Combine the word-aligned words in the correct order for current endianness. 1624 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1625 } 1626#endif 1627 1628 bool success = false; 1629 const uint32_t opcode = OpcodeAsUnsigned (&success); 1630 if (!success) 1631 return false; 1632 1633 if (ConditionPassed()) 1634 { 1635 const uint32_t addr_byte_size = GetAddressByteSize(); 1636 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1637 if (!success) 1638 return false; 1639 bool single_regs; 1640 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1641 uint32_t imm32; // stack offset 1642 uint32_t regs; // number of registers 1643 switch (encoding) { 1644 case eEncodingT1: 1645 case eEncodingA1: 1646 single_regs = false; 1647 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 1648 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1649 // If UInt(imm8) is odd, see "FLDMX". 1650 regs = Bits32(opcode, 7, 0) / 2; 1651 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1652 if (regs == 0 || regs > 16 || (d + regs) > 32) 1653 return false; 1654 break; 1655 case eEncodingT2: 1656 case eEncodingA2: 1657 single_regs = true; 1658 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 1659 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1660 regs = Bits32(opcode, 7, 0); 1661 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1662 if (regs == 0 || regs > 16 || (d + regs) > 32) 1663 return false; 1664 break; 1665 default: 1666 return false; 1667 } 1668 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1669 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1670 addr_t sp_offset = imm32; 1671 addr_t addr = sp; 1672 uint32_t i; 1673 uint64_t data; // uint64_t to accomodate 64-bit registers. 1674 1675 EmulateInstruction::Context context; 1676 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1677 Register dwarf_reg; 1678 dwarf_reg.SetRegister (eRegisterKindDWARF, 0); 1679 for (i=d; i<regs; ++i) 1680 { 1681 dwarf_reg.num = start_reg + i; 1682 context.SetRegisterPlusOffset (dwarf_reg, addr - sp); 1683 data = ReadMemoryUnsigned(context, addr, reg_byte_size, 0, &success); 1684 if (!success) 1685 return false; 1686 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data)) 1687 return false; 1688 addr += reg_byte_size; 1689 } 1690 1691 context.type = EmulateInstruction::eContextAdjustStackPointer; 1692 context.SetImmediateSigned (sp_offset); 1693 1694 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1695 return false; 1696 } 1697 return true; 1698} 1699 1700// SVC (previously SWI) 1701bool 1702EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1703{ 1704#if 0 1705 // ARM pseudo code... 1706 if (ConditionPassed()) 1707 { 1708 EncodingSpecificOperations(); 1709 CallSupervisor(); 1710 } 1711#endif 1712 1713 bool success = false; 1714 const uint32_t opcode = OpcodeAsUnsigned (&success); 1715 if (!success) 1716 return false; 1717 1718 if (ConditionPassed()) 1719 { 1720 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1721 addr_t lr; // next instruction address 1722 if (!success) 1723 return false; 1724 uint32_t imm32; // the immediate constant 1725 uint32_t mode; // ARM or Thumb mode 1726 switch (encoding) { 1727 case eEncodingT1: 1728 lr = (pc + 2) | 1u; // return address 1729 imm32 = Bits32(opcode, 7, 0); 1730 mode = eModeThumb; 1731 break; 1732 case eEncodingA1: 1733 lr = pc + 4; // return address 1734 imm32 = Bits32(opcode, 23, 0); 1735 mode = eModeARM; 1736 break; 1737 default: 1738 return false; 1739 } 1740 1741 EmulateInstruction::Context context; 1742 context.type = EmulateInstruction::eContextSupervisorCall; 1743 context.SetModeAndImmediate (mode, imm32); 1744 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1745 return false; 1746 } 1747 return true; 1748} 1749 1750// If Then makes up to four following instructions (the IT block) conditional. 1751bool 1752EmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1753{ 1754#if 0 1755 // ARM pseudo code... 1756 EncodingSpecificOperations(); 1757 ITSTATE.IT<7:0> = firstcond:mask; 1758#endif 1759 1760 bool success = false; 1761 const uint32_t opcode = OpcodeAsUnsigned (&success); 1762 if (!success) 1763 return false; 1764 1765 m_it_session.InitIT(Bits32(opcode, 7, 0)); 1766 return true; 1767} 1768 1769// Branch causes a branch to a target address. 1770bool 1771EmulateInstructionARM::EmulateB (ARMEncoding encoding) 1772{ 1773#if 0 1774 // ARM pseudo code... 1775 if (ConditionPassed()) 1776 { 1777 EncodingSpecificOperations(); 1778 BranchWritePC(PC + imm32); 1779 } 1780#endif 1781 1782 bool success = false; 1783 const uint32_t opcode = OpcodeAsUnsigned (&success); 1784 if (!success) 1785 return false; 1786 1787 if (ConditionPassed()) 1788 { 1789 EmulateInstruction::Context context; 1790 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1791 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1792 if (!success) 1793 return false; 1794 addr_t target; // target address 1795 int32_t imm32; // PC-relative offset 1796 switch (encoding) { 1797 case eEncodingT1: 1798 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1799 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1800 target = pc + 4 + imm32; 1801 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1802 break; 1803 case eEncodingT2: 1804 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1805 target = pc + 4 + imm32; 1806 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1807 break; 1808 case eEncodingT3: 1809 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1810 { 1811 uint32_t S = Bit32(opcode, 26); 1812 uint32_t imm6 = Bits32(opcode, 21, 16); 1813 uint32_t J1 = Bit32(opcode, 13); 1814 uint32_t J2 = Bit32(opcode, 11); 1815 uint32_t imm11 = Bits32(opcode, 10, 0); 1816 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 1817 imm32 = llvm::SignExtend32<21>(imm21); 1818 target = pc + 4 + imm32; 1819 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1820 break; 1821 } 1822 case eEncodingT4: 1823 { 1824 uint32_t S = Bit32(opcode, 26); 1825 uint32_t imm10 = Bits32(opcode, 25, 16); 1826 uint32_t J1 = Bit32(opcode, 13); 1827 uint32_t J2 = Bit32(opcode, 11); 1828 uint32_t imm11 = Bits32(opcode, 10, 0); 1829 uint32_t I1 = !(J1 ^ S); 1830 uint32_t I2 = !(J2 ^ S); 1831 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1832 imm32 = llvm::SignExtend32<25>(imm25); 1833 target = pc + 4 + imm32; 1834 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1835 break; 1836 } 1837 case eEncodingA1: 1838 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1839 target = pc + 8 + imm32; 1840 context.SetModeAndImmediateSigned (eModeARM, 8 + imm32); 1841 break; 1842 default: 1843 return false; 1844 } 1845 if (!BranchWritePC(context, target)) 1846 return false; 1847 } 1848 return true; 1849} 1850 1851// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 1852// zero and conditionally branch forward a constant value. They do not affect the condition flags. 1853// CBNZ, CBZ 1854bool 1855EmulateInstructionARM::EmulateCB (ARMEncoding encoding) 1856{ 1857#if 0 1858 // ARM pseudo code... 1859 EncodingSpecificOperations(); 1860 if nonzero ^ IsZero(R[n]) then 1861 BranchWritePC(PC + imm32); 1862#endif 1863 1864 bool success = false; 1865 const uint32_t opcode = OpcodeAsUnsigned (&success); 1866 if (!success) 1867 return false; 1868 1869 // Read the register value from the operand register Rn. 1870 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Bits32(opcode, 2, 0), 0, &success); 1871 if (!success) 1872 return false; 1873 1874 EmulateInstruction::Context context; 1875 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1876 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1877 if (!success) 1878 return false; 1879 1880 addr_t target; // target address 1881 uint32_t imm32; // PC-relative offset to branch forward 1882 bool nonzero; 1883 switch (encoding) { 1884 case eEncodingT1: 1885 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 1886 nonzero = BitIsSet(opcode, 11); 1887 target = pc + 4 + imm32; 1888 context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32); 1889 break; 1890 default: 1891 return false; 1892 } 1893 if (nonzero ^ (reg_val == 0)) 1894 if (!BranchWritePC(context, target)) 1895 return false; 1896 1897 return true; 1898} 1899 1900// ADD <Rdn>, <Rm> 1901// where <Rdn> the destination register is also the first operand register 1902// and <Rm> is the second operand register. 1903bool 1904EmulateInstructionARM::EmulateAddRdnRm (ARMEncoding encoding) 1905{ 1906#if 0 1907 // ARM pseudo code... 1908 if ConditionPassed() then 1909 EncodingSpecificOperations(); 1910 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1911 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 1912 if d == 15 then 1913 ALUWritePC(result); // setflags is always FALSE here 1914 else 1915 R[d] = result; 1916 if setflags then 1917 APSR.N = result<31>; 1918 APSR.Z = IsZeroBit(result); 1919 APSR.C = carry; 1920 APSR.V = overflow; 1921#endif 1922 1923 bool success = false; 1924 const uint32_t opcode = OpcodeAsUnsigned (&success); 1925 if (!success) 1926 return false; 1927 1928 if (ConditionPassed()) 1929 { 1930 uint32_t Rd, Rn, Rm; 1931 //bool setflags = false; 1932 switch (encoding) 1933 { 1934 case eEncodingT2: 1935 // setflags = FALSE 1936 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1937 Rm = Bits32(opcode, 6, 3); 1938 if (Rn == 15 && Rm == 15) 1939 return false; 1940 break; 1941 default: 1942 return false; 1943 } 1944 1945 int32_t result, val1, val2; 1946 // Read the first operand. 1947 if (Rn == 15) 1948 val1 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1949 else 1950 val1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 1951 if (!success) 1952 return false; 1953 1954 // Read the second operand. 1955 if (Rm == 15) 1956 val2 = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1957 else 1958 val2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 1959 if (!success) 1960 return false; 1961 1962 result = val1 + val2; 1963 1964 EmulateInstruction::Context context; 1965 context.type = EmulateInstruction::eContextImmediate; 1966 context.SetNoArgs (); 1967 Register dummy_reg; 1968 dummy_reg.SetRegister (eRegisterKindDWARF, dwarf_r0); 1969 1970 if (Rd == 15) 1971 { 1972 if (!ALUWritePC (context, result, dummy_reg)) 1973 return false; 1974 } 1975 else 1976 { 1977 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 1978 return false; 1979 } 1980 } 1981 return true; 1982} 1983 1984// CMP (immediate) 1985bool 1986EmulateInstructionARM::EmulateCmpRnImm (ARMEncoding encoding) 1987{ 1988#if 0 1989 // ARM pseudo code... 1990 if ConditionPassed() then 1991 EncodingSpecificOperations(); 1992 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 1993 APSR.N = result<31>; 1994 APSR.Z = IsZeroBit(result); 1995 APSR.C = carry; 1996 APSR.V = overflow; 1997#endif 1998 1999 bool success = false; 2000 const uint32_t opcode = OpcodeAsUnsigned (&success); 2001 if (!success) 2002 return false; 2003 2004 uint32_t Rn; // the first operand 2005 uint32_t imm32; // the immediate value to be compared with 2006 switch (encoding) { 2007 case eEncodingT1: 2008 Rn = Bits32(opcode, 10, 8); 2009 imm32 = Bits32(opcode, 7, 0); 2010 break; 2011 default: 2012 return false; 2013 } 2014 // Read the register value from the operand register Rn. 2015 uint32_t reg_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2016 if (!success) 2017 return false; 2018 2019 EmulateInstruction::Context context; 2020 context.type = EmulateInstruction::eContextImmediate; 2021 context.SetNoArgs (); 2022 2023 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2024 m_new_inst_cpsr = m_inst_cpsr; 2025 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(res.result, CPSR_N)); 2026 SetBit32(m_new_inst_cpsr, CPSR_Z, res.result == 0 ? 1 : 0); 2027 SetBit32(m_new_inst_cpsr, CPSR_C, res.carry_out); 2028 SetBit32(m_new_inst_cpsr, CPSR_V, res.overflow); 2029 if (m_new_inst_cpsr != m_inst_cpsr) 2030 { 2031 EmulateInstruction::Context context; 2032 context.type = EmulateInstruction::eContextImmediate; 2033 context.SetNoArgs (); 2034 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2035 return false; 2036 } 2037 return true; 2038} 2039 2040// CMP (register) 2041bool 2042EmulateInstructionARM::EmulateCmpRnRm (ARMEncoding encoding) 2043{ 2044#if 0 2045 // ARM pseudo code... 2046 if ConditionPassed() then 2047 EncodingSpecificOperations(); 2048 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2049 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2050 APSR.N = result<31>; 2051 APSR.Z = IsZeroBit(result); 2052 APSR.C = carry; 2053 APSR.V = overflow; 2054#endif 2055 2056 bool success = false; 2057 const uint32_t opcode = OpcodeAsUnsigned (&success); 2058 if (!success) 2059 return false; 2060 2061 uint32_t Rn; // the first operand 2062 uint32_t Rm; // the second operand 2063 switch (encoding) { 2064 case eEncodingT1: 2065 Rn = Bits32(opcode, 2, 0); 2066 Rm = Bits32(opcode, 5, 3); 2067 break; 2068 case eEncodingT2: 2069 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2070 Rm = Bits32(opcode, 6, 3); 2071 if (Rn < 8 && Rm < 8) 2072 return false; 2073 if (Rn == 15 || Rm == 15) 2074 return false; 2075 break; 2076 default: 2077 return false; 2078 } 2079 // Read the register value from register Rn. 2080 uint32_t reg_val1 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2081 if (!success) 2082 return false; 2083 // Read the register value from register Rm. 2084 // The register value is not being shifted since we don't handle ARM for now. 2085 uint32_t reg_val2 = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2086 if (!success) 2087 return false; 2088 2089 EmulateInstruction::Context context; 2090 context.type = EmulateInstruction::eContextImmediate; 2091 context.SetNoArgs(); 2092 2093 AddWithCarryResult res = AddWithCarry(reg_val1, reg_val2, 1); 2094 m_new_inst_cpsr = m_inst_cpsr; 2095 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(res.result, CPSR_N)); 2096 SetBit32(m_new_inst_cpsr, CPSR_Z, res.result == 0 ? 1 : 0); 2097 SetBit32(m_new_inst_cpsr, CPSR_C, res.carry_out); 2098 SetBit32(m_new_inst_cpsr, CPSR_V, res.overflow); 2099 if (m_new_inst_cpsr != m_inst_cpsr) 2100 { 2101 EmulateInstruction::Context context; 2102 context.type = EmulateInstruction::eContextImmediate; 2103 context.SetNoArgs (); 2104 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2105 return false; 2106 } 2107 return true; 2108} 2109 2110// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 2111// shifting in copies of its sign bit, and writes the result to the destination register. It can 2112// optionally update the condition flags based on the result. 2113bool 2114EmulateInstructionARM::EmulateASRImm (ARMEncoding encoding) 2115{ 2116#if 0 2117 // ARM pseudo code... 2118 if ConditionPassed() then 2119 EncodingSpecificOperations(); 2120 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 2121 if d == 15 then // Can only occur for ARM encoding 2122 ALUWritePC(result); // setflags is always FALSE here 2123 else 2124 R[d] = result; 2125 if setflags then 2126 APSR.N = result<31>; 2127 APSR.Z = IsZeroBit(result); 2128 APSR.C = carry; 2129 // APSR.V unchanged 2130#endif 2131 2132 bool success = false; 2133 const uint32_t opcode = OpcodeAsUnsigned (&success); 2134 if (!success) 2135 return false; 2136 2137 if (ConditionPassed()) 2138 { 2139 uint32_t Rd; // the destination register 2140 uint32_t Rm; // the first operand register 2141 uint32_t imm5; // encoding for the shift amount 2142 uint32_t carry; // the carry bit after the shift operation 2143 bool setflags; 2144 switch (encoding) { 2145 case eEncodingT1: 2146 Rd = Bits32(opcode, 2, 0); 2147 Rm = Bits32(opcode, 5, 3); 2148 setflags = !InITBlock(); 2149 imm5 = Bits32(opcode, 10, 6); 2150 break; 2151 case eEncodingT2: 2152 Rd = Bits32(opcode, 11, 8); 2153 Rm = Bits32(opcode, 3, 0); 2154 setflags = BitIsSet(opcode, 20); 2155 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 2156 if (BadReg(Rd) || BadReg(Rm)) 2157 return false; 2158 break; 2159 case eEncodingA1: 2160 Rd = Bits32(opcode, 15, 12); 2161 Rm = Bits32(opcode, 3, 0); 2162 setflags = BitIsSet(opcode, 20); 2163 imm5 = Bits32(opcode, 11, 7); 2164 break; 2165 default: 2166 return false; 2167 } 2168 2169 // Get the first operand. 2170 uint32_t value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 2171 if (!success) 2172 return false; 2173 2174 // Decode the shift amount. 2175 uint32_t amt = DecodeImmShift(SRType_ASR, imm5); 2176 2177 uint32_t result = Shift_C(value, SRType_ASR, amt, Bit32(m_inst_cpsr, CPSR_C), carry); 2178 2179 // The context specifies that an immediate is to be moved into Rd. 2180 EmulateInstruction::Context context; 2181 context.type = EmulateInstruction::eContextImmediate; 2182 context.SetNoArgs (); 2183 2184 Register dummy_reg; 2185 dummy_reg.SetRegister (eRegisterKindDWARF, dwarf_r0); 2186 2187 if (Rd == 15) 2188 { 2189 if (!ALUWritePC (context, result, dummy_reg)) 2190 return false; 2191 } 2192 else 2193 { 2194 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, result)) 2195 return false; 2196 if (setflags) 2197 { 2198 m_new_inst_cpsr = m_inst_cpsr; 2199 SetBit32(m_new_inst_cpsr, CPSR_N, Bit32(result, CPSR_N)); 2200 SetBit32(m_new_inst_cpsr, CPSR_Z, result == 0 ? 1 : 0); 2201 SetBit32(m_new_inst_cpsr, CPSR_C, carry); 2202 if (m_new_inst_cpsr != m_inst_cpsr) 2203 { 2204 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2205 return false; 2206 } 2207 } 2208 } 2209 } 2210 return true; 2211} 2212 2213// LDM loads multiple registers from consecutive memory locations, using an 2214// address from a base register. Optionally the address just above the highest of those locations 2215// can be written back to the base register. 2216bool 2217EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 2218{ 2219#if 0 2220 // ARM pseudo code... 2221 if ConditionPassed() 2222 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 2223 address = R[n]; 2224 2225 for i = 0 to 14 2226 if registers<i> == '1' then 2227 R[i] = MemA[address, 4]; address = address + 4; 2228 if registers<15> == '1' then 2229 LoadWritePC (MemA[address, 4]); 2230 2231 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 2232 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2233 2234#endif 2235 2236 bool success = false; 2237 const uint32_t opcode = OpcodeAsUnsigned (&success); 2238 if (!success) 2239 return false; 2240 2241 if (ConditionPassed()) 2242 { 2243 uint32_t n; 2244 uint32_t registers = 0; 2245 bool wback; 2246 const uint32_t addr_byte_size = GetAddressByteSize(); 2247 switch (encoding) 2248 { 2249 case eEncodingT1: 2250 // n = UInt(Rn); registers = ’00000000’:register_list; wback = (registers<n> == ’0’); 2251 n = Bits32 (opcode, 10, 8); 2252 registers = Bits32 (opcode, 7, 0); 2253 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 2254 wback = BitIsClear (registers, n); 2255 // if BitCount(registers) < 1 then UNPREDICTABLE; 2256 if (BitCount(registers) < 1) 2257 return false; 2258 break; 2259 case eEncodingT2: 2260 // if W == ’1’ && Rn == ’1101’ then SEE POP; 2261 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2262 n = Bits32 (opcode, 19, 16); 2263 registers = Bits32 (opcode, 15, 0); 2264 registers = registers & 0xdfff; // Make sure bit 13 is zero. 2265 wback = BitIsSet (opcode, 21); 2266 2267 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2268 if ((n == 15) 2269 || (BitCount (registers) < 2) 2270 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2271 return false; 2272 2273 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2274 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2275 return false; 2276 2277 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2278 if (wback 2279 && BitIsSet (registers, n)) 2280 return false; 2281 break; 2282 2283 case eEncodingA1: 2284 n = Bits32 (opcode, 19, 16); 2285 registers = Bits32 (opcode, 15, 0); 2286 wback = BitIsSet (opcode, 21); 2287 if ((n == 15) 2288 || (BitCount (registers) < 1)) 2289 return false; 2290 break; 2291 default: 2292 return false; 2293 } 2294 2295 int32_t offset = 0; 2296 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2297 if (!success) 2298 return false; 2299 2300 EmulateInstruction::Context context; 2301 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2302 Register dwarf_reg; 2303 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2304 context.SetRegisterPlusOffset (dwarf_reg, offset); 2305 2306 for (int i = 0; i < 14; ++i) 2307 { 2308 if (BitIsSet (registers, i)) 2309 { 2310 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2311 context.SetRegisterPlusOffset (dwarf_reg, offset); 2312 if (wback && (n == 13)) // Pop Instruction 2313 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2314 2315 // R[i] = MemA [address, 4]; address = address + 4; 2316 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 2317 if (!success) 2318 return false; 2319 2320 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2321 return false; 2322 2323 offset += addr_byte_size; 2324 } 2325 } 2326 2327 if (BitIsSet (registers, 15)) 2328 { 2329 //LoadWritePC (MemA [address, 4]); 2330 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2331 context.SetRegisterPlusOffset (dwarf_reg, offset); 2332 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 2333 if (!success) 2334 return false; 2335 // In ARMv5T and above, this is an interworking branch. 2336 if (!LoadWritePC(context, data, dwarf_reg)) 2337 return false; 2338 } 2339 2340 if (wback && BitIsClear (registers, n)) 2341 { 2342 // R[n] = R[n] + 4 * BitCount (registers) 2343 int32_t offset = addr_byte_size * BitCount (registers); 2344 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2345 context.SetRegisterPlusOffset (dwarf_reg, offset); 2346 2347 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 2348 return false; 2349 } 2350 if (wback && BitIsSet (registers, n)) 2351 // R[n] bits(32) UNKNOWN; 2352 return WriteBits32Unknown (n); 2353 } 2354 return true; 2355} 2356 2357// LDMDA loads multiple registers from consecutive memory locations using an address from a base registers. 2358// The consecutive memorty locations end at this address and the address just below the lowest of those locations 2359// can optionally be written back tot he base registers. 2360bool 2361EmulateInstructionARM::EmulateLDMDA (ARMEncoding encoding) 2362{ 2363#if 0 2364 // ARM pseudo code... 2365 if ConditionPassed() then 2366 EncodingSpecificOperations(); 2367 address = R[n] - 4*BitCount(registers) + 4; 2368 2369 for i = 0 to 14 2370 if registers<i> == ’1’ then 2371 R[i] = MemA[address,4]; address = address + 4; 2372 2373 if registers<15> == ’1’ then 2374 LoadWritePC(MemA[address,4]); 2375 2376 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2377 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2378#endif 2379 2380 bool success = false; 2381 const uint32_t opcode = OpcodeAsUnsigned (&success); 2382 if (!success) 2383 return false; 2384 2385 if (ConditionPassed()) 2386 { 2387 uint32_t n; 2388 uint32_t registers = 0; 2389 bool wback; 2390 const uint32_t addr_byte_size = GetAddressByteSize(); 2391 2392 // EncodingSpecificOperations(); 2393 switch (encoding) 2394 { 2395 case eEncodingA1: 2396 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2397 n = Bits32 (opcode, 19, 16); 2398 registers = Bits32 (opcode, 15, 0); 2399 wback = BitIsSet (opcode, 21); 2400 2401 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2402 if ((n == 15) || (BitCount (registers) < 1)) 2403 return false; 2404 2405 break; 2406 2407 default: 2408 return false; 2409 } 2410 // address = R[n] - 4*BitCount(registers) + 4; 2411 2412 int32_t offset = 0; 2413 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2414 2415 if (!success) 2416 return false; 2417 2418 address = address - (addr_byte_size * BitCount (registers)) + addr_byte_size; 2419 2420 EmulateInstruction::Context context; 2421 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2422 Register dwarf_reg; 2423 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2424 context.SetRegisterPlusOffset (dwarf_reg, offset); 2425 2426 // for i = 0 to 14 2427 for (int i = 0; i < 14; ++i) 2428 { 2429 // if registers<i> == ’1’ then 2430 if (BitIsSet (registers, i)) 2431 { 2432 // R[i] = MemA[address,4]; address = address + 4; 2433 context.SetRegisterPlusOffset (dwarf_reg, offset); 2434 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2435 if (!success) 2436 return false; 2437 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2438 return false; 2439 offset += addr_byte_size; 2440 } 2441 } 2442 2443 // if registers<15> == ’1’ then 2444 // LoadWritePC(MemA[address,4]); 2445 if (BitIsSet (registers, 15)) 2446 { 2447 context.SetRegisterPlusOffset (dwarf_reg, offset); 2448 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2449 if (!success) 2450 return false; 2451 // In ARMv5T and above, this is an interworking branch. 2452 if (!LoadWritePC(context, data, dwarf_reg)) 2453 return false; 2454 } 2455 2456 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2457 if (wback && BitIsClear (registers, n)) 2458 { 2459 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2460 if (!success) 2461 return false; 2462 2463 offset = (addr_byte_size * BitCount (registers)) * -1; 2464 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2465 context.SetImmediateSigned (offset); 2466 addr = addr + offset; 2467 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2468 return false; 2469 } 2470 2471 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2472 if (wback && BitIsSet (registers, n)) 2473 return WriteBits32Unknown (n); 2474 } 2475 return true; 2476} 2477 2478// LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 2479// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can 2480// be optionally written back to the base register. 2481bool 2482EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 2483{ 2484#if 0 2485 // ARM pseudo code... 2486 if ConditionPassed() then 2487 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2488 address = R[n] - 4*BitCount(registers); 2489 2490 for i = 0 to 14 2491 if registers<i> == ’1’ then 2492 R[i] = MemA[address,4]; address = address + 4; 2493 if registers<15> == ’1’ then 2494 LoadWritePC(MemA[address,4]); 2495 2496 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2497 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2498#endif 2499 2500 bool success = false; 2501 const uint32_t opcode = OpcodeAsUnsigned (&success); 2502 if (!success) 2503 return false; 2504 2505 if (ConditionPassed()) 2506 { 2507 uint32_t n; 2508 uint32_t registers = 0; 2509 bool wback; 2510 const uint32_t addr_byte_size = GetAddressByteSize(); 2511 switch (encoding) 2512 { 2513 case eEncodingT1: 2514 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 2515 n = Bits32 (opcode, 19, 16); 2516 registers = Bits32 (opcode, 15, 0); 2517 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 2518 wback = BitIsSet (opcode, 21); 2519 2520 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 2521 if ((n == 15) 2522 || (BitCount (registers) < 2) 2523 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 2524 return false; 2525 2526 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 2527 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 2528 return false; 2529 2530 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2531 if (wback && BitIsSet (registers, n)) 2532 return false; 2533 2534 break; 2535 2536 case eEncodingA1: 2537 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2538 n = Bits32 (opcode, 19, 16); 2539 registers = Bits32 (opcode, 15, 0); 2540 wback = BitIsSet (opcode, 21); 2541 2542 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2543 if ((n == 15) || (BitCount (registers) < 1)) 2544 return false; 2545 2546 break; 2547 2548 default: 2549 return false; 2550 } 2551 2552 // address = R[n] - 4*BitCount(registers); 2553 2554 int32_t offset = 0; 2555 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2556 2557 if (!success) 2558 return false; 2559 2560 address = address - (addr_byte_size * BitCount (registers)); 2561 EmulateInstruction::Context context; 2562 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2563 Register dwarf_reg; 2564 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2565 context.SetRegisterPlusOffset (dwarf_reg, offset); 2566 2567 for (int i = 0; i < 14; ++i) 2568 { 2569 if (BitIsSet (registers, i)) 2570 { 2571 // R[i] = MemA[address,4]; address = address + 4; 2572 context.SetRegisterPlusOffset (dwarf_reg, offset); 2573 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2574 if (!success) 2575 return false; 2576 2577 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2578 return false; 2579 2580 offset += addr_byte_size; 2581 } 2582 } 2583 2584 // if registers<15> == ’1’ then 2585 // LoadWritePC(MemA[address,4]); 2586 if (BitIsSet (registers, 15)) 2587 { 2588 context.SetRegisterPlusOffset (dwarf_reg, offset); 2589 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2590 if (!success) 2591 return false; 2592 // In ARMv5T and above, this is an interworking branch. 2593 if (!LoadWritePC(context, data, dwarf_reg)) 2594 return false; 2595 } 2596 2597 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 2598 if (wback && BitIsClear (registers, n)) 2599 { 2600 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2601 if (!success) 2602 return false; 2603 2604 offset = (addr_byte_size * BitCount (registers)) * -1; 2605 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2606 context.SetImmediateSigned (offset); 2607 addr = addr + offset; 2608 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2609 return false; 2610 } 2611 2612 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2613 if (wback && BitIsSet (registers, n)) 2614 return WriteBits32Unknown (n); 2615 } 2616 return true; 2617} 2618 2619// LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 2620// consecutive memory locations start just above this address, and thea ddress of the last of those locations can 2621// optinoally be written back to the base register. 2622bool 2623EmulateInstructionARM::EmulateLDMIB (ARMEncoding encoding) 2624{ 2625#if 0 2626 if ConditionPassed() then 2627 EncodingSpecificOperations(); 2628 address = R[n] + 4; 2629 2630 for i = 0 to 14 2631 if registers<i> == ’1’ then 2632 R[i] = MemA[address,4]; address = address + 4; 2633 if registers<15> == ’1’ then 2634 LoadWritePC(MemA[address,4]); 2635 2636 if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2637 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; 2638#endif 2639 2640 bool success = false; 2641 const uint32_t opcode = OpcodeAsUnsigned (&success); 2642 if (!success) 2643 return false; 2644 2645 if (ConditionPassed()) 2646 { 2647 uint32_t n; 2648 uint32_t registers = 0; 2649 bool wback; 2650 const uint32_t addr_byte_size = GetAddressByteSize(); 2651 switch (encoding) 2652 { 2653 case eEncodingA1: 2654 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2655 n = Bits32 (opcode, 19, 16); 2656 registers = Bits32 (opcode, 15, 0); 2657 wback = BitIsSet (opcode, 21); 2658 2659 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2660 if ((n == 15) || (BitCount (registers) < 1)) 2661 return false; 2662 2663 break; 2664 default: 2665 return false; 2666 } 2667 // address = R[n] + 4; 2668 2669 int32_t offset = 0; 2670 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2671 2672 if (!success) 2673 return false; 2674 2675 address = address + addr_byte_size; 2676 2677 EmulateInstruction::Context context; 2678 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2679 Register dwarf_reg; 2680 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2681 context.SetRegisterPlusOffset (dwarf_reg, offset); 2682 2683 for (int i = 0; i < 14; ++i) 2684 { 2685 if (BitIsSet (registers, i)) 2686 { 2687 // R[i] = MemA[address,4]; address = address + 4; 2688 2689 context.SetRegisterPlusOffset (dwarf_reg, offset); 2690 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2691 if (!success) 2692 return false; 2693 2694 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 2695 return false; 2696 2697 offset += addr_byte_size; 2698 } 2699 } 2700 2701 // if registers<15> == ’1’ then 2702 // LoadWritePC(MemA[address,4]); 2703 if (BitIsSet (registers, 15)) 2704 { 2705 context.SetRegisterPlusOffset (dwarf_reg, offset); 2706 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 2707 if (!success) 2708 return false; 2709 // In ARMv5T and above, this is an interworking branch. 2710 if (!LoadWritePC(context, data, dwarf_reg)) 2711 return false; 2712 } 2713 2714 // if wback && registers<n> == ’0’ then R[n] = R[n] + 4*BitCount(registers); 2715 if (wback && BitIsClear (registers, n)) 2716 { 2717 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2718 if (!success) 2719 return false; 2720 2721 offset = addr_byte_size * BitCount (registers); 2722 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2723 context.SetImmediateSigned (offset); 2724 addr = addr + offset; 2725 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 2726 return false; 2727 } 2728 2729 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 2730 if (wback && BitIsSet (registers, n)) 2731 return WriteBits32Unknown (n); 2732 } 2733 return true; 2734} 2735 2736// Load Register (immediate) calculates an address from a base register value and 2737// an immediate offset, loads a word from memory, and writes to a register. 2738// LDR (immediate, Thumb) 2739bool 2740EmulateInstructionARM::EmulateLDRRtRnImm (ARMEncoding encoding) 2741{ 2742#if 0 2743 // ARM pseudo code... 2744 if (ConditionPassed()) 2745 { 2746 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 2747 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2748 address = if index then offset_addr else R[n]; 2749 data = MemU[address,4]; 2750 if wback then R[n] = offset_addr; 2751 if t == 15 then 2752 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 2753 elsif UnalignedSupport() || address<1:0> = '00' then 2754 R[t] = data; 2755 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 2756 } 2757#endif 2758 2759 bool success = false; 2760 const uint32_t opcode = OpcodeAsUnsigned (&success); 2761 if (!success) 2762 return false; 2763 2764 if (ConditionPassed()) 2765 { 2766 uint32_t Rt; // the destination register 2767 uint32_t Rn; // the base register 2768 uint32_t imm32; // the immediate offset used to form the address 2769 addr_t offset_addr; // the offset address 2770 addr_t address; // the calculated address 2771 uint32_t data; // the literal data value from memory load 2772 bool add, index, wback; 2773 switch (encoding) { 2774 case eEncodingT1: 2775 Rt = Bits32(opcode, 5, 3); 2776 Rn = Bits32(opcode, 2, 0); 2777 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 2778 // index = TRUE; add = TRUE; wback = FALSE 2779 add = true; 2780 index = true; 2781 wback = false; 2782 break; 2783 default: 2784 return false; 2785 } 2786 uint32_t base = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rn, 0, &success); 2787 if (!success) 2788 return false; 2789 if (add) 2790 offset_addr = base + imm32; 2791 else 2792 offset_addr = base - imm32; 2793 2794 address = (index ? offset_addr : base); 2795 2796 if (wback) 2797 { 2798 EmulateInstruction::Context ctx; 2799 ctx.type = EmulateInstruction::eContextRegisterPlusOffset; 2800 Register dwarf_reg; 2801 dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn); 2802 ctx.SetRegisterPlusOffset (dwarf_reg, (int32_t) (offset_addr - base)); 2803 2804 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 2805 return false; 2806 } 2807 2808 // Prepare to write to the Rt register. 2809 EmulateInstruction::Context context; 2810 context.type = EmulateInstruction::eContextImmediate; 2811 context.SetNoArgs (); 2812 Register dummy_reg; 2813 dummy_reg.SetRegister (eRegisterKindDWARF, dwarf_r0); 2814 2815 // Read memory from the address. 2816 data = ReadMemoryUnsigned(context, address, 4, 0, &success); 2817 if (!success) 2818 return false; 2819 2820 if (Rt == 15) 2821 { 2822 if (Bits32(address, 1, 0) == 0) 2823 { 2824 if (!LoadWritePC(context, data, dummy_reg)) 2825 return false; 2826 } 2827 else 2828 return false; 2829 } 2830 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 2831 { 2832 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 2833 return false; 2834 } 2835 else 2836 return false; 2837 } 2838 return true; 2839} 2840 2841// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 2842// from a base register. The consecutive memory locations start at this address, and teh address just above the last 2843// of those locations can optionally be written back to the base register. 2844bool 2845EmulateInstructionARM::EmulateSTM (ARMEncoding encoding) 2846{ 2847#if 0 2848 if ConditionPassed() then 2849 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2850 address = R[n]; 2851 2852 for i = 0 to 14 2853 if registers<i> == ’1’ then 2854 if i == n && wback && i != LowestSetBit(registers) then 2855 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 2856 else 2857 MemA[address,4] = R[i]; 2858 address = address + 4; 2859 2860 if registers<15> == ’1’ then // Only possible for encoding A1 2861 MemA[address,4] = PCStoreValue(); 2862 if wback then R[n] = R[n] + 4*BitCount(registers); 2863#endif 2864 2865 bool success = false; 2866 const uint32_t opcode = OpcodeAsUnsigned (&success); 2867 if (!success) 2868 return false; 2869 2870 if (ConditionPassed ()) 2871 { 2872 uint32_t n; 2873 uint32_t registers = 0; 2874 bool wback; 2875 const uint32_t addr_byte_size = GetAddressByteSize(); 2876 2877 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2878 switch (encoding) 2879 { 2880 case eEncodingT1: 2881 // n = UInt(Rn); registers = ’00000000’:register_list; wback = TRUE; 2882 n = Bits32 (opcode, 10, 8); 2883 registers = Bits32 (opcode, 7, 0); 2884 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 2885 wback = true; 2886 2887 // if BitCount(registers) < 1 then UNPREDICTABLE; 2888 if (BitCount (registers) < 1) 2889 return false; 2890 2891 break; 2892 2893 case eEncodingT2: 2894 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 2895 n = Bits32 (opcode, 19, 16); 2896 registers = Bits32 (opcode, 15, 0); 2897 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 2898 wback = BitIsSet (opcode, 21); 2899 2900 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 2901 if ((n == 15) || (BitCount (registers) < 2)) 2902 return false; 2903 2904 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 2905 if (wback && BitIsSet (registers, n)) 2906 return false; 2907 2908 break; 2909 2910 case eEncodingA1: 2911 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 2912 n = Bits32 (opcode, 19, 16); 2913 registers = Bits32 (opcode, 15, 0); 2914 wback = BitIsSet (opcode, 21); 2915 2916 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 2917 if ((n == 15) || (BitCount (registers) < 1)) 2918 return false; 2919 2920 break; 2921 2922 default: 2923 return false; 2924 } 2925 2926 // address = R[n]; 2927 int32_t offset = 0; 2928 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2929 if (!success) 2930 return false; 2931 2932 EmulateInstruction::Context context; 2933 context.type = EmulateInstruction::eContextRegisterStore; 2934 Register base_reg; 2935 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 2936 2937 // for i = 0 to 14 2938 for (int i = 0; i < 14; ++i) 2939 { 2940 int lowest_set_bit = 14; 2941 // if registers<i> == ’1’ then 2942 if (BitIsSet (registers, i)) 2943 { 2944 if (i < lowest_set_bit) 2945 lowest_set_bit = i; 2946 // if i == n && wback && i != LowestSetBit(registers) then 2947 if ((i == n) && wback && (i != lowest_set_bit)) 2948 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 2949 WriteBits32UnknownToMemory (address + offset); 2950 else 2951 { 2952 // MemA[address,4] = R[i]; 2953 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 2954 if (!success) 2955 return false; 2956 2957 Register data_reg; 2958 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 2959 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 2960 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 2961 return false; 2962 } 2963 2964 // address = address + 4; 2965 offset += addr_byte_size; 2966 } 2967 } 2968 2969 // if registers<15> == ’1’ then // Only possible for encoding A1 2970 // MemA[address,4] = PCStoreValue(); 2971 if (BitIsSet (registers, 15)) 2972 { 2973 Register pc_reg; 2974 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 2975 context.SetRegisterPlusOffset (pc_reg, 8); 2976 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 2977 if (!success) 2978 return false; 2979 2980 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 2981 return false; 2982 } 2983 2984 // if wback then R[n] = R[n] + 4*BitCount(registers); 2985 if (wback) 2986 { 2987 offset = addr_byte_size * BitCount (registers); 2988 context.type = EmulateInstruction::eContextAdjustBaseRegister; 2989 context.SetImmediateSigned (offset); 2990 addr_t data = address + offset; 2991 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 2992 return false; 2993 } 2994 } 2995 return true; 2996} 2997 2998// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 2999// from a base register. The consecutive memory locations end at this address, and the address just below the lowest 3000// of those locations can optionally be written back to the base register. 3001bool 3002EmulateInstructionARM::EmulateSTMDA (ARMEncoding encoding) 3003{ 3004#if 0 3005 if ConditionPassed() then 3006 EncodingSpecificOperations(); 3007 address = R[n] - 4*BitCount(registers) + 4; 3008 3009 for i = 0 to 14 3010 if registers<i> == ’1’ then 3011 if i == n && wback && i != LowestSetBit(registers) then 3012 MemA[address,4] = bits(32) UNKNOWN; 3013 else 3014 MemA[address,4] = R[i]; 3015 address = address + 4; 3016 3017 if registers<15> == ’1’ then 3018 MemA[address,4] = PCStoreValue(); 3019 3020 if wback then R[n] = R[n] - 4*BitCount(registers); 3021#endif 3022 3023 bool success = false; 3024 const uint32_t opcode = OpcodeAsUnsigned (&success); 3025 if (!success) 3026 return false; 3027 3028 if (ConditionPassed ()) 3029 { 3030 uint32_t n; 3031 uint32_t registers = 0; 3032 bool wback; 3033 const uint32_t addr_byte_size = GetAddressByteSize(); 3034 3035 // EncodingSpecificOperations(); 3036 switch (encoding) 3037 { 3038 case eEncodingA1: 3039 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3040 n = Bits32 (opcode, 19, 16); 3041 registers = Bits32 (opcode, 15, 0); 3042 wback = BitIsSet (opcode, 21); 3043 3044 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3045 if ((n == 15) || (BitCount (registers) < 1)) 3046 return false; 3047 break; 3048 default: 3049 return false; 3050 } 3051 3052 // address = R[n] - 4*BitCount(registers) + 4; 3053 int32_t offset = 0; 3054 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3055 if (!success) 3056 return false; 3057 3058 address = address - (addr_byte_size * BitCount (registers)) + 4; 3059 3060 EmulateInstruction::Context context; 3061 context.type = EmulateInstruction::eContextRegisterStore; 3062 Register base_reg; 3063 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3064 3065 // for i = 0 to 14 3066 for (int i = 0; i < 14; ++i) 3067 { 3068 int lowest_bit_set = 14; 3069 // if registers<i> == ’1’ then 3070 if (BitIsSet (registers, i)) 3071 { 3072 if (i < lowest_bit_set) 3073 lowest_bit_set = i; 3074 //if i == n && wback && i != LowestSetBit(registers) then 3075 if ((i == n) && wback && (i != lowest_bit_set)) 3076 // MemA[address,4] = bits(32) UNKNOWN; 3077 WriteBits32UnknownToMemory (address + offset); 3078 else 3079 { 3080 // MemA[address,4] = R[i]; 3081 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3082 if (!success) 3083 return false; 3084 3085 Register data_reg; 3086 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3087 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3088 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 3089 return false; 3090 } 3091 3092 // address = address + 4; 3093 offset += addr_byte_size; 3094 } 3095 } 3096 3097 // if registers<15> == ’1’ then 3098 // MemA[address,4] = PCStoreValue(); 3099 if (BitIsSet (registers, 15)) 3100 { 3101 Register pc_reg; 3102 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3103 context.SetRegisterPlusOffset (pc_reg, 8); 3104 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3105 if (!success) 3106 return false; 3107 3108 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 3109 return false; 3110 } 3111 3112 // if wback then R[n] = R[n] - 4*BitCount(registers); 3113 if (wback) 3114 { 3115 offset = (addr_byte_size * BitCount (registers)) * -1; 3116 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3117 context.SetImmediateSigned (offset); 3118 addr_t data = address + offset; 3119 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3120 return false; 3121 } 3122 } 3123 return true; 3124} 3125 3126// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 3127// from a base register. The consecutive memory locations end just below this address, and the address of the first of 3128// those locations can optionally be written back to the base register. 3129bool 3130EmulateInstructionARM::EmulateSTMDB (ARMEncoding encoding) 3131{ 3132#if 0 3133 if ConditionPassed() then 3134 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3135 address = R[n] - 4*BitCount(registers); 3136 3137 for i = 0 to 14 3138 if registers<i> == ’1’ then 3139 if i == n && wback && i != LowestSetBit(registers) then 3140 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3141 else 3142 MemA[address,4] = R[i]; 3143 address = address + 4; 3144 3145 if registers<15> == ’1’ then // Only possible for encoding A1 3146 MemA[address,4] = PCStoreValue(); 3147 3148 if wback then R[n] = R[n] - 4*BitCount(registers); 3149#endif 3150 3151 3152 bool success = false; 3153 const uint32_t opcode = OpcodeAsUnsigned (&success); 3154 if (!success) 3155 return false; 3156 3157 if (ConditionPassed ()) 3158 { 3159 uint32_t n; 3160 uint32_t registers = 0; 3161 bool wback; 3162 const uint32_t addr_byte_size = GetAddressByteSize(); 3163 3164 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3165 switch (encoding) 3166 { 3167 case eEncodingT1: 3168 // if W == ’1’ && Rn == ’1101’ then SEE PUSH; 3169 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 3170 { 3171 // See PUSH 3172 } 3173 // n = UInt(Rn); registers = ’0’:M:’0’:register_list; wback = (W == ’1’); 3174 n = Bits32 (opcode, 19, 16); 3175 registers = Bits32 (opcode, 15, 0); 3176 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 3177 wback = BitIsSet (opcode, 21); 3178 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 3179 if ((n == 15) || BitCount (registers) < 2) 3180 return false; 3181 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 3182 if (wback && BitIsSet (registers, n)) 3183 return false; 3184 break; 3185 3186 case eEncodingA1: 3187 // if W == ’1’ && Rn == ’1101’ && BitCount(register_list) >= 2 then SEE PUSH; 3188 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 3189 { 3190 // See Push 3191 } 3192 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3193 n = Bits32 (opcode, 19, 16); 3194 registers = Bits32 (opcode, 15, 0); 3195 wback = BitIsSet (opcode, 21); 3196 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3197 if ((n == 15) || BitCount (registers) < 1) 3198 return false; 3199 break; 3200 3201 default: 3202 return false; 3203 } 3204 3205 // address = R[n] - 4*BitCount(registers); 3206 3207 int32_t offset = 0; 3208 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3209 if (!success) 3210 return false; 3211 3212 address = address - (addr_byte_size * BitCount (registers)); 3213 3214 EmulateInstruction::Context context; 3215 context.type = EmulateInstruction::eContextRegisterStore; 3216 Register base_reg; 3217 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3218 3219 // for i = 0 to 14 3220 for (int i = 0; i < 14; ++i) 3221 { 3222 uint32_t lowest_set_bit = 14; 3223 // if registers<i> == ’1’ then 3224 if (BitIsSet (registers, i)) 3225 { 3226 if (i < lowest_set_bit) 3227 lowest_set_bit = i; 3228 // if i == n && wback && i != LowestSetBit(registers) then 3229 if ((i == n) && wback && (i != lowest_set_bit)) 3230 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 3231 WriteBits32UnknownToMemory (address + offset); 3232 else 3233 { 3234 // MemA[address,4] = R[i]; 3235 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3236 if (!success) 3237 return false; 3238 3239 Register data_reg; 3240 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3241 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3242 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 3243 return false; 3244 } 3245 3246 // address = address + 4; 3247 offset += addr_byte_size; 3248 } 3249 } 3250 3251 // if registers<15> == ’1’ then // Only possible for encoding A1 3252 // MemA[address,4] = PCStoreValue(); 3253 if (BitIsSet (registers, 15)) 3254 { 3255 Register pc_reg; 3256 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3257 context.SetRegisterPlusOffset (pc_reg, 8); 3258 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3259 if (!success) 3260 return false; 3261 3262 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 3263 return false; 3264 } 3265 3266 // if wback then R[n] = R[n] - 4*BitCount(registers); 3267 if (wback) 3268 { 3269 offset = (addr_byte_size * BitCount (registers)) * -1; 3270 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3271 context.SetImmediateSigned (offset); 3272 addr_t data = address + offset; 3273 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3274 return false; 3275 } 3276 } 3277 return true; 3278} 3279 3280// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 3281// from a base register. The consecutive memory locations start just above this address, and the address of the last 3282// of those locations can optionally be written back to the base register. 3283bool 3284EmulateInstructionARM::EmulateSTMIB (ARMEncoding encoding) 3285{ 3286#if 0 3287 if ConditionPassed() then 3288 EncodingSpecificOperations(); 3289 address = R[n] + 4; 3290 3291 for i = 0 to 14 3292 if registers<i> == ’1’ then 3293 if i == n && wback && i != LowestSetBit(registers) then 3294 MemA[address,4] = bits(32) UNKNOWN; 3295 else 3296 MemA[address,4] = R[i]; 3297 address = address + 4; 3298 3299 if registers<15> == ’1’ then 3300 MemA[address,4] = PCStoreValue(); 3301 3302 if wback then R[n] = R[n] + 4*BitCount(registers); 3303#endif 3304 3305 bool success = false; 3306 const uint32_t opcode = OpcodeAsUnsigned (&success); 3307 if (!success) 3308 return false; 3309 3310 if (ConditionPassed()) 3311 { 3312 uint32_t n; 3313 uint32_t registers = 0; 3314 bool wback; 3315 const uint32_t addr_byte_size = GetAddressByteSize(); 3316 3317 // EncodingSpecificOperations(); 3318 switch (encoding) 3319 { 3320 case eEncodingA1: 3321 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 3322 n = Bits32 (opcode, 19, 16); 3323 registers = Bits32 (opcode, 15, 0); 3324 wback = BitIsSet (opcode, 21); 3325 3326 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3327 if ((n == 15) && (BitCount (registers) < 1)) 3328 return false; 3329 break; 3330 default: 3331 return false; 3332 } 3333 // address = R[n] + 4; 3334 3335 int32_t offset = 0; 3336 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3337 if (!success) 3338 return false; 3339 3340 address = address + addr_byte_size; 3341 3342 EmulateInstruction::Context context; 3343 context.type = EmulateInstruction::eContextRegisterStore; 3344 Register base_reg; 3345 base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n); 3346 3347 uint32_t lowest_set_bit = 14; 3348 // for i = 0 to 14 3349 for (int i = 0; i < 14; ++i) 3350 { 3351 // if registers<i> == ’1’ then 3352 if (BitIsSet (registers, i)) 3353 { 3354 if (i < lowest_set_bit) 3355 lowest_set_bit = i; 3356 // if i == n && wback && i != LowestSetBit(registers) then 3357 if ((i == n) && wback && (i != lowest_set_bit)) 3358 // MemA[address,4] = bits(32) UNKNOWN; 3359 WriteBits32UnknownToMemory (address + offset); 3360 // else 3361 else 3362 { 3363 // MemA[address,4] = R[i]; 3364 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 3365 if (!success) 3366 return false; 3367 3368 Register data_reg; 3369 data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i); 3370 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 3371 if (!WriteMemoryUnsigned (context, address + offset, data, addr_byte_size)) 3372 return false; 3373 } 3374 3375 // address = address + 4; 3376 offset += addr_byte_size; 3377 } 3378 } 3379 3380 // if registers<15> == ’1’ then 3381 // MemA[address,4] = PCStoreValue(); 3382 if (BitIsSet (registers, 15)) 3383 { 3384 Register pc_reg; 3385 pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc); 3386 context.SetRegisterPlusOffset (pc_reg, 8); 3387 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 3388 if (!success) 3389 return false; 3390 3391 if (!WriteMemoryUnsigned (context, address + offset, pc + 8, addr_byte_size)) 3392 return false; 3393 } 3394 3395 // if wback then R[n] = R[n] + 4*BitCount(registers); 3396 if (wback) 3397 { 3398 offset = addr_byte_size * BitCount (registers); 3399 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3400 context.SetImmediateSigned (offset); 3401 addr_t data = address + offset; 3402 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 3403 return false; 3404 } 3405 } 3406 return true; 3407} 3408 3409 3410EmulateInstructionARM::ARMOpcode* 3411EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 3412{ 3413 static ARMOpcode 3414 g_arm_opcodes[] = 3415 { 3416 //---------------------------------------------------------------------- 3417 // Prologue instructions 3418 //---------------------------------------------------------------------- 3419 3420 // push register(s) 3421 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 3422 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePush, "push <register>" }, 3423 3424 // set r7 to point to a stack offset 3425 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #<const>" }, 3426 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"}, 3427 // copy the stack pointer to ip 3428 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMovRdSP, "mov ip, sp" }, 3429 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add ip, sp, #<const>" }, 3430 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"}, 3431 3432 // adjust the stack pointer 3433 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"}, 3434 3435 // push one register 3436 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 3437 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 3438 3439 // vector push consecutive extension register(s) 3440 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 3441 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 3442 3443 //---------------------------------------------------------------------- 3444 // Epilogue instructions 3445 //---------------------------------------------------------------------- 3446 3447 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 3448 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePop, "pop <register>"}, 3449 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 3450 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 3451 3452 //---------------------------------------------------------------------- 3453 // Supervisor Call (previously Software Interrupt) 3454 //---------------------------------------------------------------------- 3455 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 3456 3457 //---------------------------------------------------------------------- 3458 // Branch instructions 3459 //---------------------------------------------------------------------- 3460 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 3461 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 3462 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 3463 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 3464 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 3465 // for example, "bx lr" 3466 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 3467 3468 //---------------------------------------------------------------------- 3469 // Data-processing instructions 3470 //---------------------------------------------------------------------- 3471 // move bitwise not 3472 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMvnRdImm, "mvn{s} <Rd>, #<const>"}, 3473 // asr (immediate) 3474 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 3475 3476 //---------------------------------------------------------------------- 3477 // Load instructions 3478 //---------------------------------------------------------------------- 3479 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 3480 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 3481 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 3482 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 3483 3484 //---------------------------------------------------------------------- 3485 // Store instructions 3486 //---------------------------------------------------------------------- 3487 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 3488 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 3489 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 3490 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" } 3491 3492 3493 }; 3494 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 3495 3496 for (size_t i=0; i<k_num_arm_opcodes; ++i) 3497 { 3498 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 3499 return &g_arm_opcodes[i]; 3500 } 3501 return NULL; 3502} 3503 3504 3505EmulateInstructionARM::ARMOpcode* 3506EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 3507{ 3508 3509 static ARMOpcode 3510 g_thumb_opcodes[] = 3511 { 3512 //---------------------------------------------------------------------- 3513 // Prologue instructions 3514 //---------------------------------------------------------------------- 3515 3516 // push register(s) 3517 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 3518 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <registers>" }, 3519 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <register>" }, 3520 3521 // set r7 to point to a stack offset 3522 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #imm" }, 3523 // copy the stack pointer to r7 3524 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdSP, "mov r7, sp" }, 3525 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 3526 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovLowHigh, "mov r0-r7, r8-r15" }, 3527 3528 // PC-relative load into register (see also EmulateAddSPRm) 3529 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 3530 3531 // adjust the stack pointer 3532 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"}, 3533 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"}, 3534 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"}, 3535 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"}, 3536 3537 // vector push consecutive extension register(s) 3538 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 3539 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 3540 3541 //---------------------------------------------------------------------- 3542 // Epilogue instructions 3543 //---------------------------------------------------------------------- 3544 3545 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"}, 3546 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 3547 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <registers>" }, 3548 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <register>" }, 3549 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 3550 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 3551 3552 //---------------------------------------------------------------------- 3553 // Supervisor Call (previously Software Interrupt) 3554 //---------------------------------------------------------------------- 3555 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 3556 3557 //---------------------------------------------------------------------- 3558 // If Then makes up to four following instructions conditional. 3559 //---------------------------------------------------------------------- 3560 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 3561 3562 //---------------------------------------------------------------------- 3563 // Branch instructions 3564 //---------------------------------------------------------------------- 3565 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 3566 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 3567 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 3568 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 3569 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 3570 // J1 == J2 == 1 3571 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 3572 // J1 == J2 == 1 3573 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 3574 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 3575 // for example, "bx lr" 3576 { 0xffffff87, 0x00004700, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 3577 // compare and branch 3578 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 3579 3580 //---------------------------------------------------------------------- 3581 // Data-processing instructions 3582 //---------------------------------------------------------------------- 3583 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 3584 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdnRm, "add <Rdn>, <Rm>"}, 3585 // move from high register to high register 3586 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "mov<c> <Rd>, <Rm>"}, 3587 // move from low register to low register 3588 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateMovRdRm, "movs <Rd>, <Rm>"}, 3589 // move immediate 3590 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdImm, "movs|mov<c> <Rd>, #imm8"}, 3591 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateMovRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 3592 // move bitwise not 3593 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateMvnRdImm, "mvn{s} <Rd>, #<const>"}, 3594 // compare a register with immediate 3595 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCmpRnImm, "cmp<c> <Rn>, #imm8"}, 3596 // compare Rn with Rm (Rn and Rm both from r0-r7) 3597 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateCmpRnRm, "cmp<c> <Rn>, <Rm>"}, 3598 // compare Rn with Rm (Rn and Rm not both from r0-r7) 3599 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateCmpRnRm, "cmp<c> <Rn>, <Rm>"}, 3600 // asr (immediate) 3601 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 3602 { 0x0fef0070, 0x01a00040, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 3603 3604 //---------------------------------------------------------------------- 3605 // Load instructions 3606 //---------------------------------------------------------------------- 3607 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 3608 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 3609 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 3610 { 0xfffff800, 0x00006800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 3611 // Thumb2 PC-relative load into register 3612 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 3613 3614 //---------------------------------------------------------------------- 3615 // Store instructions 3616 //---------------------------------------------------------------------- 3617 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 3618 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 3619 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" } 3620 3621 }; 3622 3623 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 3624 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 3625 { 3626 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 3627 return &g_thumb_opcodes[i]; 3628 } 3629 return NULL; 3630} 3631 3632bool 3633EmulateInstructionARM::SetTargetTriple (const ConstString &triple) 3634{ 3635 m_arm_isa = 0; 3636 const char *triple_cstr = triple.GetCString(); 3637 if (triple_cstr) 3638 { 3639 const char *dash = ::strchr (triple_cstr, '-'); 3640 if (dash) 3641 { 3642 std::string arch (triple_cstr, dash); 3643 const char *arch_cstr = arch.c_str(); 3644 if (strcasecmp(arch_cstr, "armv4t") == 0) 3645 m_arm_isa = ARMv4T; 3646 else if (strcasecmp(arch_cstr, "armv4") == 0) 3647 m_arm_isa = ARMv4; 3648 else if (strcasecmp(arch_cstr, "armv5tej") == 0) 3649 m_arm_isa = ARMv5TEJ; 3650 else if (strcasecmp(arch_cstr, "armv5te") == 0) 3651 m_arm_isa = ARMv5TE; 3652 else if (strcasecmp(arch_cstr, "armv5t") == 0) 3653 m_arm_isa = ARMv5T; 3654 else if (strcasecmp(arch_cstr, "armv6k") == 0) 3655 m_arm_isa = ARMv6K; 3656 else if (strcasecmp(arch_cstr, "armv6") == 0) 3657 m_arm_isa = ARMv6; 3658 else if (strcasecmp(arch_cstr, "armv6t2") == 0) 3659 m_arm_isa = ARMv6T2; 3660 else if (strcasecmp(arch_cstr, "armv7") == 0) 3661 m_arm_isa = ARMv7; 3662 else if (strcasecmp(arch_cstr, "armv8") == 0) 3663 m_arm_isa = ARMv8; 3664 } 3665 } 3666 return m_arm_isa != 0; 3667} 3668 3669 3670bool 3671EmulateInstructionARM::ReadInstruction () 3672{ 3673 bool success = false; 3674 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 3675 if (success) 3676 { 3677 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 3678 if (success) 3679 { 3680 Context read_inst_context; 3681 read_inst_context.type = eContextReadOpcode; 3682 read_inst_context.SetNoArgs (); 3683 3684 if (m_inst_cpsr & MASK_CPSR_T) 3685 { 3686 m_inst_mode = eModeThumb; 3687 uint32_t thumb_opcode = ReadMemoryUnsigned(read_inst_context, pc, 2, 0, &success); 3688 3689 if (success) 3690 { 3691 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 3692 { 3693 m_inst.opcode_type = eOpcode16; 3694 m_inst.opcode.inst16 = thumb_opcode; 3695 } 3696 else 3697 { 3698 m_inst.opcode_type = eOpcode32; 3699 m_inst.opcode.inst32 = (thumb_opcode << 16) | ReadMemoryUnsigned(read_inst_context, pc + 2, 2, 0, &success); 3700 } 3701 } 3702 } 3703 else 3704 { 3705 m_inst_mode = eModeARM; 3706 m_inst.opcode_type = eOpcode32; 3707 m_inst.opcode.inst32 = ReadMemoryUnsigned(read_inst_context, pc, 4, 0, &success); 3708 } 3709 } 3710 } 3711 if (!success) 3712 { 3713 m_inst_mode = eModeInvalid; 3714 m_inst_pc = LLDB_INVALID_ADDRESS; 3715 } 3716 return success; 3717} 3718 3719uint32_t 3720EmulateInstructionARM::ArchVersion () 3721{ 3722 return m_arm_isa; 3723} 3724 3725bool 3726EmulateInstructionARM::ConditionPassed () 3727{ 3728 if (m_inst_cpsr == 0) 3729 return false; 3730 3731 const uint32_t cond = CurrentCond (); 3732 3733 if (cond == UINT32_MAX) 3734 return false; 3735 3736 bool result = false; 3737 switch (UnsignedBits(cond, 3, 1)) 3738 { 3739 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 3740 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 3741 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 3742 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 3743 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 3744 case 5: 3745 { 3746 bool n = (m_inst_cpsr & MASK_CPSR_N); 3747 bool v = (m_inst_cpsr & MASK_CPSR_V); 3748 result = n == v; 3749 } 3750 break; 3751 case 6: 3752 { 3753 bool n = (m_inst_cpsr & MASK_CPSR_N); 3754 bool v = (m_inst_cpsr & MASK_CPSR_V); 3755 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 3756 } 3757 break; 3758 case 7: 3759 result = true; 3760 break; 3761 } 3762 3763 if (cond & 1) 3764 result = !result; 3765 return result; 3766} 3767 3768uint32_t 3769EmulateInstructionARM::CurrentCond () 3770{ 3771 switch (m_inst_mode) 3772 { 3773 default: 3774 case eModeInvalid: 3775 break; 3776 3777 case eModeARM: 3778 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 3779 3780 case eModeThumb: 3781 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 3782 // 'cond' field of the encoding. 3783 if (m_inst.opcode_type == eOpcode16 && 3784 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 3785 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 3786 { 3787 return Bits32(m_inst.opcode.inst16, 11, 7); 3788 } 3789 else if (m_inst.opcode_type == eOpcode32 && 3790 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 3791 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 3792 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 3793 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 3794 { 3795 return Bits32(m_inst.opcode.inst32, 25, 22); 3796 } 3797 3798 return m_it_session.GetCond(); 3799 } 3800 return UINT32_MAX; // Return invalid value 3801} 3802 3803bool 3804EmulateInstructionARM::InITBlock() 3805{ 3806 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 3807} 3808 3809bool 3810EmulateInstructionARM::LastInITBlock() 3811{ 3812 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 3813} 3814 3815bool 3816EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 3817{ 3818 addr_t target; 3819 3820 // Check the current instruction set. 3821 if (CurrentInstrSet() == eModeARM) 3822 target = addr & 0xfffffffc; 3823 else 3824 target = addr & 0xfffffffe; 3825 3826 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 3827 return false; 3828 3829 return true; 3830} 3831 3832// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 3833bool 3834EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr, Register ®) 3835{ 3836 addr_t target; 3837 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 3838 // we want to record it and issue a WriteRegister callback so the clients 3839 // can track the mode changes accordingly. 3840 bool cpsr_changed = false; 3841 3842 if (BitIsSet(addr, 0)) 3843 { 3844 if (CurrentInstrSet() != eModeThumb) 3845 { 3846 SelectInstrSet(eModeThumb); 3847 cpsr_changed = true; 3848 } 3849 target = addr & 0xfffffffe; 3850 context.SetModeAndRegister (eModeThumb, reg); 3851 } 3852 else if (BitIsClear(addr, 1)) 3853 { 3854 if (CurrentInstrSet() != eModeARM) 3855 { 3856 SelectInstrSet(eModeARM); 3857 cpsr_changed = true; 3858 } 3859 target = addr & 0xfffffffc; 3860 context.SetModeAndRegister (eModeARM, reg); 3861 } 3862 else 3863 return false; // address<1:0> == '10' => UNPREDICTABLE 3864 3865 if (cpsr_changed) 3866 { 3867 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 3868 return false; 3869 } 3870 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 3871 return false; 3872 3873 return true; 3874} 3875 3876// Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 3877bool 3878EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr, Register ®) 3879{ 3880 if (ArchVersion() >= ARMv5T) 3881 return BXWritePC(context, addr, reg); 3882 else 3883 return BranchWritePC((const Context)context, addr); 3884} 3885 3886// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 3887bool 3888EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr, Register ®) 3889{ 3890 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 3891 return BXWritePC(context, addr, reg); 3892 else 3893 return BranchWritePC((const Context)context, addr); 3894} 3895 3896EmulateInstructionARM::Mode 3897EmulateInstructionARM::CurrentInstrSet () 3898{ 3899 return m_inst_mode; 3900} 3901 3902// Set the 'T' bit of our CPSR. The m_inst_mode gets updated when the next 3903// ReadInstruction() is performed. This function has a side effect of updating 3904// the m_new_inst_cpsr member variable if necessary. 3905bool 3906EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 3907{ 3908 m_new_inst_cpsr = m_inst_cpsr; 3909 switch (arm_or_thumb) 3910 { 3911 default: 3912 return false; 3913 eModeARM: 3914 // Clear the T bit. 3915 m_new_inst_cpsr &= ~MASK_CPSR_T; 3916 break; 3917 eModeThumb: 3918 // Set the T bit. 3919 m_new_inst_cpsr |= MASK_CPSR_T; 3920 break; 3921 } 3922 return true; 3923} 3924 3925// This function returns TRUE if the processor currently provides support for 3926// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 3927// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 3928bool 3929EmulateInstructionARM::UnalignedSupport() 3930{ 3931 return (ArchVersion() >= ARMv7); 3932} 3933 3934// The main addition and subtraction instructions can produce status information 3935// about both unsigned carry and signed overflow conditions. This status 3936// information can be used to synthesize multi-word additions and subtractions. 3937EmulateInstructionARM::AddWithCarryResult 3938EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 3939{ 3940 uint32_t result; 3941 uint8_t carry_out; 3942 uint8_t overflow; 3943 3944 uint64_t unsigned_sum = x + y + carry_in; 3945 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 3946 3947 result = UnsignedBits(unsigned_sum, 31, 0); 3948 carry_out = (result == unsigned_sum ? 0 : 1); 3949 overflow = ((int32_t)result == signed_sum ? 0 : 1); 3950 3951 AddWithCarryResult res = { result, carry_out, overflow }; 3952 return res; 3953} 3954 3955bool 3956EmulateInstructionARM::EvaluateInstruction () 3957{ 3958 // Advance the ITSTATE bits to their values for the next instruction. 3959 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 3960 m_it_session.ITAdvance(); 3961 3962 return false; 3963} 3964