]>
git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
02f93feaabf2502f709116dd22ce026463338520
2 Default exception handler
4 Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/BaseLib.h>
18 #include <Library/PrintLib.h>
19 #include <Library/ArmDisassemblerLib.h>
21 CHAR8
*gCondition
[] = {
40 #define COND(_a) gCondition[((_a) >> 28)]
67 CHAR8
*gLdmStack
[] = {
74 #define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
77 #define SIGN(_U) ((_U) ? "" : "-")
78 #define WRITE(_W) ((_W) ? "!" : "")
79 #define BYTE(_B) ((_B) ? "B":"")
80 #define USER(_B) ((_B) ? "^" : "")
82 CHAR8 mMregListStr
[4*15 + 1];
89 UINTN Index
, Start
, End
;
95 AsciiStrCat (Str
, "{");
96 for (Index
= 0, First
= TRUE
; Index
<= 15; Index
++) {
97 if ((OpCode
& (1 << Index
)) != 0) {
99 for (Index
++; ((OpCode
& (1 << Index
)) != 0) && Index
<= 15; Index
++) {
104 AsciiStrCat (Str
, ",");
110 AsciiStrCat (Str
, gReg
[Start
]);
111 AsciiStrCat (Str
, ", ");
113 AsciiStrCat (Str
, gReg
[Start
]);
114 AsciiStrCat (Str
, "-");
115 AsciiStrCat (Str
, gReg
[End
]);
120 AsciiStrCat (Str
, "ERROR");
122 AsciiStrCat (Str
, "}");
124 // BugBug: Make caller pass in buffer it is cleaner
142 return (Op
>> Shift
) | (Op
<< (32 - Shift
));
147 Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
148 point to next instructin.
150 We cheat and only decode instructions that access
151 memory. If the instruction is not found we dump the instruction in hex.
153 @param OpCodePtr Pointer to pointer of ARM instruction to disassemble.
154 @param Buf Buffer to sprintf disassembly into.
155 @param Size Size of Buf in bytes.
156 @param Extended TRUE dump hex for instruction too.
160 DisassembleArmInstruction (
161 IN UINT32
**OpCodePtr
,
167 UINT32 OpCode
= **OpCodePtr
;
169 BOOLEAN I
, P
, U
, B
, W
, L
, S
, H
;
171 UINT32 imode
, offset_8
, offset_12
;
173 UINT32 shift_imm
, shift
;
175 I
= (OpCode
& BIT25
) == BIT25
;
176 P
= (OpCode
& BIT24
) == BIT24
;
177 U
= (OpCode
& BIT23
) == BIT23
;
178 B
= (OpCode
& BIT22
) == BIT22
; // Also called S
179 W
= (OpCode
& BIT21
) == BIT21
;
180 L
= (OpCode
& BIT20
) == BIT20
;
181 S
= (OpCode
& BIT6
) == BIT6
;
182 H
= (OpCode
& BIT5
) == BIT5
;
183 Rn
= (OpCode
>> 16) & 0xf;
184 Rd
= (OpCode
>> 12) & 0xf;
189 Index
= AsciiSPrint (Buf
, Size
, "0x%08x ", OpCode
);
195 if ((OpCode
& 0x0fe000f0) == 0x01800090) {
197 // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]
198 AsciiSPrint (Buf
, Size
, "LDREX%a %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
]);
200 // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
201 AsciiSPrint (Buf
, Size
, "STREX%a %a, %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
], gReg
[Rn
]);
207 if ((OpCode
& 0x0e000000) == 0x08000000) {
209 // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
210 // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
211 // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
212 AsciiSPrint (Buf
, Size
, "LDM%a%a, %a%a, %a", COND (OpCode
), LDM_EXT (Rn
,(OpCode
>> 23) & 3), gReg
[Rn
], WRITE (W
), MRegList (OpCode
), USER (B
));
214 // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
215 // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
216 AsciiSPrint (Buf
, Size
, "STM%a%a, %a%a, %a", COND (OpCode
), LDM_EXT (Rn
,(OpCode
>> 23) & 3), gReg
[Rn
], WRITE (W
), MRegList (OpCode
), USER (B
));
221 // LDR/STR Address Mode 2
222 if ( ((OpCode
& 0x0c000000) == 0x04000000) || ((OpCode
& 0xfd70f000 ) == 0xf550f000) ) {
223 offset_12
= OpCode
& 0xfff;
224 if ((OpCode
& 0xfd70f000 ) == 0xf550f000) {
225 Index
= AsciiSPrint (Buf
, Size
, "PLD");
227 Index
= AsciiSPrint (Buf
, Size
, "%a%a%a%a %a, ", L
? "LDR" : "STR", COND (OpCode
), BYTE (B
), (!(P
) && W
) ? "T":"", gReg
[Rd
]);
231 // A5.2.2 [<Rn>, #+/-<offset_12>]
232 // A5.2.5 [<Rn>, #+/-<offset_12>]
233 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x]%a", gReg
[Rn
], SIGN (U
), offset_12
, WRITE (W
));
234 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
235 // A5.2.3 [<Rn>, +/-<Rm>]
236 // A5.2.6 [<Rn>, +/-<Rm>]!
237 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a]%a", gReg
[Rn
], SIGN (U
), WRITE (W
));
239 // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
240 // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
241 shift_imm
= (OpCode
>> 7) & 0x1f;
242 shift
= (OpCode
>> 5) & 0x3;
245 } else if (shift
== 0x1) {
247 if (shift_imm
== 0) {
250 } else if (shift
== 0x12) {
252 } else if (shift_imm
== 0) {
253 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, RRX]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
259 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, #%d]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
, WRITE (W
));
263 // A5.2.8 [<Rn>], #+/-<offset_12>
264 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x", gReg
[Rn
], SIGN (U
), offset_12
);
265 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
266 // A5.2.9 [<Rn>], +/-<Rm>
267 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
269 // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
270 shift_imm
= (OpCode
>> 7) & 0x1f;
271 shift
= (OpCode
>> 5) & 0x3;
275 } else if (shift
== 0x1) {
277 if (shift_imm
== 0) {
280 } else if (shift
== 0x12) {
282 } else if (shift_imm
== 0) {
283 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, RRX", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
290 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, #%d", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
);
296 if ((OpCode
& 0x0e000000) == 0x00000000) {
297 // LDR/STR address mode 3
298 // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>
301 Root
= "LDR%aH %a, ";
303 Root
= "LDR%aSB %a, ";
305 Root
= "LDR%aSH %a, ";
317 Index
= AsciiSPrint (Buf
, Size
, Root
, COND (OpCode
), gReg
[Rd
]);
319 S
= (OpCode
& BIT6
) == BIT6
;
320 H
= (OpCode
& BIT5
) == BIT5
;
321 offset_8
= ((OpCode
>> 4) | (OpCode
* 0xf)) & 0xff;
323 // Immediate offset/index
325 // A5.3.2 [<Rn>, #+/-<offset_8>]
326 // A5.3.4 [<Rn>, #+/-<offset_8>]!
327 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%d]%a", gReg
[Rn
], SIGN (U
), offset_8
, WRITE (W
));
329 // A5.3.3 [<Rn>, +/-<Rm>]
330 // A5.3.5 [<Rn>, +/-<Rm>]!
331 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%]a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
334 // Register offset/index
336 // A5.3.6 [<Rn>], #+/-<offset_8>
337 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%d", gReg
[Rn
], SIGN (U
), offset_8
);
339 // A5.3.7 [<Rn>], +/-<Rm>
340 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
346 if ((OpCode
& 0x0fb000f0) == 0x01000050) {
347 // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
348 // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
349 AsciiSPrint (Buf
, Size
, "SWP%a%a %a, %a, [%a]", COND (OpCode
), BYTE (B
), gReg
[Rd
], gReg
[Rm
], gReg
[Rn
]);
353 if ((OpCode
& 0xfe5f0f00) == 0xf84d0500) {
354 // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}
355 AsciiSPrint (Buf
, Size
, "SRS%a #0x%x%a", gLdmStack
[(OpCode
>> 23) & 3], OpCode
& 0x1f, WRITE (W
));
359 if ((OpCode
& 0xfe500f00) == 0xf8100500) {
360 // A4.1.59 RFE<addressing_mode> <Rn>{!}
361 AsciiSPrint (Buf
, Size
, "RFE%a %a", gLdmStack
[(OpCode
>> 23) & 3], gReg
[Rn
], WRITE (W
));
365 if ((OpCode
& 0xfff000f0) == 0xe1200070) {
366 // A4.1.7 BKPT <immed_16>
367 AsciiSPrint (Buf
, Size
, "BKPT %x", ((OpCode
>> 8) | (OpCode
& 0xf)) & 0xffff);
371 if ((OpCode
& 0xfff10020) == 0xf1000000) {
372 // A4.1.16 CPS<effect> <iflags> {, #<mode>}
373 if (((OpCode
>> 6) & 0x7) == 0) {
374 AsciiSPrint (Buf
, Size
, "CPS #0x%x", (OpCode
& 0x2f));
376 imode
= (OpCode
>> 18) & 0x3;
377 Index
= AsciiSPrint (Buf
, Size
, "CPS%a %a%a%a", (imode
== 3) ? "ID":"IE", (OpCode
& BIT8
) ? "A":"", (OpCode
& BIT7
) ? "I":"", (OpCode
& BIT6
) ? "F":"");
378 if ((OpCode
& BIT17
) != 0) {
379 AsciiSPrint (&Buf
[Index
], Size
- Index
, ", #0x%x", OpCode
& 0x1f);
385 if ((OpCode
& 0x0f000000) == 0x0f000000) {
386 // A4.1.107 SWI{<cond>} <immed_24>
387 AsciiSPrint (Buf
, Size
, "SWI%a %x", COND (OpCode
), OpCode
& 0x00ffffff);
391 if ((OpCode
& 0x0fb00000) == 0x01000000) {
392 // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR
393 AsciiSPrint (Buf
, Size
, "MRS%a %a, %a", COND (OpCode
), gReg
[Rd
], B
? "SPSR" : "CPSR");
398 if ((OpCode
& 0x0db00000) == 0x03200000) {
399 // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
401 // MSR{<cond>} CPSR_<fields>, #<immediate>
402 AsciiSPrint (Buf
, Size
, "MRS%a %a_%a, #0x%x", COND (OpCode
), B
? "SPSR" : "CPSR", FieldMask ((OpCode
>> 16) & 0xf), RotateRight (OpCode
& 0xf, ((OpCode
>> 8) & 0xf) *2));
404 // MSR{<cond>} CPSR_<fields>, <Rm>
405 AsciiSPrint (Buf
, Size
, "MRS%a %a_%a, %a", COND (OpCode
), B
? "SPSR" : "CPSR", gReg
[Rd
]);
410 if ((OpCode
& 0xff000010) == 0xfe000000) {
411 // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
412 AsciiSPrint (Buf
, Size
, "CDP%a 0x%x, 0x%x, CR%d, CR%d, CR%d, 0x%x", COND (OpCode
), (OpCode
>> 8) & 0xf, (OpCode
>> 20) & 0xf, Rn
, Rd
, Rm
, (OpCode
>> 5) &0x7);
416 if ((OpCode
& 0x0e000000) == 0x0c000000) {
417 // A4.1.19 LDC and A4.1.96 SDC
418 if ((OpCode
& 0xf0000000) == 0xf0000000) {
419 Index
= AsciiSPrint (Buf
, Size
, "%a2 0x%x, CR%d, ", L
? "LDC":"SDC", (OpCode
>> 8) & 0xf, Rd
);
421 Index
= AsciiSPrint (Buf
, Size
, "%a%a 0x%x, CR%d, ", L
? "LDC":"SDC", COND (OpCode
), (OpCode
>> 8) & 0xf, Rd
);
426 // A5.5.5.5 [<Rn>], <option>
427 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], {0x%x}", gReg
[Rn
], OpCode
& 0xff);
429 // A.5.5.4 [<Rn>], #+/-<offset_8>*4
430 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x*4", gReg
[Rn
], SIGN (U
), OpCode
& 0xff);
433 // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
434 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x*4]%a", gReg
[Rn
], SIGN (U
), OpCode
& 0xff, WRITE (W
));
439 if ((OpCode
& 0x0f000010) == 0x0e000010) {
440 // A4.1.32 MRC2, MCR2
441 AsciiSPrint (Buf
, Size
, "%a%a 0x%x, 0x%x, %a, CR%d, CR%d, 0x%x", L
? "MRC":"MCR", COND (OpCode
), (OpCode
>> 8) & 0xf, (OpCode
>> 20) & 0xf, gReg
[Rd
], Rn
, Rm
, (OpCode
>> 5) &0x7);
445 if ((OpCode
& 0x0ff00000) == 0x0c400000) {
446 // A4.1.33 MRRC2, MCRR2
447 AsciiSPrint (Buf
, Size
, "%a%a 0x%x, 0x%x, %a, %a, CR%d", L
? "MRRC":"MCRR", COND (OpCode
), (OpCode
>> 4) & 0xf, (OpCode
>> 20) & 0xf, gReg
[Rd
], gReg
[Rn
], Rm
);
451 AsciiSPrint (Buf
, Size
, "Faulting OpCode 0x%08x", OpCode
);