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