EmulateInstructionARM.h revision b344843f75ef893762c93fd0a22d2d45712ce74d
1//===-- lldb_EmulateInstructionARM.h ------------------------------------*- 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#ifndef lldb_EmulateInstructionARM_h_ 11#define lldb_EmulateInstructionARM_h_ 12 13#include "lldb/Core/EmulateInstruction.h" 14#include "lldb/Core/Error.h" 15#include "Plugins/Process/Utility/ARMDefines.h" 16 17namespace lldb_private { 18 19// ITSession - Keep track of the IT Block progression. 20class ITSession 21{ 22public: 23 ITSession() : ITCounter(0), ITState(0) {} 24 ~ITSession() {} 25 26 // InitIT - Initializes ITCounter/ITState. 27 bool InitIT(unsigned short bits7_0); 28 29 // ITAdvance - Updates ITCounter/ITState as IT Block progresses. 30 void ITAdvance(); 31 32 // InITBlock - Returns true if we're inside an IT Block. 33 bool InITBlock(); 34 35 // LastInITBlock - Returns true if we're the last instruction inside an IT Block. 36 bool LastInITBlock(); 37 38 // GetCond - Gets condition bits for the current thumb instruction. 39 uint32_t GetCond(); 40 41private: 42 uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4. 43 uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially. 44}; 45 46class EmulateInstructionARM : public EmulateInstruction 47{ 48public: 49 typedef enum 50 { 51 eEncodingA1, 52 eEncodingA2, 53 eEncodingA3, 54 eEncodingA4, 55 eEncodingA5, 56 eEncodingT1, 57 eEncodingT2, 58 eEncodingT3, 59 eEncodingT4, 60 eEncodingT5 61 } ARMEncoding; 62 63 64 static void 65 Initialize (); 66 67 static void 68 Terminate (); 69 70 virtual const char * 71 GetPluginName() 72 { 73 return "EmulateInstructionARM"; 74 } 75 76 virtual const char * 77 GetShortPluginName() 78 { 79 return "lldb.emulate-instruction.arm"; 80 } 81 82 virtual uint32_t 83 GetPluginVersion() 84 { 85 return 1; 86 } 87 88 enum Mode 89 { 90 eModeInvalid, 91 eModeARM, 92 eModeThumb 93 }; 94 95 EmulateInstructionARM (void *baton, 96 ReadMemory read_mem_callback, 97 WriteMemory write_mem_callback, 98 ReadRegister read_reg_callback, 99 WriteRegister write_reg_callback) : 100 EmulateInstruction (lldb::eByteOrderLittle, // Byte order for ARM 101 4, // Address size in byte 102 baton, 103 read_mem_callback, 104 write_mem_callback, 105 read_reg_callback, 106 write_reg_callback), 107 m_arm_isa (0), 108 m_opcode_mode (eModeInvalid), 109 m_opcode_cpsr (0), 110 m_it_session () 111 { 112 } 113 114 115 virtual bool 116 SetArchitecture (const ArchSpec &arch); 117 118 virtual bool 119 ReadInstruction (); 120 121 virtual bool 122 EvaluateInstruction (); 123 124 uint32_t 125 ArchVersion(); 126 127 bool 128 ConditionPassed (); 129 130 uint32_t 131 CurrentCond (); 132 133 // InITBlock - Returns true if we're in Thumb mode and inside an IT Block. 134 bool InITBlock(); 135 136 // LastInITBlock - Returns true if we're in Thumb mode and the last instruction inside an IT Block. 137 bool LastInITBlock(); 138 139 bool 140 BadMode (uint32_t mode); 141 142 bool 143 CurrentModeIsPrivileged (); 144 145 void 146 CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate); 147 148 bool 149 BranchWritePC(const Context &context, uint32_t addr); 150 151 bool 152 BXWritePC(Context &context, uint32_t addr); 153 154 bool 155 LoadWritePC(Context &context, uint32_t addr); 156 157 bool 158 ALUWritePC(Context &context, uint32_t addr); 159 160 Mode 161 CurrentInstrSet(); 162 163 bool 164 SelectInstrSet(Mode arm_or_thumb); 165 166 bool 167 WriteBits32Unknown (int n); 168 169 bool 170 WriteBits32UnknownToMemory (lldb::addr_t address); 171 172 bool 173 UnalignedSupport(); 174 175 typedef struct 176 { 177 uint32_t result; 178 uint8_t carry_out; 179 uint8_t overflow; 180 } AddWithCarryResult; 181 182 AddWithCarryResult 183 AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in); 184 185 // Helper method to read the content of an ARM core register. 186 uint32_t 187 ReadCoreReg (uint32_t regnum, bool *success); 188 189 // See A8.6.96 MOV (immediate) Operation. 190 // Default arguments are specified for carry and overflow parameters, which means 191 // not to update the respective flags even if setflags is true. 192 bool 193 WriteCoreRegOptionalFlags (Context &context, 194 const uint32_t result, 195 const uint32_t Rd, 196 bool setflags, 197 const uint32_t carry = ~0u, 198 const uint32_t overflow = ~0u); 199 200 bool 201 WriteCoreReg (Context &context, 202 const uint32_t result, 203 const uint32_t Rd) 204 { 205 // Don't set the flags. 206 return WriteCoreRegOptionalFlags(context, result, Rd, false); 207 } 208 209 // See A8.6.35 CMP (immediate) Operation. 210 // Default arguments are specified for carry and overflow parameters, which means 211 // not to update the respective flags. 212 bool 213 WriteFlags (Context &context, 214 const uint32_t result, 215 const uint32_t carry = ~0u, 216 const uint32_t overflow = ~0u); 217 218 inline uint64_t 219 MemARead (EmulateInstruction::Context &context, 220 lldb::addr_t address, 221 uint32_t size, 222 uint64_t fail_value, 223 bool *success_ptr) 224 { 225 // This is a stub function corresponding to "MemA[]" in the ARM manual pseudocode, for 226 // aligned reads from memory. Since we are not trying to write a full hardware simulator, and since 227 // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the 228 // system registers we would need in order to fully implement this function, we will just call 229 // ReadMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of 230 // the hardware, we can update this function appropriately. 231 232 return ReadMemoryUnsigned (context, address, size, fail_value, success_ptr); 233 } 234 235 inline bool 236 MemAWrite (EmulateInstruction::Context &context, 237 lldb::addr_t address, 238 uint64_t data_val, 239 uint32_t size) 240 241 { 242 // This is a stub function corresponding to "MemA[]" in the ARM manual pseudocode, for 243 // aligned writes to memory. Since we are not trying to write a full hardware simulator, and since 244 // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the 245 // system registers we would need in order to fully implement this function, we will just call 246 // WriteMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of 247 // the hardware, we can update this function appropriately. 248 249 return WriteMemoryUnsigned (context, address, data_val, size); 250 } 251 252 253 inline uint64_t 254 MemURead (EmulateInstruction::Context &context, 255 lldb::addr_t address, 256 uint32_t size, 257 uint64_t fail_value, 258 bool *success_ptr) 259 { 260 // This is a stub function corresponding to "MemU[]" in the ARM manual pseudocode, for 261 // unaligned reads from memory. Since we are not trying to write a full hardware simulator, and since 262 // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the 263 // system registers we would need in order to fully implement this function, we will just call 264 // ReadMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of 265 // the hardware, we can update this function appropriately. 266 267 return ReadMemoryUnsigned (context, address, size, fail_value, success_ptr); 268 } 269 270 inline bool 271 MemUWrite (EmulateInstruction::Context &context, 272 lldb::addr_t address, 273 uint64_t data_val, 274 uint32_t size) 275 276 { 277 // This is a stub function corresponding to "MemU[]" in the ARM manual pseudocode, for 278 // unaligned writes to memory. Since we are not trying to write a full hardware simulator, and since 279 // we are running in User mode (rather than Kernel mode) and therefore won't have access to many of the 280 // system registers we would need in order to fully implement this function, we will just call 281 // WriteMemoryUnsigned from here. In the future, if we decide we do need to do more faithful emulation of 282 // the hardware, we can update this function appropriately. 283 284 return WriteMemoryUnsigned (context, address, data_val, size); 285 } 286 287protected: 288 289 // Typedef for the callback function used during the emulation. 290 // Pass along (ARMEncoding)encoding as the callback data. 291 typedef enum 292 { 293 eSize16, 294 eSize32 295 } ARMInstrSize; 296 297 typedef struct 298 { 299 uint32_t mask; 300 uint32_t value; 301 uint32_t variants; 302 EmulateInstructionARM::ARMEncoding encoding; 303 ARMInstrSize size; 304 bool (EmulateInstructionARM::*callback) (EmulateInstructionARM::ARMEncoding encoding); 305 const char *name; 306 } ARMOpcode; 307 308 309 static ARMOpcode* 310 GetARMOpcodeForInstruction (const uint32_t opcode); 311 312 static ARMOpcode* 313 GetThumbOpcodeForInstruction (const uint32_t opcode); 314 315 // A8.6.123 PUSH 316 bool 317 EmulatePUSH (ARMEncoding encoding); 318 319 // A8.6.122 POP 320 bool 321 EmulatePOP (ARMEncoding encoding); 322 323 // A8.6.8 ADD (SP plus immediate) 324 bool 325 EmulateADDRdSPImm (ARMEncoding encoding); 326 327 // A8.6.97 MOV (register) -- Rd == r7|ip and Rm == sp 328 bool 329 EmulateMOVRdSP (ARMEncoding encoding); 330 331 // A8.6.97 MOV (register) -- move from r8-r15 to r0-r7 332 bool 333 EmulateMOVLowHigh (ARMEncoding encoding); 334 335 // A8.6.59 LDR (literal) 336 bool 337 EmulateLDRRtPCRelative (ARMEncoding encoding); 338 339 // A8.6.8 ADD (SP plus immediate) 340 bool 341 EmulateADDSPImm (ARMEncoding encoding); 342 343 // A8.6.9 ADD (SP plus register) 344 bool 345 EmulateADDSPRm (ARMEncoding encoding); 346 347 // A8.6.23 BL, BLX (immediate) 348 bool 349 EmulateBLXImmediate (ARMEncoding encoding); 350 351 // A8.6.24 BLX (register) 352 bool 353 EmulateBLXRm (ARMEncoding encoding); 354 355 // A8.6.25 BX 356 bool 357 EmulateBXRm (ARMEncoding encoding); 358 359 // A8.6.26 BXJ 360 bool 361 EmulateBXJRm (ARMEncoding encoding); 362 363 // A8.6.212 SUB (immediate, ARM) -- Rd == r7 and Rm == ip 364 bool 365 EmulateSUBR7IPImm (ARMEncoding encoding); 366 367 // A8.6.215 SUB (SP minus immediate) -- Rd == ip 368 bool 369 EmulateSUBIPSPImm (ARMEncoding encoding); 370 371 // A8.6.215 SUB (SP minus immediate) 372 bool 373 EmulateSUBSPImm (ARMEncoding encoding); 374 375 // A8.6.194 STR (immediate, ARM) -- Rn == sp 376 bool 377 EmulateSTRRtSP (ARMEncoding encoding); 378 379 // A8.6.355 VPUSH 380 bool 381 EmulateVPUSH (ARMEncoding encoding); 382 383 // A8.6.354 VPOP 384 bool 385 EmulateVPOP (ARMEncoding encoding); 386 387 // A8.6.218 SVC (previously SWI) 388 bool 389 EmulateSVC (ARMEncoding encoding); 390 391 // A8.6.50 IT 392 bool 393 EmulateIT (ARMEncoding encoding); 394 395 // A8.6.16 B 396 bool 397 EmulateB (ARMEncoding encoding); 398 399 // A8.6.27 CBNZ, CBZ 400 bool 401 EmulateCB (ARMEncoding encoding); 402 403 // A8.6.226 TBB, TBH 404 bool 405 EmulateTB (ARMEncoding encoding); 406 407 // A8.6.4 ADD (immediate, Thumb) 408 bool 409 EmulateADDImmThumb (ARMEncoding encoding); 410 411 // A8.6.5 ADD (immediate, ARM) 412 bool 413 EmulateADDImmARM (ARMEncoding encoding); 414 415 // A8.6.6 ADD (register) 416 bool 417 EmulateADDReg (ARMEncoding encoding); 418 419 // A8.6.97 MOV (register) 420 bool 421 EmulateMOVRdRm (ARMEncoding encoding); 422 423 // A8.6.96 MOV (immediate) 424 bool 425 EmulateMOVRdImm (ARMEncoding encoding); 426 427 // A8.6.35 CMP (immediate) 428 bool 429 EmulateCMPImm (ARMEncoding encoding); 430 431 // A8.6.36 CMP (register) 432 bool 433 EmulateCMPReg (ARMEncoding encoding); 434 435 // A8.6.14 ASR (immediate) 436 bool 437 EmulateASRImm (ARMEncoding encoding); 438 439 // A8.6.15 ASR (register) 440 bool 441 EmulateASRReg (ARMEncoding encoding); 442 443 // A8.6.88 LSL (immediate) 444 bool 445 EmulateLSLImm (ARMEncoding encoding); 446 447 // A8.6.89 LSL (register) 448 bool 449 EmulateLSLReg (ARMEncoding encoding); 450 451 // A8.6.90 LSR (immediate) 452 bool 453 EmulateLSRImm (ARMEncoding encoding); 454 455 // A8.6.91 LSR (register) 456 bool 457 EmulateLSRReg (ARMEncoding encoding); 458 459 // A8.6.139 ROR (immediate) 460 bool 461 EmulateRORImm (ARMEncoding encoding); 462 463 // A8.6.140 ROR (register) 464 bool 465 EmulateRORReg (ARMEncoding encoding); 466 467 // A8.6.141 RRX 468 bool 469 EmulateRRX (ARMEncoding encoding); 470 471 // Helper method for ASR, LSL, LSR, ROR (immediate), and RRX 472 bool 473 EmulateShiftImm (ARMEncoding encoding, ARM_ShifterType shift_type); 474 475 // Helper method for ASR, LSL, LSR, and ROR (register) 476 bool 477 EmulateShiftReg (ARMEncoding encoding, ARM_ShifterType shift_type); 478 479 // A8.6.53 LDM/LDMIA/LDMFD 480 bool 481 EmulateLDM (ARMEncoding encoding); 482 483 // A8.6.54 LDMDA/LDMFA 484 bool 485 EmulateLDMDA (ARMEncoding encoding); 486 487 // A8.6.55 LDMDB/LDMEA 488 bool 489 EmulateLDMDB (ARMEncoding encoding); 490 491 // A8.6.56 LDMIB/LDMED 492 bool 493 EmulateLDMIB (ARMEncoding encoding); 494 495 // A8.6.57 LDR (immediate, Thumb) -- Encoding T1 496 bool 497 EmulateLDRRtRnImm (ARMEncoding encoding); 498 499 // A8.6.188 STM/STMIA/STMEA 500 bool 501 EmulateSTM (ARMEncoding encoding); 502 503 // A8.6.189 STMDA/STMED 504 bool 505 EmulateSTMDA (ARMEncoding encoding); 506 507 // A8.6.190 STMDB/STMFD 508 bool 509 EmulateSTMDB (ARMEncoding encoding); 510 511 // A8.6.191 STMIB/STMFA 512 bool 513 EmulateSTMIB (ARMEncoding encoding); 514 515 // A8.6.192 STR (immediate, Thumb) 516 bool 517 EmulateSTRThumb(ARMEncoding encoding); 518 519 // A8.6.194 STR (register) 520 bool 521 EmulateSTRRegister (ARMEncoding encoding); 522 523 // A8.6.195 STRB (immediate, Thumb) 524 bool 525 EmulateSTRBThumb (ARMEncoding encoding); 526 527 // A8.6.207 STRH (register) 528 bool 529 EmulateSTRHRegister (ARMEncoding encoding); 530 531 // A8.6.1 ADC (immediate) 532 bool 533 EmulateADCImm (ARMEncoding encoding); 534 535 // A8.6.2 ADC (Register) 536 bool 537 EmulateADCReg (ARMEncoding encoding); 538 539 // A8.6.10 ADR 540 bool 541 EmulateADR (ARMEncoding encoding); 542 543 // A8.6.11 AND (immediate) 544 bool 545 EmulateANDImm (ARMEncoding encoding); 546 547 // A8.6.12 AND (register) 548 bool 549 EmulateANDReg (ARMEncoding encoding); 550 551 // A8.6.19 BIC (immediate) 552 bool 553 EmulateBICImm (ARMEncoding encoding); 554 555 // A8.6.20 BIC (register) 556 bool 557 EmulateBICReg (ARMEncoding encoding); 558 559 // A8.6.26 BXJ 560 bool 561 EmulateBXJ (ARMEncoding encoding); 562 563 // A8.6.32 CMN (immediate) 564 bool 565 EmulateCMNImm (ARMEncoding encoding); 566 567 // A8.6.33 CMN (register) 568 bool 569 EmulateCMNReg (ARMEncoding encoding); 570 571 // A8.6.44 EOR (immediate) 572 bool 573 EmulateEORImm (ARMEncoding encoding); 574 575 // A8.6.45 EOR (register) 576 bool 577 EmulateEORReg (ARMEncoding encoding); 578 579 // A8.6.58 LDR (immediate, ARM) - Encoding A1 580 bool 581 EmulateLDRImmediateARM (ARMEncoding encoding); 582 583 // A8.6.60 LDR (register) - Encoding T1, T2, A1 584 bool 585 EmulateLDRRegister (ARMEncoding encoding); 586 587 // A8.6.61 LDRB (immediate, Thumb) - Encoding T1, T2 588 bool 589 EmulateLDRBImmediate (ARMEncoding encoding); 590 591 // A8.6.63 LDRB (literal) - Encoding T1 592 bool 593 EmulateLDRBLiteral (ARMEncoding encoding); 594 595 // A8.6.64 LDRB (register) - Encoding T1 596 bool 597 EmulateLDRBRegister (ARMEncoding encoding); 598 599 // A8.6.73 LDRH (immediate, Thumb) - Encoding T1, T2 600 bool 601 EmulateLDRHImmediate (ARMEncoding encoding); 602 603 // A8.6.75 LDRH (literal) - Encoding T1 604 bool 605 EmulateLDRHLiteral (ARMEncoding encoding); 606 607 // A8.6.76 LDRH (register) - Encoding T1, T2 608 bool 609 EmulateLDRHRegister (ARMEncoding encoding); 610 611 // A8.6.78 LDRSB (immediate) - Encoding T1 612 bool 613 EmulateLDRSBImmediate (ARMEncoding encoding); 614 615 // A8.6.79 LDRSB (literal) - Encoding T1 616 bool 617 EmulateLDRSBLiteral (ARMEncoding encoding); 618 619 // A8.6.80 LDRSB (register) - Encoding T1, T2 620 bool 621 EmulateLDRSBRegister (ARMEncoding encoding); 622 623 // A8.6.82 LDRSH (immediate) - Encoding T1 624 bool 625 EmulateLDRSHImmediate (ARMEncoding encoding); 626 627 // A8.6.83 LDRSH (literal) - Encoding T1 628 bool 629 EmulateLDRSHLiteral (ARMEncoding encoding); 630 631 // A8.6.84 LDRSH (register) - Encoding T1, T2 632 bool 633 EmulateLDRSHRegister (ARMEncoding encoding); 634 635 // A8.6.105 MUL 636 bool 637 EmulateMUL (ARMEncoding encoding); 638 639 // A8.6.106 MVN (immediate) 640 bool 641 EmulateMVNImm (ARMEncoding encoding); 642 643 // A8.6.107 MVN (register) 644 bool 645 EmulateMVNReg (ARMEncoding encoding); 646 647 // A8.6.113 ORR (immediate) 648 bool 649 EmulateORRImm (ARMEncoding encoding); 650 651 // A8.6.114 ORR (register) 652 bool 653 EmulateORRReg (ARMEncoding encoding); 654 655 // A8.6.117 PLD (immediate, literal) - Encoding T1, T2, T3, A1 656 bool 657 EmulatePLDImmediate (ARMEncoding encoding); 658 659 // A8.6.119 PLI (immediate,literal) - Encoding T3, A1 660 bool 661 EmulatePLIImmediate (ARMEncoding encoding); 662 663 // A8.6.120 PLI (register) - Encoding T1, A1 664 bool 665 EmulatePLIRegister (ARMEncoding encoding); 666 667 // A8.6.141 RSB (immediate) 668 bool 669 EmulateRSBImm (ARMEncoding encoding); 670 671 // A8.6.142 RSB (register) 672 bool 673 EmulateRSBReg (ARMEncoding encoding); 674 675 // A8.6.144 RSC (immediate) 676 bool 677 EmulateRSCImm (ARMEncoding encoding); 678 679 // A8.6.145 RSC (register) 680 bool 681 EmulateRSCReg (ARMEncoding encoding); 682 683 // A8.6.150 SBC (immediate) 684 bool 685 EmulateSBCImm (ARMEncoding encoding); 686 687 // A8.6.151 SBC (register) 688 bool 689 EmulateSBCReg (ARMEncoding encoding); 690 691 // A8.6.211 SUB (immediate, Thumb) 692 bool 693 EmulateSUBImmThumb (ARMEncoding encoding); 694 695 // A8.6.212 SUB (immediate, ARM) 696 bool 697 EmulateSUBImmARM (ARMEncoding encoding); 698 699 // A8.6.222 SXTB - Encoding T1 700 bool 701 EmulateSXTB (ARMEncoding encoding); 702 703 // A8.6.224 SXTH - EncodingT1 704 bool 705 EmulateSXTH (ARMEncoding encoding); 706 707 // A8.6.227 TEQ (immediate) - Encoding A1 708 bool 709 EmulateTEQImm (ARMEncoding encoding); 710 711 // A8.6.228 TEQ (register) - Encoding A1 712 bool 713 EmulateTEQReg (ARMEncoding encoding); 714 715 // A8.6.230 TST (immediate) - Encoding A1 716 bool 717 EmulateTSTImm (ARMEncoding encoding); 718 719 // A8.6.231 TST (register) - Encoding T1, A1 720 bool 721 EmulateTSTReg (ARMEncoding encoding); 722 723 // A8.6.262 UXTB - Encoding T1 724 bool 725 EmulateUXTB (ARMEncoding encoding); 726 727 // A8.6.264 UXTH - Encoding T1 728 bool 729 EmulateUXTH (ARMEncoding encoding); 730 731 // B6.1.8 RFE 732 bool 733 EmulateRFE (ARMEncoding encoding); 734 735 uint32_t m_arm_isa; 736 Mode m_opcode_mode; 737 uint32_t m_opcode_cpsr; 738 uint32_t m_new_inst_cpsr; // This can get updated by the opcode. 739 ITSession m_it_session; 740}; 741 742} // namespace lldb_private 743 744#endif // lldb_EmulateInstructionARM_h_ 745