EmulateInstructionARM.cpp revision 0b29e24ecd86048ac5d722dc964e55bab49f72aa
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 "EmulateInstructionARM.h" 11#include "lldb/Core/ConstString.h" 12 13#include "ARMDefines.h" 14#include "ARMUtils.h" 15#include "ARM_DWARF_Registers.h" 16#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 17 // and CountTrailingZeros_32 function 18 19using namespace lldb; 20using namespace lldb_private; 21 22static inline uint32_t Align(uint32_t val, uint32_t alignment) 23{ 24 return alignment * (val / alignment); 25} 26 27// A8.6.50 28// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 29static unsigned short CountITSize(unsigned ITMask) { 30 // First count the trailing zeros of the IT mask. 31 unsigned TZ = llvm::CountTrailingZeros_32(ITMask); 32 if (TZ > 3) 33 { 34 printf("Encoding error: IT Mask '0000'\n"); 35 return 0; 36 } 37 return (4 - TZ); 38} 39 40// Init ITState. Note that at least one bit is always 1 in mask. 41bool ITSession::InitIT(unsigned short bits7_0) 42{ 43 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 44 if (ITCounter == 0) 45 return false; 46 47 // A8.6.50 IT 48 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 49 if (FirstCond == 0xF) 50 { 51 printf("Encoding error: IT FirstCond '1111'\n"); 52 return false; 53 } 54 if (FirstCond == 0xE && ITCounter != 1) 55 { 56 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 57 return false; 58 } 59 60 ITState = bits7_0; 61 return true; 62} 63 64// Update ITState if necessary. 65void ITSession::ITAdvance() 66{ 67 assert(ITCounter); 68 --ITCounter; 69 if (ITCounter == 0) 70 ITState = 0; 71 else 72 { 73 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 74 SetBits32(ITState, 4, 0, NewITState4_0); 75 } 76} 77 78// Return true if we're inside an IT Block. 79bool ITSession::InITBlock() 80{ 81 return ITCounter != 0; 82} 83 84// Return true if we're the last instruction inside an IT Block. 85bool ITSession::LastInITBlock() 86{ 87 return ITCounter == 1; 88} 89 90// Get condition bits for the current thumb instruction. 91uint32_t ITSession::GetCond() 92{ 93 if (InITBlock()) 94 return Bits32(ITState, 7, 4); 95 else 96 return COND_AL; 97} 98 99// ARM constants used during decoding 100#define REG_RD 0 101#define LDM_REGLIST 1 102#define PC_REG 15 103#define PC_REGLIST_BIT 0x8000 104 105#define ARMv4 (1u << 0) 106#define ARMv4T (1u << 1) 107#define ARMv5T (1u << 2) 108#define ARMv5TE (1u << 3) 109#define ARMv5TEJ (1u << 4) 110#define ARMv6 (1u << 5) 111#define ARMv6K (1u << 6) 112#define ARMv6T2 (1u << 7) 113#define ARMv7 (1u << 8) 114#define ARMv8 (1u << 9) 115#define ARMvAll (0xffffffffu) 116 117#define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 118#define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8) 119#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8) 120 121void 122EmulateInstructionARM::Initialize () 123{ 124} 125 126void 127EmulateInstructionARM::Terminate () 128{ 129} 130 131// Push Multiple Registers stores multiple registers to the stack, storing to 132// consecutive memory locations ending just below the address in SP, and updates 133// SP to point to the start of the stored data. 134bool 135EmulateInstructionARM::EmulatePush (ARMEncoding encoding) 136{ 137#if 0 138 // ARM pseudo code... 139 if (ConditionPassed()) 140 { 141 EncodingSpecificOperations(); 142 NullCheckIfThumbEE(13); 143 address = SP - 4*BitCount(registers); 144 145 for (i = 0 to 14) 146 { 147 if (registers<i> == ’1’) 148 { 149 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 150 MemA[address,4] = bits(32) UNKNOWN; 151 else 152 MemA[address,4] = R[i]; 153 address = address + 4; 154 } 155 } 156 157 if (registers<15> == ’1’) // Only possible for encoding A1 or A2 158 MemA[address,4] = PCStoreValue(); 159 160 SP = SP - 4*BitCount(registers); 161 } 162#endif 163 164 bool success = false; 165 const uint32_t opcode = OpcodeAsUnsigned (&success); 166 if (!success) 167 return false; 168 169 if (ConditionPassed()) 170 { 171 const uint32_t addr_byte_size = GetAddressByteSize(); 172 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 173 if (!success) 174 return false; 175 uint32_t registers = 0; 176 uint32_t Rt; // the source register 177 switch (encoding) { 178 case eEncodingT1: 179 registers = Bits32(opcode, 7, 0); 180 // The M bit represents LR. 181 if (Bits32(opcode, 8, 8)) 182 registers |= (1u << 14); 183 // if BitCount(registers) < 1 then UNPREDICTABLE; 184 if (BitCount(registers) < 1) 185 return false; 186 break; 187 case eEncodingT2: 188 // Ignore bits 15 & 13. 189 registers = Bits32(opcode, 15, 0) & ~0xa000; 190 // if BitCount(registers) < 2 then UNPREDICTABLE; 191 if (BitCount(registers) < 2) 192 return false; 193 break; 194 case eEncodingT3: 195 Rt = Bits32(opcode, 15, 12); 196 // if BadReg(t) then UNPREDICTABLE; 197 if (BadReg(Rt)) 198 return false; 199 registers = (1u << Rt); 200 break; 201 case eEncodingA1: 202 registers = Bits32(opcode, 15, 0); 203 // Instead of return false, let's handle the following case as well, 204 // which amounts to pushing one reg onto the full descending stacks. 205 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 206 break; 207 case eEncodingA2: 208 Rt = Bits32(opcode, 15, 12); 209 // if t == 13 then UNPREDICTABLE; 210 if (Rt == dwarf_sp) 211 return false; 212 registers = (1u << Rt); 213 break; 214 default: 215 return false; 216 } 217 addr_t sp_offset = addr_byte_size * BitCount (registers); 218 addr_t addr = sp - sp_offset; 219 uint32_t i; 220 221 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 222 for (i=0; i<15; ++i) 223 { 224 if (BitIsSet (registers, 1u << i)) 225 { 226 context.arg1 = dwarf_r0 + i; // arg1 in the context is the DWARF register number 227 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 228 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 229 if (!success) 230 return false; 231 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 232 return false; 233 addr += addr_byte_size; 234 } 235 } 236 237 if (BitIsSet (registers, 1u << 15)) 238 { 239 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 240 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 241 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 242 if (!success) 243 return false; 244 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 245 return false; 246 } 247 248 context.type = EmulateInstruction::eContextAdjustStackPointer; 249 context.arg0 = eRegisterKindGeneric; 250 context.arg1 = LLDB_REGNUM_GENERIC_SP; 251 context.arg2 = -sp_offset; 252 253 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 254 return false; 255 } 256 return true; 257} 258 259// Pop Multiple Registers loads multiple registers from the stack, loading from 260// consecutive memory locations staring at the address in SP, and updates 261// SP to point just above the loaded data. 262bool 263EmulateInstructionARM::EmulatePop (ARMEncoding encoding) 264{ 265#if 0 266 // ARM pseudo code... 267 if (ConditionPassed()) 268 { 269 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 270 address = SP; 271 for i = 0 to 14 272 if registers<i> == ‘1’ then 273 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 274 if registers<15> == ‘1’ then 275 if UnalignedAllowed then 276 LoadWritePC(MemU[address,4]); 277 else 278 LoadWritePC(MemA[address,4]); 279 if registers<13> == ‘0’ then SP = SP + 4*BitCount(registers); 280 if registers<13> == ‘1’ then SP = bits(32) UNKNOWN; 281 } 282#endif 283 284 bool success = false; 285 const uint32_t opcode = OpcodeAsUnsigned (&success); 286 if (!success) 287 return false; 288 289 if (ConditionPassed()) 290 { 291 const uint32_t addr_byte_size = GetAddressByteSize(); 292 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 293 if (!success) 294 return false; 295 uint32_t registers = 0; 296 uint32_t Rt; // the destination register 297 switch (encoding) { 298 case eEncodingT1: 299 registers = Bits32(opcode, 7, 0); 300 // The P bit represents PC. 301 if (Bits32(opcode, 8, 8)) 302 registers |= (1u << 15); 303 // if BitCount(registers) < 1 then UNPREDICTABLE; 304 if (BitCount(registers) < 1) 305 return false; 306 break; 307 case eEncodingT2: 308 // Ignore bit 13. 309 registers = Bits32(opcode, 15, 0) & ~0x2000; 310 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 311 if (BitCount(registers) < 2 || (Bits32(opcode, 15, 15) && Bits32(opcode, 14, 14))) 312 return false; 313 break; 314 case eEncodingT3: 315 Rt = Bits32(opcode, 15, 12); 316 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 317 if (Rt == dwarf_sp) 318 return false; 319 registers = (1u << Rt); 320 break; 321 case eEncodingA1: 322 registers = Bits32(opcode, 15, 0); 323 // Instead of return false, let's handle the following case as well, 324 // which amounts to popping one reg from the full descending stacks. 325 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 326 327 // if registers<13> == ‘1’ && ArchVersion() >= 7 then UNPREDICTABLE; 328 if (Bits32(opcode, 13, 13)) 329 return false; 330 break; 331 case eEncodingA2: 332 Rt = Bits32(opcode, 15, 12); 333 // if t == 13 then UNPREDICTABLE; 334 if (Rt == dwarf_sp) 335 return false; 336 registers = (1u << Rt); 337 break; 338 default: 339 return false; 340 } 341 addr_t sp_offset = addr_byte_size * BitCount (registers); 342 addr_t addr = sp; 343 uint32_t i, data; 344 345 EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 }; 346 for (i=0; i<15; ++i) 347 { 348 if (BitIsSet (registers, 1u << i)) 349 { 350 context.arg1 = dwarf_r0 + i; // arg1 in the context is the DWARF register number 351 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 352 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 353 if (!success) 354 return false; 355 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data)) 356 return false; 357 addr += addr_byte_size; 358 } 359 } 360 361 if (BitIsSet (registers, 1u << 15)) 362 { 363 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 364 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 365 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 366 if (!success) 367 return false; 368 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, data)) 369 return false; 370 addr += addr_byte_size; 371 } 372 373 context.type = EmulateInstruction::eContextAdjustStackPointer; 374 context.arg0 = eRegisterKindGeneric; 375 context.arg1 = LLDB_REGNUM_GENERIC_SP; 376 context.arg2 = sp_offset; 377 378 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 379 return false; 380 } 381 return true; 382} 383 384// Set r7 or ip to point to saved value residing within the stack. 385// ADD (SP plus immediate) 386bool 387EmulateInstructionARM::EmulateAddRdSPImmediate (ARMEncoding encoding) 388{ 389#if 0 390 // ARM pseudo code... 391 if (ConditionPassed()) 392 { 393 EncodingSpecificOperations(); 394 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 395 if d == 15 then 396 ALUWritePC(result); // setflags is always FALSE here 397 else 398 R[d] = result; 399 if setflags then 400 APSR.N = result<31>; 401 APSR.Z = IsZeroBit(result); 402 APSR.C = carry; 403 APSR.V = overflow; 404 } 405#endif 406 407 bool success = false; 408 const uint32_t opcode = OpcodeAsUnsigned (&success); 409 if (!success) 410 return false; 411 412 if (ConditionPassed()) 413 { 414 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 415 if (!success) 416 return false; 417 uint32_t Rd; // the destination register 418 uint32_t imm32; 419 switch (encoding) { 420 case eEncodingT1: 421 Rd = 7; 422 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 423 break; 424 case eEncodingA1: 425 Rd = Bits32(opcode, 15, 12); 426 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 427 break; 428 default: 429 return false; 430 } 431 addr_t sp_offset = imm32; 432 addr_t addr = sp + sp_offset; // a pointer to the stack area 433 434 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 435 eRegisterKindGeneric, 436 LLDB_REGNUM_GENERIC_SP, 437 sp_offset }; 438 439 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 440 return false; 441 } 442 return true; 443} 444 445// Set r7 or ip to the current stack pointer. 446// MOV (register) 447bool 448EmulateInstructionARM::EmulateMovRdSP (ARMEncoding encoding) 449{ 450#if 0 451 // ARM pseudo code... 452 if (ConditionPassed()) 453 { 454 EncodingSpecificOperations(); 455 result = R[m]; 456 if d == 15 then 457 ALUWritePC(result); // setflags is always FALSE here 458 else 459 R[d] = result; 460 if setflags then 461 APSR.N = result<31>; 462 APSR.Z = IsZeroBit(result); 463 // APSR.C unchanged 464 // APSR.V unchanged 465 } 466#endif 467 468 bool success = false; 469 //const uint32_t opcode = OpcodeAsUnsigned (&success); 470 //if (!success) 471 // return false; 472 473 if (ConditionPassed()) 474 { 475 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 476 if (!success) 477 return false; 478 uint32_t Rd; // the destination register 479 switch (encoding) { 480 case eEncodingT1: 481 Rd = 7; 482 break; 483 case eEncodingA1: 484 Rd = 12; 485 break; 486 default: 487 return false; 488 } 489 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 490 eRegisterKindGeneric, 491 LLDB_REGNUM_GENERIC_SP, 492 0 }; 493 494 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 495 return false; 496 } 497 return true; 498} 499 500// Move from high register (r8-r15) to low register (r0-r7). 501// MOV (register) 502bool 503EmulateInstructionARM::EmulateMovLowHigh (ARMEncoding encoding) 504{ 505#if 0 506 // ARM pseudo code... 507 if (ConditionPassed()) 508 { 509 EncodingSpecificOperations(); 510 result = R[m]; 511 if d == 15 then 512 ALUWritePC(result); // setflags is always FALSE here 513 else 514 R[d] = result; 515 if setflags then 516 APSR.N = result<31>; 517 APSR.Z = IsZeroBit(result); 518 // APSR.C unchanged 519 // APSR.V unchanged 520 } 521#endif 522 523 bool success = false; 524 const uint32_t opcode = OpcodeAsUnsigned (&success); 525 if (!success) 526 return false; 527 528 if (ConditionPassed()) 529 { 530 uint32_t Rm; // the source register 531 uint32_t Rd; // the destination register 532 switch (encoding) { 533 case eEncodingT1: 534 Rm = Bits32(opcode, 6, 3); 535 Rd = Bits32(opcode, 2, 1); // bits(7) == 0 536 break; 537 default: 538 return false; 539 } 540 int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 541 if (!success) 542 return false; 543 544 // The context specifies that Rm is to be moved into Rd. 545 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 546 eRegisterKindDWARF, 547 dwarf_r0 + Rm, 548 0 }; 549 550 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, reg_value)) 551 return false; 552 } 553 return true; 554} 555 556// PC relative immediate load into register, possibly followed by ADD (SP plus register). 557// LDR (literal) 558bool 559EmulateInstructionARM::EmulateLDRRdPCRelative (ARMEncoding encoding) 560{ 561#if 0 562 // ARM pseudo code... 563 if (ConditionPassed()) 564 { 565 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 566 base = Align(PC,4); 567 address = if add then (base + imm32) else (base - imm32); 568 data = MemU[address,4]; 569 if t == 15 then 570 if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE; 571 elsif UnalignedSupport() || address<1:0> = ‘00’ then 572 R[t] = data; 573 else // Can only apply before ARMv7 574 if CurrentInstrSet() == InstrSet_ARM then 575 R[t] = ROR(data, 8*UInt(address<1:0>)); 576 else 577 R[t] = bits(32) UNKNOWN; 578 } 579#endif 580 581 bool success = false; 582 const uint32_t opcode = OpcodeAsUnsigned (&success); 583 if (!success) 584 return false; 585 586 if (ConditionPassed()) 587 { 588 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 589 if (!success) 590 return false; 591 592 // PC relative immediate load context 593 EmulateInstruction::Context context = {EmulateInstruction::eContextRegisterPlusOffset, 594 eRegisterKindGeneric, 595 LLDB_REGNUM_GENERIC_PC, 596 0}; 597 uint32_t Rd; // the destination register 598 uint32_t imm32; // immediate offset from the PC 599 addr_t addr; // the PC relative address 600 uint32_t data; // the literal data value from the PC relative load 601 switch (encoding) { 602 case eEncodingT1: 603 Rd = Bits32(opcode, 10, 8); 604 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 605 addr = pc + 4 + imm32; 606 context.arg2 = 4 + imm32; 607 break; 608 default: 609 return false; 610 } 611 data = ReadMemoryUnsigned(context, addr, 4, 0, &success); 612 if (!success) 613 return false; 614 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, data)) 615 return false; 616 } 617 return true; 618} 619 620// An add operation to adjust the SP. 621// ADD (SP plus immediate) 622bool 623EmulateInstructionARM::EmulateAddSPImmediate (ARMEncoding encoding) 624{ 625#if 0 626 // ARM pseudo code... 627 if (ConditionPassed()) 628 { 629 EncodingSpecificOperations(); 630 (result, carry, overflow) = AddWithCarry(SP, imm32, ‘0’); 631 if d == 15 then // Can only occur for ARM encoding 632 ALUWritePC(result); // setflags is always FALSE here 633 else 634 R[d] = result; 635 if setflags then 636 APSR.N = result<31>; 637 APSR.Z = IsZeroBit(result); 638 APSR.C = carry; 639 APSR.V = overflow; 640 } 641#endif 642 643 bool success = false; 644 const uint32_t opcode = OpcodeAsUnsigned (&success); 645 if (!success) 646 return false; 647 648 if (ConditionPassed()) 649 { 650 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 651 if (!success) 652 return false; 653 uint32_t imm32; // the immediate operand 654 switch (encoding) { 655 case eEncodingT2: 656 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 657 break; 658 default: 659 return false; 660 } 661 addr_t sp_offset = imm32; 662 addr_t addr = sp + sp_offset; // the adjusted stack pointer value 663 664 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 665 eRegisterKindGeneric, 666 LLDB_REGNUM_GENERIC_SP, 667 sp_offset }; 668 669 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 670 return false; 671 } 672 return true; 673} 674 675// An add operation to adjust the SP. 676// ADD (SP plus register) 677bool 678EmulateInstructionARM::EmulateAddSPRm (ARMEncoding encoding) 679{ 680#if 0 681 // ARM pseudo code... 682 if (ConditionPassed()) 683 { 684 EncodingSpecificOperations(); 685 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 686 (result, carry, overflow) = AddWithCarry(SP, shifted, ‘0’); 687 if d == 15 then 688 ALUWritePC(result); // setflags is always FALSE here 689 else 690 R[d] = result; 691 if setflags then 692 APSR.N = result<31>; 693 APSR.Z = IsZeroBit(result); 694 APSR.C = carry; 695 APSR.V = overflow; 696 } 697#endif 698 699 bool success = false; 700 const uint32_t opcode = OpcodeAsUnsigned (&success); 701 if (!success) 702 return false; 703 704 if (ConditionPassed()) 705 { 706 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 707 if (!success) 708 return false; 709 uint32_t Rm; // the second operand 710 switch (encoding) { 711 case eEncodingT2: 712 Rm = Bits32(opcode, 6, 3); 713 break; 714 default: 715 return false; 716 } 717 int32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 718 if (!success) 719 return false; 720 721 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 722 723 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 724 eRegisterKindGeneric, 725 LLDB_REGNUM_GENERIC_SP, 726 reg_value }; 727 728 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 729 return false; 730 } 731 return true; 732} 733 734// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 735// at a PC-relative address, and changes instruction set from ARM to Thumb, or 736// from Thumb to ARM. 737// BLX (immediate) 738bool 739EmulateInstructionARM::EmulateBLXImmediate (ARMEncoding encoding) 740{ 741#if 0 742 // ARM pseudo code... 743 if (ConditionPassed()) 744 { 745 EncodingSpecificOperations(); 746 if CurrentInstrSet() == InstrSet_ARM then 747 LR = PC - 4; 748 else 749 LR = PC<31:1> : '1'; 750 if targetInstrSet == InstrSet_ARM then 751 targetAddress = Align(PC,4) + imm32; 752 else 753 targetAddress = PC + imm32; 754 SelectInstrSet(targetInstrSet); 755 BranchWritePC(targetAddress); 756 } 757#endif 758 759 bool success = false; 760 const uint32_t opcode = OpcodeAsUnsigned (&success); 761 if (!success) 762 return false; 763 764 if (ConditionPassed()) 765 { 766 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 767 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 768 addr_t lr; // next instruction address 769 addr_t target; // target address 770 if (!success) 771 return false; 772 int32_t imm32; // PC-relative offset 773 switch (encoding) { 774 case eEncodingT1: 775 { 776 lr = (pc + 4) | 1u; // return address 777 uint32_t S = Bits32(opcode, 26, 26); 778 uint32_t imm10 = Bits32(opcode, 25, 16); 779 uint32_t J1 = Bits32(opcode, 13, 13); 780 uint32_t J2 = Bits32(opcode, 11, 11); 781 uint32_t imm11 = Bits32(opcode, 10, 0); 782 uint32_t I1 = !(J1 ^ S); 783 uint32_t I2 = !(J2 ^ S); 784 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) + (imm11 << 1); 785 imm32 = llvm::SignExtend32<25>(imm25); 786 target = pc + 4 + imm32; 787 context.arg1 = 4 + imm32; // signed offset 788 context.arg2 = eModeThumb; // target instruction set 789 break; 790 } 791 case eEncodingT2: 792 { 793 lr = (pc + 4) | 1u; // return address 794 uint32_t S = Bits32(opcode, 26, 26); 795 uint32_t imm10H = Bits32(opcode, 25, 16); 796 uint32_t J1 = Bits32(opcode, 13, 13); 797 uint32_t J2 = Bits32(opcode, 11, 11); 798 uint32_t imm10L = Bits32(opcode, 10, 1); 799 uint32_t I1 = !(J1 ^ S); 800 uint32_t I2 = !(J2 ^ S); 801 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) + (imm10L << 2); 802 imm32 = llvm::SignExtend32<25>(imm25); 803 target = Align(pc + 4, 4) + imm32; 804 context.arg1 = 4 + imm32; // signed offset 805 context.arg2 = eModeARM; // target instruction set 806 break; 807 } 808 case eEncodingA1: 809 lr = pc + 4; // return address 810 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 811 target = Align(pc + 8, 4) + imm32; 812 context.arg1 = 8 + imm32; // signed offset 813 context.arg2 = eModeARM; // target instruction set 814 break; 815 case eEncodingA2: 816 lr = pc + 4; // return address 817 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 818 target = pc + 8 + imm32; 819 context.arg1 = 8 + imm32; // signed offset 820 context.arg2 = eModeThumb; // target instruction set 821 break; 822 default: 823 return false; 824 } 825 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 826 return false; 827 if (!BranchWritePC(context, target)) 828 return false; 829 } 830 return true; 831} 832 833// Branch with Link and Exchange (register) calls a subroutine at an address and 834// instruction set specified by a register. 835// BLX (register) 836bool 837EmulateInstructionARM::EmulateBLXRm (ARMEncoding encoding) 838{ 839#if 0 840 // ARM pseudo code... 841 if (ConditionPassed()) 842 { 843 EncodingSpecificOperations(); 844 target = R[m]; 845 if CurrentInstrSet() == InstrSet_ARM then 846 next_instr_addr = PC - 4; 847 LR = next_instr_addr; 848 else 849 next_instr_addr = PC - 2; 850 LR = next_instr_addr<31:1> : ‘1’; 851 BXWritePC(target); 852 } 853#endif 854 855 bool success = false; 856 const uint32_t opcode = OpcodeAsUnsigned (&success); 857 if (!success) 858 return false; 859 860 if (ConditionPassed()) 861 { 862 EmulateInstruction::Context context = { EmulateInstruction::eContextAbsoluteBranchRegister, 0, 0, 0}; 863 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 864 addr_t lr; // next instruction address 865 addr_t target; // target address 866 if (!success) 867 return false; 868 uint32_t Rm; // the register with the target address 869 switch (encoding) { 870 case eEncodingT1: 871 lr = (pc + 2) | 1u; // return address 872 Rm = Bits32(opcode, 6, 3); 873 // if m == 15 then UNPREDICTABLE; 874 if (Rm == 15) 875 return false; 876 target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 877 break; 878 case eEncodingA1: 879 lr = pc + 4; // return address 880 Rm = Bits32(opcode, 3, 0); 881 // if m == 15 then UNPREDICTABLE; 882 if (Rm == 15) 883 return false; 884 target = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + Rm, 0, &success); 885 break; 886 default: 887 return false; 888 } 889 context.arg0 = eRegisterKindDWARF; 890 context.arg1 = dwarf_r0 + Rm; 891 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 892 return false; 893 if (!BXWritePC(context, target)) 894 return false; 895 } 896 return true; 897} 898 899// Set r7 to point to some ip offset. 900// SUB (immediate) 901bool 902EmulateInstructionARM::EmulateSubR7IPImmediate (ARMEncoding encoding) 903{ 904#if 0 905 // ARM pseudo code... 906 if (ConditionPassed()) 907 { 908 EncodingSpecificOperations(); 909 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 910 if d == 15 then // Can only occur for ARM encoding 911 ALUWritePC(result); // setflags is always FALSE here 912 else 913 R[d] = result; 914 if setflags then 915 APSR.N = result<31>; 916 APSR.Z = IsZeroBit(result); 917 APSR.C = carry; 918 APSR.V = overflow; 919 } 920#endif 921 922 bool success = false; 923 const uint32_t opcode = OpcodeAsUnsigned (&success); 924 if (!success) 925 return false; 926 927 if (ConditionPassed()) 928 { 929 const addr_t ip = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r12, 0, &success); 930 if (!success) 931 return false; 932 uint32_t imm32; 933 switch (encoding) { 934 case eEncodingA1: 935 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 936 break; 937 default: 938 return false; 939 } 940 addr_t ip_offset = imm32; 941 addr_t addr = ip - ip_offset; // the adjusted ip value 942 943 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 944 eRegisterKindDWARF, 945 dwarf_r12, 946 -ip_offset }; 947 948 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 949 return false; 950 } 951 return true; 952} 953 954// Set ip to point to some stack offset. 955// SUB (SP minus immediate) 956bool 957EmulateInstructionARM::EmulateSubIPSPImmediate (ARMEncoding encoding) 958{ 959#if 0 960 // ARM pseudo code... 961 if (ConditionPassed()) 962 { 963 EncodingSpecificOperations(); 964 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 965 if d == 15 then // Can only occur for ARM encoding 966 ALUWritePC(result); // setflags is always FALSE here 967 else 968 R[d] = result; 969 if setflags then 970 APSR.N = result<31>; 971 APSR.Z = IsZeroBit(result); 972 APSR.C = carry; 973 APSR.V = overflow; 974 } 975#endif 976 977 bool success = false; 978 const uint32_t opcode = OpcodeAsUnsigned (&success); 979 if (!success) 980 return false; 981 982 if (ConditionPassed()) 983 { 984 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 985 if (!success) 986 return false; 987 uint32_t imm32; 988 switch (encoding) { 989 case eEncodingA1: 990 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 991 break; 992 default: 993 return false; 994 } 995 addr_t sp_offset = imm32; 996 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 997 998 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 999 eRegisterKindGeneric, 1000 LLDB_REGNUM_GENERIC_SP, 1001 -sp_offset }; 1002 1003 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1004 return false; 1005 } 1006 return true; 1007} 1008 1009// A sub operation to adjust the SP -- allocate space for local storage. 1010bool 1011EmulateInstructionARM::EmulateSubSPImmdiate (ARMEncoding encoding) 1012{ 1013#if 0 1014 // ARM pseudo code... 1015 if (ConditionPassed()) 1016 { 1017 EncodingSpecificOperations(); 1018 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), ‘1’); 1019 if d == 15 then // Can only occur for ARM encoding 1020 ALUWritePC(result); // setflags is always FALSE here 1021 else 1022 R[d] = result; 1023 if setflags then 1024 APSR.N = result<31>; 1025 APSR.Z = IsZeroBit(result); 1026 APSR.C = carry; 1027 APSR.V = overflow; 1028 } 1029#endif 1030 1031 bool success = false; 1032 const uint32_t opcode = OpcodeAsUnsigned (&success); 1033 if (!success) 1034 return false; 1035 1036 if (ConditionPassed()) 1037 { 1038 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1039 if (!success) 1040 return false; 1041 uint32_t imm32; 1042 switch (encoding) { 1043 case eEncodingT1: 1044 imm32 = ThumbImmScaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1045 case eEncodingT2: 1046 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1047 break; 1048 case eEncodingT3: 1049 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1050 break; 1051 case eEncodingA1: 1052 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1053 break; 1054 default: 1055 return false; 1056 } 1057 addr_t sp_offset = imm32; 1058 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1059 1060 EmulateInstruction::Context context = { EmulateInstruction::eContextAdjustStackPointer, 1061 eRegisterKindGeneric, 1062 LLDB_REGNUM_GENERIC_SP, 1063 -sp_offset }; 1064 1065 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1066 return false; 1067 } 1068 return true; 1069} 1070 1071// A store operation to the stack that also updates the SP. 1072bool 1073EmulateInstructionARM::EmulateSTRRtSP (ARMEncoding encoding) 1074{ 1075#if 0 1076 // ARM pseudo code... 1077 if (ConditionPassed()) 1078 { 1079 EncodingSpecificOperations(); 1080 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1081 address = if index then offset_addr else R[n]; 1082 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1083 if wback then R[n] = offset_addr; 1084 } 1085#endif 1086 1087 bool success = false; 1088 const uint32_t opcode = OpcodeAsUnsigned (&success); 1089 if (!success) 1090 return false; 1091 1092 if (ConditionPassed()) 1093 { 1094 const uint32_t addr_byte_size = GetAddressByteSize(); 1095 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1096 if (!success) 1097 return false; 1098 uint32_t Rt; // the source register 1099 uint32_t imm12; 1100 switch (encoding) { 1101 case eEncodingA1: 1102 Rt = Bits32(opcode, 15, 12); 1103 imm12 = Bits32(opcode, 11, 0); 1104 break; 1105 default: 1106 return false; 1107 } 1108 addr_t sp_offset = imm12; 1109 addr_t addr = sp - sp_offset; 1110 1111 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 1112 if (Rt != 15) 1113 { 1114 context.arg1 = dwarf_r0 + Rt; // arg1 in the context is the DWARF register number 1115 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1116 uint32_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 1117 if (!success) 1118 return false; 1119 if (!WriteMemoryUnsigned (context, addr, reg_value, addr_byte_size)) 1120 return false; 1121 } 1122 else 1123 { 1124 context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number 1125 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1126 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1127 if (!success) 1128 return false; 1129 if (!WriteMemoryUnsigned (context, addr, pc + 8, addr_byte_size)) 1130 return false; 1131 } 1132 1133 context.type = EmulateInstruction::eContextAdjustStackPointer; 1134 context.arg0 = eRegisterKindGeneric; 1135 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1136 context.arg2 = -sp_offset; 1137 1138 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1139 return false; 1140 } 1141 return true; 1142} 1143 1144// Vector Push stores multiple extension registers to the stack. 1145// It also updates SP to point to the start of the stored data. 1146bool 1147EmulateInstructionARM::EmulateVPUSH (ARMEncoding encoding) 1148{ 1149#if 0 1150 // ARM pseudo code... 1151 if (ConditionPassed()) 1152 { 1153 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1154 address = SP - imm32; 1155 SP = SP - imm32; 1156 if single_regs then 1157 for r = 0 to regs-1 1158 MemA[address,4] = S[d+r]; address = address+4; 1159 else 1160 for r = 0 to regs-1 1161 // Store as two word-aligned words in the correct order for current endianness. 1162 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 1163 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 1164 address = address+8; 1165 } 1166#endif 1167 1168 bool success = false; 1169 const uint32_t opcode = OpcodeAsUnsigned (&success); 1170 if (!success) 1171 return false; 1172 1173 if (ConditionPassed()) 1174 { 1175 const uint32_t addr_byte_size = GetAddressByteSize(); 1176 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1177 if (!success) 1178 return false; 1179 bool single_regs; 1180 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1181 uint32_t imm32; // stack offset 1182 uint32_t regs; // number of registers 1183 switch (encoding) { 1184 case eEncodingT1: 1185 case eEncodingA1: 1186 single_regs = false; 1187 d = Bits32(opcode, 22, 22) << 4 | Bits32(opcode, 15, 12); 1188 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1189 // If UInt(imm8) is odd, see "FSTMX". 1190 regs = Bits32(opcode, 7, 0) / 2; 1191 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1192 if (regs == 0 || regs > 16 || (d + regs) > 32) 1193 return false; 1194 break; 1195 case eEncodingT2: 1196 case eEncodingA2: 1197 single_regs = true; 1198 d = Bits32(opcode, 15, 12) << 1 | Bits32(opcode, 22, 22); 1199 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1200 regs = Bits32(opcode, 7, 0); 1201 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1202 if (regs == 0 || regs > 16 || (d + regs) > 32) 1203 return false; 1204 break; 1205 default: 1206 return false; 1207 } 1208 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1209 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1210 addr_t sp_offset = imm32; 1211 addr_t addr = sp - sp_offset; 1212 uint32_t i; 1213 1214 EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 }; 1215 for (i=d; i<regs; ++i) 1216 { 1217 context.arg1 = start_reg + i; // arg1 in the context is the DWARF register number 1218 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1219 // uint64_t to accommodate 64-bit registers. 1220 uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, context.arg1, 0, &success); 1221 if (!success) 1222 return false; 1223 if (!WriteMemoryUnsigned (context, addr, reg_value, reg_byte_size)) 1224 return false; 1225 addr += reg_byte_size; 1226 } 1227 1228 context.type = EmulateInstruction::eContextAdjustStackPointer; 1229 context.arg0 = eRegisterKindGeneric; 1230 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1231 context.arg2 = -sp_offset; 1232 1233 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1234 return false; 1235 } 1236 return true; 1237} 1238 1239// Vector Pop loads multiple extension registers from the stack. 1240// It also updates SP to point just above the loaded data. 1241bool 1242EmulateInstructionARM::EmulateVPOP (ARMEncoding encoding) 1243{ 1244#if 0 1245 // ARM pseudo code... 1246 if (ConditionPassed()) 1247 { 1248 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 1249 address = SP; 1250 SP = SP + imm32; 1251 if single_regs then 1252 for r = 0 to regs-1 1253 S[d+r] = MemA[address,4]; address = address+4; 1254 else 1255 for r = 0 to regs-1 1256 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 1257 // Combine the word-aligned words in the correct order for current endianness. 1258 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 1259 } 1260#endif 1261 1262 bool success = false; 1263 const uint32_t opcode = OpcodeAsUnsigned (&success); 1264 if (!success) 1265 return false; 1266 1267 if (ConditionPassed()) 1268 { 1269 const uint32_t addr_byte_size = GetAddressByteSize(); 1270 const addr_t sp = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, 0, &success); 1271 if (!success) 1272 return false; 1273 bool single_regs; 1274 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 1275 uint32_t imm32; // stack offset 1276 uint32_t regs; // number of registers 1277 switch (encoding) { 1278 case eEncodingT1: 1279 case eEncodingA1: 1280 single_regs = false; 1281 d = Bits32(opcode, 22, 22) << 4 | Bits32(opcode, 15, 12); 1282 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1283 // If UInt(imm8) is odd, see "FLDMX". 1284 regs = Bits32(opcode, 7, 0) / 2; 1285 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1286 if (regs == 0 || regs > 16 || (d + regs) > 32) 1287 return false; 1288 break; 1289 case eEncodingT2: 1290 case eEncodingA2: 1291 single_regs = true; 1292 d = Bits32(opcode, 15, 12) << 1 | Bits32(opcode, 22, 22); 1293 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 1294 regs = Bits32(opcode, 7, 0); 1295 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 1296 if (regs == 0 || regs > 16 || (d + regs) > 32) 1297 return false; 1298 break; 1299 default: 1300 return false; 1301 } 1302 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 1303 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 1304 addr_t sp_offset = imm32; 1305 addr_t addr = sp; 1306 uint32_t i; 1307 uint64_t data; // uint64_t to accomodate 64-bit registers. 1308 1309 EmulateInstruction::Context context = { EmulateInstruction::eContextPopRegisterOffStack, eRegisterKindDWARF, 0, 0 }; 1310 for (i=d; i<regs; ++i) 1311 { 1312 context.arg1 = start_reg + i; // arg1 in the context is the DWARF register number 1313 context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset 1314 data = ReadMemoryUnsigned(context, addr, reg_byte_size, 0, &success); 1315 if (!success) 1316 return false; 1317 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, context.arg1, data)) 1318 return false; 1319 addr += reg_byte_size; 1320 } 1321 1322 context.type = EmulateInstruction::eContextAdjustStackPointer; 1323 context.arg0 = eRegisterKindGeneric; 1324 context.arg1 = LLDB_REGNUM_GENERIC_SP; 1325 context.arg2 = sp_offset; 1326 1327 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1328 return false; 1329 } 1330 return true; 1331} 1332 1333// SVC (previously SWI) 1334bool 1335EmulateInstructionARM::EmulateSVC (ARMEncoding encoding) 1336{ 1337#if 0 1338 // ARM pseudo code... 1339 if (ConditionPassed()) 1340 { 1341 EncodingSpecificOperations(); 1342 CallSupervisor(); 1343 } 1344#endif 1345 1346 bool success = false; 1347 const uint32_t opcode = OpcodeAsUnsigned (&success); 1348 if (!success) 1349 return false; 1350 1351 if (ConditionPassed()) 1352 { 1353 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1354 addr_t lr; // next instruction address 1355 if (!success) 1356 return false; 1357 uint32_t imm32; // the immediate constant 1358 uint32_t mode; // ARM or Thumb mode 1359 switch (encoding) { 1360 case eEncodingT1: 1361 lr = (pc + 2) | 1u; // return address 1362 imm32 = Bits32(opcode, 7, 0); 1363 mode = eModeThumb; 1364 break; 1365 case eEncodingA1: 1366 lr = pc + 4; // return address 1367 imm32 = Bits32(opcode, 23, 0); 1368 mode = eModeARM; 1369 break; 1370 default: 1371 return false; 1372 } 1373 EmulateInstruction::Context context = { EmulateInstruction::eContextSupervisorCall, mode, imm32, 0}; 1374 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1375 return false; 1376 } 1377 return true; 1378} 1379 1380// If Then makes up to four following instructions (the IT block) conditional. 1381bool 1382EmulateInstructionARM::EmulateIT (ARMEncoding encoding) 1383{ 1384#if 0 1385 // ARM pseudo code... 1386 EncodingSpecificOperations(); 1387 ITSTATE.IT<7:0> = firstcond:mask; 1388#endif 1389 1390 bool success = false; 1391 const uint32_t opcode = OpcodeAsUnsigned (&success); 1392 if (!success) 1393 return false; 1394 1395 m_it_session.InitIT(Bits32(opcode, 7, 0)); 1396 return true; 1397} 1398 1399// Branch causes a branch to a target address. 1400bool 1401EmulateInstructionARM::EmulateB (ARMEncoding encoding) 1402{ 1403#if 0 1404 // ARM pseudo code... 1405 if (ConditionPassed()) 1406 { 1407 EncodingSpecificOperations(); 1408 BranchWritePC(PC + imm32); 1409 } 1410#endif 1411 1412 bool success = false; 1413 const uint32_t opcode = OpcodeAsUnsigned (&success); 1414 if (!success) 1415 return false; 1416 1417 if (ConditionPassed()) 1418 { 1419 EmulateInstruction::Context context = { EmulateInstruction::eContextRelativeBranchImmediate, 0, 0, 0}; 1420 const uint32_t pc = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 0, &success); 1421 addr_t target; // target address 1422 if (!success) 1423 return false; 1424 int32_t imm32; // PC-relative offset 1425 switch (encoding) { 1426 case eEncodingT1: 1427 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1428 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 1429 target = pc + 4 + imm32; 1430 context.arg1 = 4 + imm32; // signed offset 1431 context.arg2 = eModeThumb; // target instruction set 1432 break; 1433 case eEncodingT2: 1434 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0)); 1435 target = pc + 4 + imm32; 1436 context.arg1 = 4 + imm32; // signed offset 1437 context.arg2 = eModeThumb; // target instruction set 1438 break; 1439 case eEncodingT3: 1440 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 1441 { 1442 uint32_t S = Bits32(opcode, 26, 26); 1443 uint32_t imm6 = Bits32(opcode, 21, 16); 1444 uint32_t J1 = Bits32(opcode, 13, 13); 1445 uint32_t J2 = Bits32(opcode, 11, 11); 1446 uint32_t imm11 = Bits32(opcode, 10, 0); 1447 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) + (imm11 << 1); 1448 imm32 = llvm::SignExtend32<21>(imm21); 1449 target = pc + 4 + imm32; 1450 context.arg1 = eModeThumb; // target instruction set 1451 context.arg2 = 4 + imm32; // signed offset 1452 break; 1453 } 1454 case eEncodingT4: 1455 { 1456 uint32_t S = Bits32(opcode, 26, 26); 1457 uint32_t imm10 = Bits32(opcode, 25, 16); 1458 uint32_t J1 = Bits32(opcode, 13, 13); 1459 uint32_t J2 = Bits32(opcode, 11, 11); 1460 uint32_t imm11 = Bits32(opcode, 10, 0); 1461 uint32_t I1 = !(J1 ^ S); 1462 uint32_t I2 = !(J2 ^ S); 1463 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) + (imm11 << 1); 1464 imm32 = llvm::SignExtend32<25>(imm25); 1465 target = pc + 4 + imm32; 1466 context.arg1 = eModeThumb; // target instruction set 1467 context.arg2 = 4 + imm32; // signed offset 1468 break; 1469 } 1470 case eEncodingA1: 1471 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1472 target = pc + 8 + imm32; 1473 context.arg1 = eModeARM; // target instruction set 1474 context.arg2 = 8 + imm32; // signed offset 1475 break; 1476 default: 1477 return false; 1478 } 1479 if (!BranchWritePC(context, target)) 1480 return false; 1481 } 1482 return true; 1483} 1484 1485// LDM loads multiple registers from consecutive memory locations, using an 1486// address from a base register. Optionally the addres just above the highest of those locations 1487// can be written back to the base register. 1488bool 1489EmulateInstructionARM::EmulateLDM (ARMEncoding encoding) 1490{ 1491#if 0 1492 // ARM pseudo code... 1493 if ConditionPassed() 1494 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 1495 address = R[n]; 1496 1497 for i = 0 to 14 1498 if registers<i> == '1' then 1499 R[i] = MemA[address, 4]; address = address + 4; 1500 if registers<15> == '1' then 1501 LoadWritePC (MemA[address, 4]); 1502 1503 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 1504 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1505 1506#endif 1507 1508 bool success = false; 1509 const uint32_t opcode = OpcodeAsUnsigned (&success); 1510 if (!success) 1511 return false; 1512 1513 if (ConditionPassed()) 1514 { 1515 uint32_t n; 1516 uint32_t registers = 0; 1517 bool wback; 1518 const uint32_t addr_byte_size = GetAddressByteSize(); 1519 switch (encoding) 1520 { 1521 case eEncodingT1: 1522 n = Bits32 (opcode, 10, 8); 1523 registers = Bits32 (opcode, 7, 0); 1524 wback = BitIsClear (registers, n); 1525 // if BitCount(registers) < 1 then UNPREDICTABLE; 1526 if (BitCount(registers) < 1) 1527 return false; 1528 break; 1529 case eEncodingT2: 1530 n = Bits32 (opcode, 19, 16); 1531 registers = Bits32 (opcode, 15, 0); 1532 wback = BitIsSet (opcode, 21); 1533 if ((n == 15) 1534 || (BitCount (registers) < 2) 1535 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 1536 return false; 1537 if (BitIsSet (registers, 15) 1538 && m_it_session.InITBlock() 1539 && !m_it_session.LastInITBlock()) 1540 return false; 1541 if (wback 1542 && BitIsSet (registers, n)) 1543 return false; 1544 break; 1545 case eEncodingA1: 1546 n = Bits32 (opcode, 19, 16); 1547 registers = Bits32 (opcode, 15, 0); 1548 wback = BitIsSet (opcode, 21); 1549 if ((n == 15) 1550 || (BitCount (registers) < 1)) 1551 return false; 1552 break; 1553 default: 1554 return false; 1555 } 1556 1557 int32_t offset = 0; 1558 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1559 if (!success) 1560 return false; 1561 1562 for (int i = 0; i < 14; ++i) 1563 { 1564 if (BitIsSet (registers, i)) 1565 { 1566 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1567 eRegisterKindDWARF, 1568 dwarf_r0 + n, 1569 offset }; 1570 1571 if (wback && (n == 13)) // Pop Instruction 1572 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1573 1574 // R[i] = MemA [address, 4]; address = address + 4; 1575 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 1576 if (!success) 1577 return false; 1578 1579 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 1580 return false; 1581 1582 offset += addr_byte_size; 1583 } 1584 } 1585 1586 if (BitIsSet (registers, 15)) 1587 { 1588 //LoadWritePC (MemA [address, 4]); 1589 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1590 eRegisterKindDWARF, 1591 dwarf_r0 + n, 1592 offset }; 1593 1594 uint32_t data = ReadMemoryUnsigned (context, base_address + offset, addr_byte_size, 0, &success); 1595 if (!success) 1596 return false; 1597 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, data)) 1598 return false; 1599 } 1600 1601 if (wback && BitIsClear (registers, n)) 1602 { 1603 addr_t offset = addr_byte_size * BitCount (registers); 1604 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1605 eRegisterKindDWARF, 1606 dwarf_r0 + n, 1607 offset }; 1608 1609 // R[n] = R[n] + 4 * BitCount (registers) 1610 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 1611 return false; 1612 } 1613 if (wback && BitIsSet (registers, n)) 1614 // R[n] bits(32) UNKNOWN; 1615 return false; //I'm not convinced this is the right thing to do here... 1616 } 1617 return true; 1618} 1619 1620bool 1621EmulateInstructionARM::EmulateLDMDB (ARMEncoding encoding) 1622{ 1623#if 0 1624 // ARM pseudo code... 1625 if ConditionPassed() then 1626 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 1627 address = R[n] - 4*BitCount(registers); 1628 1629 for i = 0 to 14 1630 if registers<i> == ’1’ then 1631 R[i] = MemA[address,4]; address = address + 4; 1632 if registers<15> == ’1’ then 1633 LoadWritePC(MemA[address,4]); 1634 1635 if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 1636 if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1637#endif 1638 1639 bool success = false; 1640 const uint32_t opcode = OpcodeAsUnsigned (&success); 1641 if (!success) 1642 return false; 1643 1644 if (ConditionPassed()) 1645 { 1646 uint32_t n; 1647 uint32_t registers = 0; 1648 bool wback; 1649 const uint32_t addr_byte_size = GetAddressByteSize(); 1650 switch (encoding) 1651 { 1652 case eEncodingT1: 1653 // n = UInt(Rn); registers = P:M:’0’:register_list; wback = (W == ’1’); 1654 n = Bits32 (opcode, 19, 16); 1655 registers = Bits32 (opcode, 15, 0); 1656 wback = BitIsSet (opcode, 21); 1657 1658 // if n == 15 || BitCount(registers) < 2 || (P == ’1’ && M == ’1’) then UNPREDICTABLE; 1659 if ((n == 15) 1660 || (BitCount (registers) < 2) 1661 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 1662 return false; 1663 1664 // if registers<15> == ’1’ && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 1665 if (BitIsSet (registers, 15) 1666 && m_it_session.InITBlock() 1667 && !m_it_session.LastInITBlock()) 1668 return false; 1669 1670 // if wback && registers<n> == ’1’ then UNPREDICTABLE; 1671 if (wback && BitIsSet (registers, n)) 1672 return false; 1673 1674 break; 1675 1676 case eEncodingA1: 1677 // n = UInt(Rn); registers = register_list; wback = (W == ’1’); 1678 n = Bits32 (opcode, 19, 16); 1679 registers = Bits32 (opcode, 15, 0); 1680 wback = BitIsSet (opcode, 21); 1681 1682 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 1683 if ((n == 15) || (BitCount (registers) < 1)) 1684 return false; 1685 1686 break; 1687 1688 default: 1689 return false; 1690 } 1691 1692 int32_t offset = 0; 1693 addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success) 1694 - (addr_byte_size * BitCount (registers)); 1695 1696 for (int i = 0; i < 14; ++i) 1697 { 1698 if (BitIsSet (registers, i)) 1699 { 1700 // R[i] = MemA[address,4]; address = address + 4; 1701 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1702 eRegisterKindDWARF, 1703 dwarf_r0 + n, 1704 offset }; 1705 1706 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 1707 if (!success) 1708 return false; 1709 1710 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 1711 return false; 1712 1713 offset += addr_byte_size; 1714 } 1715 } 1716 1717 // if registers<15> == ’1’ then 1718 // LoadWritePC(MemA[address,4]); 1719 if (BitIsSet (registers, 15)) 1720 { 1721 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1722 eRegisterKindDWARF, 1723 dwarf_r0 + n, 1724 offset }; 1725 1726 uint32_t data = ReadMemoryUnsigned (context, address + offset, addr_byte_size, 0, &success); 1727 if (!success) 1728 return false; 1729 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, data)) 1730 return false; 1731 } 1732 1733 // if wback && registers<n> == ’0’ then R[n] = R[n] - 4*BitCount(registers); 1734 if (wback && BitIsClear (registers, n)) 1735 { 1736 EmulateInstruction::Context context = { EmulateInstruction::eContextRegisterPlusOffset, 1737 eRegisterKindDWARF, 1738 dwarf_r0 + n, 1739 offset }; 1740 1741 addr_t addr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1742 if (!success) 1743 return false; 1744 addr = addr - (addr_byte_size * BitCount (registers)); 1745 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 1746 return false; 1747 } 1748 1749 // if wback && registers<n> == ’1’ then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 1750 if (wback && BitIsSet (registers, n)) 1751 return false; // I'm not sure this is right; how do I set R[n] to bits(32) UNKNOWN. 1752 } 1753 return true; 1754} 1755 1756EmulateInstructionARM::ARMOpcode* 1757EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 1758{ 1759 static ARMOpcode 1760 g_arm_opcodes[] = 1761 { 1762 //---------------------------------------------------------------------- 1763 // Prologue instructions 1764 //---------------------------------------------------------------------- 1765 1766 // push register(s) 1767 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 1768 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePush, "push <register>" }, 1769 1770 // set r7 to point to a stack offset 1771 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #<const>" }, 1772 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"}, 1773 // set ip to point to a stack offset 1774 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMovRdSP, "mov ip, sp" }, 1775 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add ip, sp, #<const>" }, 1776 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"}, 1777 1778 // adjust the stack pointer 1779 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"}, 1780 1781 // push one register 1782 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 1783 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 1784 1785 // vector push consecutive extension register(s) 1786 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 1787 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 1788 1789 //---------------------------------------------------------------------- 1790 // Epilogue instructions 1791 //---------------------------------------------------------------------- 1792 1793 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 1794 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 1795 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 1796 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 1797 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 1798 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePop, "pop <register>"}, 1799 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 1800 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 1801 1802 //---------------------------------------------------------------------- 1803 // Supervisor Call (previously Software Interrupt) 1804 //---------------------------------------------------------------------- 1805 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 1806 1807 //---------------------------------------------------------------------- 1808 // Branch instructions 1809 //---------------------------------------------------------------------- 1810 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 1811 1812 //---------------------------------------------------------------------- 1813 // Load instructions 1814 //---------------------------------------------------------------------- 1815 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 1816 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" } 1817 1818 }; 1819 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 1820 1821 for (size_t i=0; i<k_num_arm_opcodes; ++i) 1822 { 1823 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 1824 return &g_arm_opcodes[i]; 1825 } 1826 return NULL; 1827} 1828 1829 1830EmulateInstructionARM::ARMOpcode* 1831EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 1832{ 1833 1834 static ARMOpcode 1835 g_thumb_opcodes[] = 1836 { 1837 //---------------------------------------------------------------------- 1838 // Prologue instructions 1839 //---------------------------------------------------------------------- 1840 1841 // push register(s) 1842 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 1843 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <registers>" }, 1844 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <register>" }, 1845 // move from high register to low register 1846 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovLowHigh, "mov r0-r7, r8-r15" }, 1847 1848 // set r7 to point to a stack offset 1849 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #imm" }, 1850 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdSP, "mov r7, sp" }, 1851 1852 // PC relative load into register (see also EmulateAddSPRm) 1853 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRdPCRelative, "ldr <Rd>, [PC, #imm]"}, 1854 1855 // adjust the stack pointer 1856 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"}, 1857 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"}, 1858 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"}, 1859 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"}, 1860 1861 // vector push consecutive extension register(s) 1862 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 1863 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 1864 1865 //---------------------------------------------------------------------- 1866 // Epilogue instructions 1867 //---------------------------------------------------------------------- 1868 1869 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"}, 1870 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 1871 // J1 == J2 == 1 1872 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 1873 // J1 == J2 == 1 1874 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 1875 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 1876 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <registers>" }, 1877 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <register>" }, 1878 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 1879 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 1880 1881 //---------------------------------------------------------------------- 1882 // Supervisor Call (previously Software Interrupt) 1883 //---------------------------------------------------------------------- 1884 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 1885 1886 //---------------------------------------------------------------------- 1887 // If Then makes up to four following instructions conditional. 1888 //---------------------------------------------------------------------- 1889 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 1890 1891 //---------------------------------------------------------------------- 1892 // Branch instructions 1893 //---------------------------------------------------------------------- 1894 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 1895 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 1896 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 1897 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 1898 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 1899 1900 1901 //---------------------------------------------------------------------- 1902 // Load instructions 1903 //---------------------------------------------------------------------- 1904 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 1905 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 1906 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" } 1907 1908 }; 1909 1910 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 1911 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 1912 { 1913 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 1914 return &g_thumb_opcodes[i]; 1915 } 1916 return NULL; 1917} 1918 1919bool 1920EmulateInstructionARM::SetTargetTriple (const ConstString &triple) 1921{ 1922 m_arm_isa = 0; 1923 const char *triple_cstr = triple.GetCString(); 1924 if (triple_cstr) 1925 { 1926 const char *dash = ::strchr (triple_cstr, '-'); 1927 if (dash) 1928 { 1929 std::string arch (triple_cstr, dash); 1930 const char *arch_cstr = arch.c_str(); 1931 if (strcasecmp(arch_cstr, "armv4t") == 0) 1932 m_arm_isa = ARMv4T; 1933 else if (strcasecmp(arch_cstr, "armv4") == 0) 1934 m_arm_isa = ARMv4; 1935 else if (strcasecmp(arch_cstr, "armv5tej") == 0) 1936 m_arm_isa = ARMv5TEJ; 1937 else if (strcasecmp(arch_cstr, "armv5te") == 0) 1938 m_arm_isa = ARMv5TE; 1939 else if (strcasecmp(arch_cstr, "armv5t") == 0) 1940 m_arm_isa = ARMv5T; 1941 else if (strcasecmp(arch_cstr, "armv6k") == 0) 1942 m_arm_isa = ARMv6K; 1943 else if (strcasecmp(arch_cstr, "armv6") == 0) 1944 m_arm_isa = ARMv6; 1945 else if (strcasecmp(arch_cstr, "armv6t2") == 0) 1946 m_arm_isa = ARMv6T2; 1947 else if (strcasecmp(arch_cstr, "armv7") == 0) 1948 m_arm_isa = ARMv7; 1949 else if (strcasecmp(arch_cstr, "armv8") == 0) 1950 m_arm_isa = ARMv8; 1951 } 1952 } 1953 return m_arm_isa != 0; 1954} 1955 1956 1957bool 1958EmulateInstructionARM::ReadInstruction () 1959{ 1960 bool success = false; 1961 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 1962 if (success) 1963 { 1964 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 1965 if (success) 1966 { 1967 Context read_inst_context = {eContextReadOpcode, 0, 0}; 1968 if (m_inst_cpsr & MASK_CPSR_T) 1969 { 1970 m_inst_mode = eModeThumb; 1971 uint32_t thumb_opcode = ReadMemoryUnsigned(read_inst_context, pc, 2, 0, &success); 1972 1973 if (success) 1974 { 1975 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 1976 { 1977 m_inst.opcode_type = eOpcode16; 1978 m_inst.opcode.inst16 = thumb_opcode; 1979 } 1980 else 1981 { 1982 m_inst.opcode_type = eOpcode32; 1983 m_inst.opcode.inst32 = (thumb_opcode << 16) | ReadMemoryUnsigned(read_inst_context, pc + 2, 2, 0, &success); 1984 } 1985 } 1986 } 1987 else 1988 { 1989 m_inst_mode = eModeARM; 1990 m_inst.opcode_type = eOpcode32; 1991 m_inst.opcode.inst32 = ReadMemoryUnsigned(read_inst_context, pc, 4, 0, &success); 1992 } 1993 } 1994 } 1995 if (!success) 1996 { 1997 m_inst_mode = eModeInvalid; 1998 m_inst_pc = LLDB_INVALID_ADDRESS; 1999 } 2000 return success; 2001} 2002 2003bool 2004EmulateInstructionARM::ConditionPassed () 2005{ 2006 if (m_inst_cpsr == 0) 2007 return false; 2008 2009 const uint32_t cond = CurrentCond (); 2010 2011 if (cond == UINT32_MAX) 2012 return false; 2013 2014 bool result = false; 2015 switch (UnsignedBits(cond, 3, 1)) 2016 { 2017 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 2018 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 2019 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 2020 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 2021 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 2022 case 5: 2023 { 2024 bool n = (m_inst_cpsr & MASK_CPSR_N); 2025 bool v = (m_inst_cpsr & MASK_CPSR_V); 2026 result = n == v; 2027 } 2028 break; 2029 case 6: 2030 { 2031 bool n = (m_inst_cpsr & MASK_CPSR_N); 2032 bool v = (m_inst_cpsr & MASK_CPSR_V); 2033 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 2034 } 2035 break; 2036 case 7: 2037 result = true; 2038 break; 2039 } 2040 2041 if (cond & 1) 2042 result = !result; 2043 return result; 2044} 2045 2046uint32_t 2047EmulateInstructionARM::CurrentCond () 2048{ 2049 switch (m_inst_mode) 2050 { 2051 default: 2052 case eModeInvalid: 2053 break; 2054 2055 case eModeARM: 2056 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 2057 2058 case eModeThumb: 2059 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 2060 // 'cond' field of the encoding. 2061 if (m_inst.opcode_type == eOpcode16 && 2062 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 2063 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 2064 { 2065 return Bits32(m_inst.opcode.inst16, 11, 7); 2066 } 2067 else if (m_inst.opcode_type == eOpcode32 && 2068 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 2069 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 2070 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 2071 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 2072 { 2073 return Bits32(m_inst.opcode.inst32, 25, 22); 2074 } 2075 2076 return m_it_session.GetCond(); 2077 } 2078 return UINT32_MAX; // Return invalid value 2079} 2080 2081// API client must pass in a context whose arg2 field contains the target instruction set. 2082bool 2083EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 2084{ 2085 addr_t target; 2086 2087 // Chech the target instruction set. 2088 switch (context.arg2) 2089 { 2090 default: 2091 assert(0 && "BranchWritePC expects context.arg1 with either eModeARM or eModeThumb"); 2092 return false; 2093 case eModeARM: 2094 target = addr & 0xfffffffc; 2095 break; 2096 case eModeThumb: 2097 target = addr & 0xfffffffe; 2098 break; 2099 } 2100 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 2101 return false; 2102 return false; 2103} 2104 2105// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 2106bool 2107EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 2108{ 2109 addr_t target; 2110 2111 if (BitIsSet(addr, 0)) 2112 { 2113 target = addr & 0xfffffffe; 2114 context.arg2 = eModeThumb; 2115 } 2116 else if (BitIsClear(addr, 1)) 2117 { 2118 target = addr & 0xfffffffc; 2119 context.arg2 = eModeARM; 2120 } 2121 else 2122 return false; // address<1:0> == '10' => UNPREDICTABLE 2123 2124 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 2125 return false; 2126 return false; 2127} 2128 2129bool 2130EmulateInstructionARM::EvaluateInstruction () 2131{ 2132 // Advance the ITSTATE bits to their values for the next instruction. 2133 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 2134 m_it_session.ITAdvance(); 2135 2136 return false; 2137} 2138