EmulateInstructionARM.h revision 30fec12a2c2f0fe75c78e9b9f791bc53cd92cdfd
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    EmulateLDRBRegister (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