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