]>
git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c
2 Default exception handler
4 Copyright (c) 2008-2010, Apple Inc. All rights reserved.
6 All rights reserved. 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/UefiLib.h>
19 #include <Library/PrintLib.h>
22 CHAR8
*gCondition
[] = {
41 #define COND(_a) gCondition[(_a) >> 28]
69 CHAR8
*gLdmStack
[] = {
76 #define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
79 #define SIGN(_U) ((_U) ? "" : "-")
80 #define WRITE(_W) ((_W) ? "!" : "")
81 #define BYTE(_B) ((_B) ? "B":"")
82 #define USER(_B) ((_B) ? "^" : "")
84 CHAR8 mMregListStr
[4*15 + 1];
91 UINTN Index
, Start
, End
;
97 AsciiStrCat (Str
, "{");
98 for (Index
= 0, First
= TRUE
; Index
<= 15; Index
++) {
99 if ((OpCode
& (1 << Index
)) != 0) {
101 for (Index
++; ((OpCode
& (1 << Index
)) != 0) && Index
<= 15; Index
++) {
106 AsciiStrCat (Str
, ",");
112 AsciiStrCat (Str
, gReg
[Start
]);
113 AsciiStrCat (Str
, ", ");
115 AsciiStrCat (Str
, gReg
[Start
]);
116 AsciiStrCat (Str
, "-");
117 AsciiStrCat (Str
, gReg
[End
]);
122 AsciiStrCat (Str
, "ERROR");
124 AsciiStrCat (Str
, "}");
126 // BugBug: Make caller pass in buffer it is cleaner
144 return (Op
>> Shift
) | (Op
<< (32 - Shift
));
149 DEBUG print the faulting instruction. We cheat and only decode instructions that access
150 memory. If the instruction is not found we dump the instruction in hex.
152 @param Insturction ARM instruction to disassemble.
156 DisassembleArmInstruction (
157 IN UINT32
*OpCodePtr
,
162 UINT32 OpCode
= *OpCodePtr
;
164 BOOLEAN I
, P
, U
, B
, W
, L
, S
, H
;
166 UINT32 imode
, offset_8
, offset_12
;
168 UINT32 shift_imm
, shift
;
170 I
= (OpCode
& BIT25
) == BIT25
;
171 P
= (OpCode
& BIT24
) == BIT24
;
172 U
= (OpCode
& BIT23
) == BIT23
;
173 B
= (OpCode
& BIT22
) == BIT22
; // Also called S
174 W
= (OpCode
& BIT21
) == BIT21
;
175 L
= (OpCode
& BIT20
) == BIT20
;
176 S
= (OpCode
& BIT6
) == BIT6
;
177 H
= (OpCode
& BIT5
) == BIT5
;
178 Rn
= (OpCode
>> 16) & 0xf;
179 Rd
= (OpCode
>> 12) & 0xf;
183 if ((OpCode
& 0x0fe000f0) == 0x01800090) {
185 // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]
186 AsciiSPrint (Buf
, Size
, "LDREX%a %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
]);
188 // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
189 AsciiSPrint (Buf
, Size
, "STREX%a %a, %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
], gReg
[Rn
]);
195 if ((OpCode
& 0x0e000000) == 0x08000000) {
197 // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
198 // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
199 // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
200 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
));
202 // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
203 // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
204 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
));
209 // LDR/STR Address Mode 2
210 if ( ((OpCode
& 0x0c000000) == 0x04000000) || ((OpCode
& 0xfd70f000 ) == 0xf550f000) ) {
211 offset_12
= OpCode
& 0xfff;
212 if ((OpCode
& 0xfd70f000 ) == 0xf550f000) {
213 Index
= AsciiSPrint (Buf
, Size
, "PLD");
215 Index
= AsciiSPrint (Buf
, Size
, "%a%a%a%a %a, ", L
? "LDR" : "STR", COND (OpCode
), BYTE (B
), (!P
& W
) ? "T":"", gReg
[Rd
]);
219 // A5.2.2 [<Rn>, #+/-<offset_12>]
220 // A5.2.5 [<Rn>, #+/-<offset_12>]
221 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x]%a", gReg
[Rn
], SIGN (U
), offset_12
, WRITE (W
));
222 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
223 // A5.2.3 [<Rn>, +/-<Rm>]
224 // A5.2.6 [<Rn>, +/-<Rm>]!
225 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a]%a", gReg
[Rn
], SIGN (U
), WRITE (W
));
227 // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
228 // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
229 shift_imm
= (OpCode
>> 7) & 0x1f;
230 shift
= (OpCode
>> 5) & 0x3;
233 } else if (shift
== 0x1) {
235 if (shift_imm
== 0) {
238 } else if (shift
== 0x12) {
240 } else if (shift_imm
== 0) {
241 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, RRX]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
247 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, #%d]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
, WRITE (W
));
251 // A5.2.8 [<Rn>], #+/-<offset_12>
252 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x", gReg
[Rn
], SIGN (U
), offset_12
);
253 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
254 // A5.2.9 [<Rn>], +/-<Rm>
255 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
257 // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
258 shift_imm
= (OpCode
>> 7) & 0x1f;
259 shift
= (OpCode
>> 5) & 0x3;
263 } else if (shift
== 0x1) {
265 if (shift_imm
== 0) {
268 } else if (shift
== 0x12) {
270 } else if (shift_imm
== 0) {
271 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, RRX", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
278 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, #%d", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
);
284 if ((OpCode
& 0x0e000000) == 0x00000000) {
285 // LDR/STR address mode 3
286 // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>
289 Root
= "LDR%aH %a, ";
291 Root
= "LDR%aSB %a, ";
293 Root
= "LDR%aSH %a, ";
305 Index
= AsciiSPrint (Buf
, Size
, Root
, COND (OpCode
), gReg
[Rd
]);
307 S
= (OpCode
& BIT6
) == BIT6
;
308 H
= (OpCode
& BIT5
) == BIT5
;
309 offset_8
= ((OpCode
>> 4) | (OpCode
* 0xf)) & 0xff;
311 // Immediate offset/index
313 // A5.3.2 [<Rn>, #+/-<offset_8>]
314 // A5.3.4 [<Rn>, #+/-<offset_8>]!
315 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%d]%a", gReg
[Rn
], SIGN (U
), offset_8
, WRITE (W
));
317 // A5.3.3 [<Rn>, +/-<Rm>]
318 // A5.3.5 [<Rn>, +/-<Rm>]!
319 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%]a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
322 // Register offset/index
324 // A5.3.6 [<Rn>], #+/-<offset_8>
325 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%d", gReg
[Rn
], SIGN (U
), offset_8
);
327 // A5.3.7 [<Rn>], +/-<Rm>
328 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
334 if ((OpCode
& 0x0fb000f0) == 0x01000050) {
335 // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
336 // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
337 AsciiSPrint (Buf
, Size
, "SWP%a%a %a, %a, [%a]", COND (OpCode
), BYTE (B
), gReg
[Rd
], gReg
[Rm
], gReg
[Rn
]);
341 if ((OpCode
& 0xfe5f0f00) == 0xf84d0500) {
342 // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}
343 AsciiSPrint (Buf
, Size
, "SRS%a #0x%x%a", gLdmStack
[(OpCode
>> 23) & 3], OpCode
& 0x1f, WRITE (W
));
347 if ((OpCode
& 0xfe500f00) == 0xf8100500) {
348 // A4.1.59 RFE<addressing_mode> <Rn>{!}
349 AsciiSPrint (Buf
, Size
, "RFE%a %a", gLdmStack
[(OpCode
>> 23) & 3], gReg
[Rn
], WRITE (W
));
353 if ((OpCode
& 0xfff000f0) == 0xe1200070) {
354 // A4.1.7 BKPT <immed_16>
355 AsciiSPrint (Buf
, Size
, "BKPT %x", ((OpCode
>> 8) | (OpCode
& 0xf)) & 0xffff);
359 if ((OpCode
& 0xfff10020) == 0xf1000000) {
360 // A4.1.16 CPS<effect> <iflags> {, #<mode>}
361 if (((OpCode
>> 6) & 0x7) == 0) {
362 AsciiSPrint (Buf
, Size
, "CPS #0x%x", (OpCode
& 0x2f));
364 imode
= (OpCode
>> 18) & 0x3;
365 Index
= AsciiSPrint (Buf
, Size
, "CPS%a %a%a%a", (imode
== 3) ? "ID":"IE", (OpCode
& BIT8
) ? "A":"", (OpCode
& BIT7
) ? "I":"", (OpCode
& BIT6
) ? "F":"");
366 if ((OpCode
& BIT17
) != 0) {
367 AsciiSPrint (&Buf
[Index
], Size
- Index
, ", #0x%x", OpCode
& 0x1f);
373 if ((OpCode
& 0x0f000000) == 0x0f000000) {
374 // A4.1.107 SWI{<cond>} <immed_24>
375 AsciiSPrint (Buf
, Size
, "SWI%a %x", COND (OpCode
), OpCode
& 0x00ffffff);
379 if ((OpCode
& 0x0fb00000) == 0x01000000) {
380 // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR
381 AsciiSPrint (Buf
, Size
, "MRS%a %a, %a", COND (OpCode
), gReg
[Rd
], B
? "SPSR" : "CPSR");
386 if ((OpCode
& 0x0db00000) == 0x03200000) {
387 // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
389 // MSR{<cond>} CPSR_<fields>, #<immediate>
390 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));
392 // MSR{<cond>} CPSR_<fields>, <Rm>
393 AsciiSPrint (Buf
, Size
, "MRS%a %a_%a, %a", COND (OpCode
), B
? "SPSR" : "CPSR", gReg
[Rd
]);
398 if ((OpCode
& 0xff000010) == 0xfe000000) {
399 // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
400 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);
404 if ((OpCode
& 0x0e000000) == 0x0c000000) {
405 // A4.1.19 LDC and A4.1.96 SDC
406 if ((OpCode
& 0xf0000000) == 0xf0000000) {
407 Index
= AsciiSPrint (Buf
, Size
, "%a2 0x%x, CR%d, ", L
? "LDC":"SDC", (OpCode
>> 8) & 0xf, Rd
);
409 Index
= AsciiSPrint (Buf
, Size
, "%a%a 0x%x, CR%d, ", L
? "LDC":"SDC", COND (OpCode
), (OpCode
>> 8) & 0xf, Rd
);
414 // A5.5.5.5 [<Rn>], <option>
415 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], {0x%x}", gReg
[Rn
], OpCode
& 0xff);
417 // A.5.5.4 [<Rn>], #+/-<offset_8>*4
418 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x*4", gReg
[Rn
], SIGN (U
), OpCode
& 0xff);
421 // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
422 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x*4]%a", gReg
[Rn
], SIGN (U
), OpCode
& 0xff, WRITE (W
));
427 if ((OpCode
& 0x0f000010) == 0x0e000010) {
428 // A4.1.32 MRC2, MCR2
429 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);
433 if ((OpCode
& 0x0ff00000) == 0x0c400000) {
434 // A4.1.33 MRRC2, MCRR2
435 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
);
439 AsciiSPrint (Buf
, Size
, "Faulting OpCode 0x%08x", OpCode
);