]>
git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
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)]
68 CHAR8
*gLdmStack
[] = {
75 #define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
78 #define SIGN(_U) ((_U) ? "" : "-")
79 #define WRITE(_W) ((_W) ? "!" : "")
80 #define BYTE(_B) ((_B) ? "B":"")
81 #define USER(_B) ((_B) ? "^" : "")
83 CHAR8 mMregListStr
[4*15 + 1];
90 UINTN Index
, Start
, End
;
96 AsciiStrCat (Str
, "{");
97 for (Index
= 0, First
= TRUE
; Index
<= 15; Index
++) {
98 if ((OpCode
& (1 << Index
)) != 0) {
100 for (Index
++; ((OpCode
& (1 << Index
)) != 0) && Index
<= 15; Index
++) {
105 AsciiStrCat (Str
, ",");
111 AsciiStrCat (Str
, gReg
[Start
]);
112 AsciiStrCat (Str
, ", ");
114 AsciiStrCat (Str
, gReg
[Start
]);
115 AsciiStrCat (Str
, "-");
116 AsciiStrCat (Str
, gReg
[End
]);
121 AsciiStrCat (Str
, "ERROR");
123 AsciiStrCat (Str
, "}");
125 // BugBug: Make caller pass in buffer it is cleaner
143 return (Op
>> Shift
) | (Op
<< (32 - Shift
));
148 Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
149 point to next instructin.
151 We cheat and only decode instructions that access
152 memory. If the instruction is not found we dump the instruction in hex.
154 @param OpCodePtr Pointer to pointer of ARM instruction to disassemble.
155 @param Buf Buffer to sprintf disassembly into.
156 @param Size Size of Buf in bytes.
157 @param Extended TRUE dump hex for instruction too.
161 DisassembleArmInstruction (
162 IN UINT32
**OpCodePtr
,
168 UINT32 OpCode
= **OpCodePtr
;
170 BOOLEAN I
, P
, U
, B
, W
, L
, S
, H
;
172 UINT32 imode
, offset_8
, offset_12
;
174 UINT32 shift_imm
, shift
;
176 I
= (OpCode
& BIT25
) == BIT25
;
177 P
= (OpCode
& BIT24
) == BIT24
;
178 U
= (OpCode
& BIT23
) == BIT23
;
179 B
= (OpCode
& BIT22
) == BIT22
; // Also called S
180 W
= (OpCode
& BIT21
) == BIT21
;
181 L
= (OpCode
& BIT20
) == BIT20
;
182 S
= (OpCode
& BIT6
) == BIT6
;
183 H
= (OpCode
& BIT5
) == BIT5
;
184 Rn
= (OpCode
>> 16) & 0xf;
185 Rd
= (OpCode
>> 12) & 0xf;
190 Index
= AsciiSPrint (Buf
, Size
, "0x%08x ", OpCode
);
196 if ((OpCode
& 0x0fe000f0) == 0x01800090) {
198 // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]
199 AsciiSPrint (Buf
, Size
, "LDREX%a %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
]);
201 // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
202 AsciiSPrint (Buf
, Size
, "STREX%a %a, %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
], gReg
[Rn
]);
208 if ((OpCode
& 0x0e000000) == 0x08000000) {
210 // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
211 // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
212 // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
213 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
));
215 // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
216 // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
217 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
));
222 // LDR/STR Address Mode 2
223 if ( ((OpCode
& 0x0c000000) == 0x04000000) || ((OpCode
& 0xfd70f000 ) == 0xf550f000) ) {
224 offset_12
= OpCode
& 0xfff;
225 if ((OpCode
& 0xfd70f000 ) == 0xf550f000) {
226 Index
= AsciiSPrint (Buf
, Size
, "PLD");
228 Index
= AsciiSPrint (Buf
, Size
, "%a%a%a%a %a, ", L
? "LDR" : "STR", COND (OpCode
), BYTE (B
), (!(P
) && W
) ? "T":"", gReg
[Rd
]);
232 // A5.2.2 [<Rn>, #+/-<offset_12>]
233 // A5.2.5 [<Rn>, #+/-<offset_12>]
234 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x]%a", gReg
[Rn
], SIGN (U
), offset_12
, WRITE (W
));
235 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
236 // A5.2.3 [<Rn>, +/-<Rm>]
237 // A5.2.6 [<Rn>, +/-<Rm>]!
238 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a]%a", gReg
[Rn
], SIGN (U
), WRITE (W
));
240 // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
241 // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
242 shift_imm
= (OpCode
>> 7) & 0x1f;
243 shift
= (OpCode
>> 5) & 0x3;
246 } else if (shift
== 0x1) {
248 if (shift_imm
== 0) {
251 } else if (shift
== 0x12) {
253 } else if (shift_imm
== 0) {
254 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, RRX]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
260 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, #%d]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
, WRITE (W
));
264 // A5.2.8 [<Rn>], #+/-<offset_12>
265 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x", gReg
[Rn
], SIGN (U
), offset_12
);
266 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
267 // A5.2.9 [<Rn>], +/-<Rm>
268 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
270 // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
271 shift_imm
= (OpCode
>> 7) & 0x1f;
272 shift
= (OpCode
>> 5) & 0x3;
276 } else if (shift
== 0x1) {
278 if (shift_imm
== 0) {
281 } else if (shift
== 0x12) {
283 } else if (shift_imm
== 0) {
284 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, RRX", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
291 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, #%d", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
);
297 if ((OpCode
& 0x0e000000) == 0x00000000) {
298 // LDR/STR address mode 3
299 // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>
302 Root
= "LDR%aH %a, ";
304 Root
= "LDR%aSB %a, ";
306 Root
= "LDR%aSH %a, ";
318 Index
= AsciiSPrint (Buf
, Size
, Root
, COND (OpCode
), gReg
[Rd
]);
320 S
= (OpCode
& BIT6
) == BIT6
;
321 H
= (OpCode
& BIT5
) == BIT5
;
322 offset_8
= ((OpCode
>> 4) | (OpCode
* 0xf)) & 0xff;
324 // Immediate offset/index
326 // A5.3.2 [<Rn>, #+/-<offset_8>]
327 // A5.3.4 [<Rn>, #+/-<offset_8>]!
328 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%d]%a", gReg
[Rn
], SIGN (U
), offset_8
, WRITE (W
));
330 // A5.3.3 [<Rn>, +/-<Rm>]
331 // A5.3.5 [<Rn>, +/-<Rm>]!
332 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%]a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
335 // Register offset/index
337 // A5.3.6 [<Rn>], #+/-<offset_8>
338 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%d", gReg
[Rn
], SIGN (U
), offset_8
);
340 // A5.3.7 [<Rn>], +/-<Rm>
341 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
347 if ((OpCode
& 0x0fb000f0) == 0x01000050) {
348 // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
349 // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
350 AsciiSPrint (Buf
, Size
, "SWP%a%a %a, %a, [%a]", COND (OpCode
), BYTE (B
), gReg
[Rd
], gReg
[Rm
], gReg
[Rn
]);
354 if ((OpCode
& 0xfe5f0f00) == 0xf84d0500) {
355 // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}
356 AsciiSPrint (Buf
, Size
, "SRS%a #0x%x%a", gLdmStack
[(OpCode
>> 23) & 3], OpCode
& 0x1f, WRITE (W
));
360 if ((OpCode
& 0xfe500f00) == 0xf8100500) {
361 // A4.1.59 RFE<addressing_mode> <Rn>{!}
362 AsciiSPrint (Buf
, Size
, "RFE%a %a", gLdmStack
[(OpCode
>> 23) & 3], gReg
[Rn
], WRITE (W
));
366 if ((OpCode
& 0xfff000f0) == 0xe1200070) {
367 // A4.1.7 BKPT <immed_16>
368 AsciiSPrint (Buf
, Size
, "BKPT %x", ((OpCode
>> 8) | (OpCode
& 0xf)) & 0xffff);
372 if ((OpCode
& 0xfff10020) == 0xf1000000) {
373 // A4.1.16 CPS<effect> <iflags> {, #<mode>}
374 if (((OpCode
>> 6) & 0x7) == 0) {
375 AsciiSPrint (Buf
, Size
, "CPS #0x%x", (OpCode
& 0x2f));
377 imode
= (OpCode
>> 18) & 0x3;
378 Index
= AsciiSPrint (Buf
, Size
, "CPS%a %a%a%a", (imode
== 3) ? "ID":"IE", (OpCode
& BIT8
) ? "A":"", (OpCode
& BIT7
) ? "I":"", (OpCode
& BIT6
) ? "F":"");
379 if ((OpCode
& BIT17
) != 0) {
380 AsciiSPrint (&Buf
[Index
], Size
- Index
, ", #0x%x", OpCode
& 0x1f);
386 if ((OpCode
& 0x0f000000) == 0x0f000000) {
387 // A4.1.107 SWI{<cond>} <immed_24>
388 AsciiSPrint (Buf
, Size
, "SWI%a %x", COND (OpCode
), OpCode
& 0x00ffffff);
392 if ((OpCode
& 0x0fb00000) == 0x01000000) {
393 // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR
394 AsciiSPrint (Buf
, Size
, "MRS%a %a, %a", COND (OpCode
), gReg
[Rd
], B
? "SPSR" : "CPSR");
399 if ((OpCode
& 0x0db00000) == 0x03200000) {
400 // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
402 // MSR{<cond>} CPSR_<fields>, #<immediate>
403 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));
405 // MSR{<cond>} CPSR_<fields>, <Rm>
406 AsciiSPrint (Buf
, Size
, "MRS%a %a_%a, %a", COND (OpCode
), B
? "SPSR" : "CPSR", gReg
[Rd
]);
411 if ((OpCode
& 0xff000010) == 0xfe000000) {
412 // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
413 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);
417 if ((OpCode
& 0x0e000000) == 0x0c000000) {
418 // A4.1.19 LDC and A4.1.96 SDC
419 if ((OpCode
& 0xf0000000) == 0xf0000000) {
420 Index
= AsciiSPrint (Buf
, Size
, "%a2 0x%x, CR%d, ", L
? "LDC":"SDC", (OpCode
>> 8) & 0xf, Rd
);
422 Index
= AsciiSPrint (Buf
, Size
, "%a%a 0x%x, CR%d, ", L
? "LDC":"SDC", COND (OpCode
), (OpCode
>> 8) & 0xf, Rd
);
427 // A5.5.5.5 [<Rn>], <option>
428 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], {0x%x}", gReg
[Rn
], OpCode
& 0xff);
430 // A.5.5.4 [<Rn>], #+/-<offset_8>*4
431 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x*4", gReg
[Rn
], SIGN (U
), OpCode
& 0xff);
434 // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
435 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x*4]%a", gReg
[Rn
], SIGN (U
), OpCode
& 0xff, WRITE (W
));
440 if ((OpCode
& 0x0f000010) == 0x0e000010) {
441 // A4.1.32 MRC2, MCR2
442 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);
446 if ((OpCode
& 0x0ff00000) == 0x0c400000) {
447 // A4.1.33 MRRC2, MCRR2
448 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
);
452 AsciiSPrint (Buf
, Size
, "Faulting OpCode 0x%08x", OpCode
);