]>
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 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/BaseLib.h>
12 #include <Library/PrintLib.h>
13 #include <Library/ArmDisassemblerLib.h>
15 CHAR8
*gCondition
[] = {
34 #define COND(_a) gCondition[((_a) >> 28)]
62 CHAR8
*gLdmStack
[] = {
69 #define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
72 #define SIGN(_U) ((_U) ? "" : "-")
73 #define WRITE(_W) ((_W) ? "!" : "")
74 #define BYTE(_B) ((_B) ? "B":"")
75 #define USER(_B) ((_B) ? "^" : "")
77 CHAR8 mMregListStr
[4*15 + 1];
84 UINTN Index
, Start
, End
;
87 mMregListStr
[0] = '\0';
88 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, "{");
89 for (Index
= 0, First
= TRUE
; Index
<= 15; Index
++) {
90 if ((OpCode
& (1 << Index
)) != 0) {
92 for (Index
++; ((OpCode
& (1 << Index
)) != 0) && Index
<= 15; Index
++) {
97 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, ",");
103 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, gReg
[Start
]);
104 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, ", ");
106 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, gReg
[Start
]);
107 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, "-");
108 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, gReg
[End
]);
113 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, "ERROR");
115 AsciiStrCatS (mMregListStr
, sizeof mMregListStr
, "}");
117 // BugBug: Make caller pass in buffer it is cleaner
135 return (Op
>> Shift
) | (Op
<< (32 - Shift
));
140 Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
141 point to next instructin.
143 We cheat and only decode instructions that access
144 memory. If the instruction is not found we dump the instruction in hex.
146 @param OpCodePtr Pointer to pointer of ARM instruction to disassemble.
147 @param Buf Buffer to sprintf disassembly into.
148 @param Size Size of Buf in bytes.
149 @param Extended TRUE dump hex for instruction too.
153 DisassembleArmInstruction (
154 IN UINT32
**OpCodePtr
,
160 UINT32 OpCode
= **OpCodePtr
;
162 BOOLEAN I
, P
, U
, B
, W
, L
, S
, H
;
164 UINT32 imode
, offset_8
, offset_12
;
166 UINT32 shift_imm
, shift
;
168 I
= (OpCode
& BIT25
) == BIT25
;
169 P
= (OpCode
& BIT24
) == BIT24
;
170 U
= (OpCode
& BIT23
) == BIT23
;
171 B
= (OpCode
& BIT22
) == BIT22
; // Also called S
172 W
= (OpCode
& BIT21
) == BIT21
;
173 L
= (OpCode
& BIT20
) == BIT20
;
174 S
= (OpCode
& BIT6
) == BIT6
;
175 H
= (OpCode
& BIT5
) == BIT5
;
176 Rn
= (OpCode
>> 16) & 0xf;
177 Rd
= (OpCode
>> 12) & 0xf;
182 Index
= AsciiSPrint (Buf
, Size
, "0x%08x ", OpCode
);
188 if ((OpCode
& 0x0fe000f0) == 0x01800090) {
190 // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]
191 AsciiSPrint (Buf
, Size
, "LDREX%a %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
]);
193 // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
194 AsciiSPrint (Buf
, Size
, "STREX%a %a, %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
], gReg
[Rn
]);
200 if ((OpCode
& 0x0e000000) == 0x08000000) {
202 // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
203 // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
204 // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
205 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
));
207 // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
208 // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
209 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
));
214 // LDR/STR Address Mode 2
215 if ( ((OpCode
& 0x0c000000) == 0x04000000) || ((OpCode
& 0xfd70f000 ) == 0xf550f000) ) {
216 offset_12
= OpCode
& 0xfff;
217 if ((OpCode
& 0xfd70f000 ) == 0xf550f000) {
218 Index
= AsciiSPrint (Buf
, Size
, "PLD");
220 Index
= AsciiSPrint (Buf
, Size
, "%a%a%a%a %a, ", L
? "LDR" : "STR", COND (OpCode
), BYTE (B
), (!(P
) && W
) ? "T":"", gReg
[Rd
]);
224 // A5.2.2 [<Rn>, #+/-<offset_12>]
225 // A5.2.5 [<Rn>, #+/-<offset_12>]
226 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x]%a", gReg
[Rn
], SIGN (U
), offset_12
, WRITE (W
));
227 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
228 // A5.2.3 [<Rn>, +/-<Rm>]
229 // A5.2.6 [<Rn>, +/-<Rm>]!
230 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a]%a", gReg
[Rn
], SIGN (U
), WRITE (W
));
232 // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
233 // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
234 shift_imm
= (OpCode
>> 7) & 0x1f;
235 shift
= (OpCode
>> 5) & 0x3;
238 } else if (shift
== 0x1) {
240 if (shift_imm
== 0) {
243 } else if (shift
== 0x12) {
245 } else if (shift_imm
== 0) {
246 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, RRX]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
252 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, #%d]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
, WRITE (W
));
256 // A5.2.8 [<Rn>], #+/-<offset_12>
257 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x", gReg
[Rn
], SIGN (U
), offset_12
);
258 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
259 // A5.2.9 [<Rn>], +/-<Rm>
260 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
262 // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
263 shift_imm
= (OpCode
>> 7) & 0x1f;
264 shift
= (OpCode
>> 5) & 0x3;
268 } else if (shift
== 0x1) {
270 if (shift_imm
== 0) {
273 } else if (shift
== 0x12) {
275 } else if (shift_imm
== 0) {
276 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, RRX", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
283 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, #%d", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
);
289 if ((OpCode
& 0x0e000000) == 0x00000000) {
290 // LDR/STR address mode 3
291 // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>
294 Root
= "LDR%aH %a, ";
296 Root
= "LDR%aSB %a, ";
298 Root
= "LDR%aSH %a, ";
310 Index
= AsciiSPrint (Buf
, Size
, Root
, COND (OpCode
), gReg
[Rd
]);
312 S
= (OpCode
& BIT6
) == BIT6
;
313 H
= (OpCode
& BIT5
) == BIT5
;
314 offset_8
= ((OpCode
>> 4) | (OpCode
* 0xf)) & 0xff;
316 // Immediate offset/index
318 // A5.3.2 [<Rn>, #+/-<offset_8>]
319 // A5.3.4 [<Rn>, #+/-<offset_8>]!
320 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%d]%a", gReg
[Rn
], SIGN (U
), offset_8
, WRITE (W
));
322 // A5.3.3 [<Rn>, +/-<Rm>]
323 // A5.3.5 [<Rn>, +/-<Rm>]!
324 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%]a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
327 // Register offset/index
329 // A5.3.6 [<Rn>], #+/-<offset_8>
330 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%d", gReg
[Rn
], SIGN (U
), offset_8
);
332 // A5.3.7 [<Rn>], +/-<Rm>
333 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
339 if ((OpCode
& 0x0fb000f0) == 0x01000050) {
340 // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
341 // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
342 AsciiSPrint (Buf
, Size
, "SWP%a%a %a, %a, [%a]", COND (OpCode
), BYTE (B
), gReg
[Rd
], gReg
[Rm
], gReg
[Rn
]);
346 if ((OpCode
& 0xfe5f0f00) == 0xf84d0500) {
347 // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}
348 AsciiSPrint (Buf
, Size
, "SRS%a #0x%x%a", gLdmStack
[(OpCode
>> 23) & 3], OpCode
& 0x1f, WRITE (W
));
352 if ((OpCode
& 0xfe500f00) == 0xf8100500) {
353 // A4.1.59 RFE<addressing_mode> <Rn>{!}
354 AsciiSPrint (Buf
, Size
, "RFE%a %a", gLdmStack
[(OpCode
>> 23) & 3], gReg
[Rn
], WRITE (W
));
358 if ((OpCode
& 0xfff000f0) == 0xe1200070) {
359 // A4.1.7 BKPT <immed_16>
360 AsciiSPrint (Buf
, Size
, "BKPT %x", ((OpCode
>> 8) | (OpCode
& 0xf)) & 0xffff);
364 if ((OpCode
& 0xfff10020) == 0xf1000000) {
365 // A4.1.16 CPS<effect> <iflags> {, #<mode>}
366 if (((OpCode
>> 6) & 0x7) == 0) {
367 AsciiSPrint (Buf
, Size
, "CPS #0x%x", (OpCode
& 0x2f));
369 imode
= (OpCode
>> 18) & 0x3;
370 Index
= AsciiSPrint (Buf
, Size
, "CPS%a %a%a%a", (imode
== 3) ? "ID":"IE", (OpCode
& BIT8
) ? "A":"", (OpCode
& BIT7
) ? "I":"", (OpCode
& BIT6
) ? "F":"");
371 if ((OpCode
& BIT17
) != 0) {
372 AsciiSPrint (&Buf
[Index
], Size
- Index
, ", #0x%x", OpCode
& 0x1f);
378 if ((OpCode
& 0x0f000000) == 0x0f000000) {
379 // A4.1.107 SWI{<cond>} <immed_24>
380 AsciiSPrint (Buf
, Size
, "SWI%a %x", COND (OpCode
), OpCode
& 0x00ffffff);
384 if ((OpCode
& 0x0fb00000) == 0x01000000) {
385 // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR
386 AsciiSPrint (Buf
, Size
, "MRS%a %a, %a", COND (OpCode
), gReg
[Rd
], B
? "SPSR" : "CPSR");
391 if ((OpCode
& 0x0db00000) == 0x01200000) {
392 // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
394 // MSR{<cond>} CPSR_<fields>, #<immediate>
395 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));
397 // MSR{<cond>} CPSR_<fields>, <Rm>
398 AsciiSPrint (Buf
, Size
, "MRS%a %a_%a, %a", COND (OpCode
), B
? "SPSR" : "CPSR", gReg
[Rd
]);
403 if ((OpCode
& 0xff000010) == 0xfe000000) {
404 // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
405 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);
409 if ((OpCode
& 0x0e000000) == 0x0c000000) {
410 // A4.1.19 LDC and A4.1.96 SDC
411 if ((OpCode
& 0xf0000000) == 0xf0000000) {
412 Index
= AsciiSPrint (Buf
, Size
, "%a2 0x%x, CR%d, ", L
? "LDC":"SDC", (OpCode
>> 8) & 0xf, Rd
);
414 Index
= AsciiSPrint (Buf
, Size
, "%a%a 0x%x, CR%d, ", L
? "LDC":"SDC", COND (OpCode
), (OpCode
>> 8) & 0xf, Rd
);
419 // A5.5.5.5 [<Rn>], <option>
420 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], {0x%x}", gReg
[Rn
], OpCode
& 0xff);
422 // A.5.5.4 [<Rn>], #+/-<offset_8>*4
423 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x*4", gReg
[Rn
], SIGN (U
), OpCode
& 0xff);
426 // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
427 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x*4]%a", gReg
[Rn
], SIGN (U
), OpCode
& 0xff, WRITE (W
));
432 if ((OpCode
& 0x0f000010) == 0x0e000010) {
433 // A4.1.32 MRC2, MCR2
434 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);
438 if ((OpCode
& 0x0ff00000) == 0x0c400000) {
439 // A4.1.33 MRRC2, MCRR2
440 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
);
444 AsciiSPrint (Buf
, Size
, "Faulting OpCode 0x%08x", OpCode
);