EmulateInstructionARM.cpp revision b9f76c33ab97dcef2e9c1dbc471097edd6b98a86
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 1620EmulateInstructionARM::ARMOpcode* 1621EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) 1622{ 1623 static ARMOpcode 1624 g_arm_opcodes[] = 1625 { 1626 //---------------------------------------------------------------------- 1627 // Prologue instructions 1628 //---------------------------------------------------------------------- 1629 1630 // push register(s) 1631 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 1632 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePush, "push <register>" }, 1633 1634 // set r7 to point to a stack offset 1635 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #<const>" }, 1636 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubR7IPImmediate, "sub r7, ip, #<const>"}, 1637 // set ip to point to a stack offset 1638 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateMovRdSP, "mov ip, sp" }, 1639 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add ip, sp, #<const>" }, 1640 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubIPSPImmediate, "sub ip, sp, #<const>"}, 1641 1642 // adjust the stack pointer 1643 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub sp, sp, #<const>"}, 1644 1645 // push one register 1646 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 1647 { 0x0fff0000, 0x052d0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 1648 1649 // vector push consecutive extension register(s) 1650 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 1651 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 1652 1653 //---------------------------------------------------------------------- 1654 // Epilogue instructions 1655 //---------------------------------------------------------------------- 1656 1657 // To resolve ambiguity, "blx <label>" should come before "bl <label>". 1658 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 1659 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 1660 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 1661 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 1662 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, eSize32, &EmulateInstructionARM::EmulatePop, "pop <register>"}, 1663 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 1664 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 1665 1666 //---------------------------------------------------------------------- 1667 // Supervisor Call (previously Software Interrupt) 1668 //---------------------------------------------------------------------- 1669 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 1670 1671 //---------------------------------------------------------------------- 1672 // Branch instructions 1673 //---------------------------------------------------------------------- 1674 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateSVC, "b #imm24"}, 1675 1676 //---------------------------------------------------------------------- 1677 // Load instructions 1678 //---------------------------------------------------------------------- 1679 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" } 1680 1681 }; 1682 static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode); 1683 1684 for (size_t i=0; i<k_num_arm_opcodes; ++i) 1685 { 1686 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) 1687 return &g_arm_opcodes[i]; 1688 } 1689 return NULL; 1690} 1691 1692 1693EmulateInstructionARM::ARMOpcode* 1694EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) 1695{ 1696 1697 static ARMOpcode 1698 g_thumb_opcodes[] = 1699 { 1700 //---------------------------------------------------------------------- 1701 // Prologue instructions 1702 //---------------------------------------------------------------------- 1703 1704 // push register(s) 1705 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePush, "push <registers>" }, 1706 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <registers>" }, 1707 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePush, "push.w <register>" }, 1708 // move from high register to low register 1709 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovLowHigh, "mov r0-r7, r8-r15" }, 1710 1711 // set r7 to point to a stack offset 1712 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateAddRdSPImmediate, "add r7, sp, #imm" }, 1713 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateMovRdSP, "mov r7, sp" }, 1714 1715 // PC relative load into register (see also EmulateAddSPRm) 1716 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDRRdPCRelative, "ldr <Rd>, [PC, #imm]"}, 1717 1718 // adjust the stack pointer 1719 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPRm, "add sp, <Rm>"}, 1720 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSubSPImmdiate, "add sp, sp, #imm"}, 1721 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "sub.w sp, sp, #<const>"}, 1722 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateSubSPImmdiate, "subw sp, sp, #imm12"}, 1723 1724 // vector push consecutive extension register(s) 1725 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 1726 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 1727 1728 //---------------------------------------------------------------------- 1729 // Epilogue instructions 1730 //---------------------------------------------------------------------- 1731 1732 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateAddSPImmediate, "add sp, #imm"}, 1733 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 1734 // J1 == J2 == 1 1735 { 0xf800f800, 0xf000f800, ARMV4T_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 1736 // J1 == J2 == 1 1737 { 0xf800e800, 0xf000e800, ARMV5_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 1738 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulatePop, "pop <registers>"}, 1739 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <registers>" }, 1740 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulatePop, "pop.w <register>" }, 1741 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 1742 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 1743 1744 //---------------------------------------------------------------------- 1745 // Supervisor Call (previously Software Interrupt) 1746 //---------------------------------------------------------------------- 1747 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 1748 1749 //---------------------------------------------------------------------- 1750 // If Then makes up to four following instructions conditional. 1751 //---------------------------------------------------------------------- 1752 { 0xffffff00, 0x0000bf00, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 1753 1754 //---------------------------------------------------------------------- 1755 // Branch instructions 1756 //---------------------------------------------------------------------- 1757 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 1758 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 1759 { 0xffff8000, 0x0000e000, ARMvAll, eEncodingT2, eSize16, &EmulateInstructionARM::EmulateB, "b #imm11 (outside or last in IT)"}, 1760 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 1761 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, eSize32, &EmulateInstructionARM::EmulateB, "b.w #imm8 (outside or last in IT)"}, 1762 1763 1764 //---------------------------------------------------------------------- 1765 // Load instructions 1766 //---------------------------------------------------------------------- 1767 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 1768 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" } 1769 1770 }; 1771 1772 const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); 1773 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 1774 { 1775 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) 1776 return &g_thumb_opcodes[i]; 1777 } 1778 return NULL; 1779} 1780 1781bool 1782EmulateInstructionARM::SetTargetTriple (const ConstString &triple) 1783{ 1784 m_arm_isa = 0; 1785 const char *triple_cstr = triple.GetCString(); 1786 if (triple_cstr) 1787 { 1788 const char *dash = ::strchr (triple_cstr, '-'); 1789 if (dash) 1790 { 1791 std::string arch (triple_cstr, dash); 1792 const char *arch_cstr = arch.c_str(); 1793 if (strcasecmp(arch_cstr, "armv4t") == 0) 1794 m_arm_isa = ARMv4T; 1795 else if (strcasecmp(arch_cstr, "armv4") == 0) 1796 m_arm_isa = ARMv4; 1797 else if (strcasecmp(arch_cstr, "armv5tej") == 0) 1798 m_arm_isa = ARMv5TEJ; 1799 else if (strcasecmp(arch_cstr, "armv5te") == 0) 1800 m_arm_isa = ARMv5TE; 1801 else if (strcasecmp(arch_cstr, "armv5t") == 0) 1802 m_arm_isa = ARMv5T; 1803 else if (strcasecmp(arch_cstr, "armv6k") == 0) 1804 m_arm_isa = ARMv6K; 1805 else if (strcasecmp(arch_cstr, "armv6") == 0) 1806 m_arm_isa = ARMv6; 1807 else if (strcasecmp(arch_cstr, "armv6t2") == 0) 1808 m_arm_isa = ARMv6T2; 1809 else if (strcasecmp(arch_cstr, "armv7") == 0) 1810 m_arm_isa = ARMv7; 1811 else if (strcasecmp(arch_cstr, "armv8") == 0) 1812 m_arm_isa = ARMv8; 1813 } 1814 } 1815 return m_arm_isa != 0; 1816} 1817 1818 1819bool 1820EmulateInstructionARM::ReadInstruction () 1821{ 1822 bool success = false; 1823 m_inst_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 1824 if (success) 1825 { 1826 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 1827 if (success) 1828 { 1829 Context read_inst_context = {eContextReadOpcode, 0, 0}; 1830 if (m_inst_cpsr & MASK_CPSR_T) 1831 { 1832 m_inst_mode = eModeThumb; 1833 uint32_t thumb_opcode = ReadMemoryUnsigned(read_inst_context, pc, 2, 0, &success); 1834 1835 if (success) 1836 { 1837 if ((m_inst.opcode.inst16 & 0xe000) != 0xe000 || ((m_inst.opcode.inst16 & 0x1800u) == 0)) 1838 { 1839 m_inst.opcode_type = eOpcode16; 1840 m_inst.opcode.inst16 = thumb_opcode; 1841 } 1842 else 1843 { 1844 m_inst.opcode_type = eOpcode32; 1845 m_inst.opcode.inst32 = (thumb_opcode << 16) | ReadMemoryUnsigned(read_inst_context, pc + 2, 2, 0, &success); 1846 } 1847 } 1848 } 1849 else 1850 { 1851 m_inst_mode = eModeARM; 1852 m_inst.opcode_type = eOpcode32; 1853 m_inst.opcode.inst32 = ReadMemoryUnsigned(read_inst_context, pc, 4, 0, &success); 1854 } 1855 } 1856 } 1857 if (!success) 1858 { 1859 m_inst_mode = eModeInvalid; 1860 m_inst_pc = LLDB_INVALID_ADDRESS; 1861 } 1862 return success; 1863} 1864 1865bool 1866EmulateInstructionARM::ConditionPassed () 1867{ 1868 if (m_inst_cpsr == 0) 1869 return false; 1870 1871 const uint32_t cond = CurrentCond (); 1872 1873 if (cond == UINT32_MAX) 1874 return false; 1875 1876 bool result = false; 1877 switch (UnsignedBits(cond, 3, 1)) 1878 { 1879 case 0: result = (m_inst_cpsr & MASK_CPSR_Z) != 0; break; 1880 case 1: result = (m_inst_cpsr & MASK_CPSR_C) != 0; break; 1881 case 2: result = (m_inst_cpsr & MASK_CPSR_N) != 0; break; 1882 case 3: result = (m_inst_cpsr & MASK_CPSR_V) != 0; break; 1883 case 4: result = ((m_inst_cpsr & MASK_CPSR_C) != 0) && ((m_inst_cpsr & MASK_CPSR_Z) == 0); break; 1884 case 5: 1885 { 1886 bool n = (m_inst_cpsr & MASK_CPSR_N); 1887 bool v = (m_inst_cpsr & MASK_CPSR_V); 1888 result = n == v; 1889 } 1890 break; 1891 case 6: 1892 { 1893 bool n = (m_inst_cpsr & MASK_CPSR_N); 1894 bool v = (m_inst_cpsr & MASK_CPSR_V); 1895 result = n == v && ((m_inst_cpsr & MASK_CPSR_Z) == 0); 1896 } 1897 break; 1898 case 7: 1899 result = true; 1900 break; 1901 } 1902 1903 if (cond & 1) 1904 result = !result; 1905 return result; 1906} 1907 1908uint32_t 1909EmulateInstructionARM::CurrentCond () 1910{ 1911 switch (m_inst_mode) 1912 { 1913 default: 1914 case eModeInvalid: 1915 break; 1916 1917 case eModeARM: 1918 return UnsignedBits(m_inst.opcode.inst32, 31, 28); 1919 1920 case eModeThumb: 1921 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 1922 // 'cond' field of the encoding. 1923 if (m_inst.opcode_type == eOpcode16 && 1924 Bits32(m_inst.opcode.inst16, 15, 12) == 0x0d && 1925 Bits32(m_inst.opcode.inst16, 11, 7) != 0x0f) 1926 { 1927 return Bits32(m_inst.opcode.inst16, 11, 7); 1928 } 1929 else if (m_inst.opcode_type == eOpcode32 && 1930 Bits32(m_inst.opcode.inst32, 31, 27) == 0x1e && 1931 Bits32(m_inst.opcode.inst32, 15, 14) == 0x02 && 1932 Bits32(m_inst.opcode.inst32, 12, 12) == 0x00 && 1933 Bits32(m_inst.opcode.inst32, 25, 22) <= 0x0d) 1934 { 1935 return Bits32(m_inst.opcode.inst32, 25, 22); 1936 } 1937 1938 return m_it_session.GetCond(); 1939 } 1940 return UINT32_MAX; // Return invalid value 1941} 1942 1943// API client must pass in a context whose arg2 field contains the target instruction set. 1944bool 1945EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 1946{ 1947 addr_t target; 1948 1949 // Chech the target instruction set. 1950 switch (context.arg2) 1951 { 1952 default: 1953 assert(0 && "BranchWritePC expects context.arg1 with either eModeARM or eModeThumb"); 1954 return false; 1955 case eModeARM: 1956 target = addr & 0xfffffffc; 1957 break; 1958 case eModeThumb: 1959 target = addr & 0xfffffffe; 1960 break; 1961 } 1962 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1963 return false; 1964 return false; 1965} 1966 1967// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 1968bool 1969EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 1970{ 1971 addr_t target; 1972 1973 if (BitIsSet(addr, 0)) 1974 { 1975 target = addr & 0xfffffffe; 1976 context.arg2 = eModeThumb; 1977 } 1978 else if (BitIsClear(addr, 1)) 1979 { 1980 target = addr & 0xfffffffc; 1981 context.arg2 = eModeARM; 1982 } 1983 else 1984 return false; // address<1:0> == '10' => UNPREDICTABLE 1985 1986 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 1987 return false; 1988 return false; 1989} 1990 1991bool 1992EmulateInstructionARM::EvaluateInstruction () 1993{ 1994 // Advance the ITSTATE bits to their values for the next instruction. 1995 if (m_inst_mode == eModeThumb && m_it_session.InITBlock()) 1996 m_it_session.ITAdvance(); 1997 1998 return false; 1999} 2000