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