]>
git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
5b43f5542e83d2b819ba9064a2b31d75aba90645
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/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.
160 DisassembleArmInstruction (
161 IN UINT32
**OpCodePtr
,
166 UINT32 OpCode
= **OpCodePtr
;
168 BOOLEAN I
, P
, U
, B
, W
, L
, S
, H
;
170 UINT32 imode
, offset_8
, offset_12
;
172 UINT32 shift_imm
, shift
;
174 I
= (OpCode
& BIT25
) == BIT25
;
175 P
= (OpCode
& BIT24
) == BIT24
;
176 U
= (OpCode
& BIT23
) == BIT23
;
177 B
= (OpCode
& BIT22
) == BIT22
; // Also called S
178 W
= (OpCode
& BIT21
) == BIT21
;
179 L
= (OpCode
& BIT20
) == BIT20
;
180 S
= (OpCode
& BIT6
) == BIT6
;
181 H
= (OpCode
& BIT5
) == BIT5
;
182 Rn
= (OpCode
>> 16) & 0xf;
183 Rd
= (OpCode
>> 12) & 0xf;
187 if ((OpCode
& 0x0fe000f0) == 0x01800090) {
189 // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]
190 AsciiSPrint (Buf
, Size
, "LDREX%a %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
]);
192 // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
193 AsciiSPrint (Buf
, Size
, "STREX%a %a, %a, [%a]", COND (OpCode
), gReg
[Rd
], gReg
[Rn
], gReg
[Rn
]);
199 if ((OpCode
& 0x0e000000) == 0x08000000) {
201 // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
202 // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
203 // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
204 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
));
206 // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
207 // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
208 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
));
213 // LDR/STR Address Mode 2
214 if ( ((OpCode
& 0x0c000000) == 0x04000000) || ((OpCode
& 0xfd70f000 ) == 0xf550f000) ) {
215 offset_12
= OpCode
& 0xfff;
216 if ((OpCode
& 0xfd70f000 ) == 0xf550f000) {
217 Index
= AsciiSPrint (Buf
, Size
, "PLD");
219 Index
= AsciiSPrint (Buf
, Size
, "%a%a%a%a %a, ", L
? "LDR" : "STR", COND (OpCode
), BYTE (B
), (!P
& W
) ? "T":"", gReg
[Rd
]);
223 // A5.2.2 [<Rn>, #+/-<offset_12>]
224 // A5.2.5 [<Rn>, #+/-<offset_12>]
225 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x]%a", gReg
[Rn
], SIGN (U
), offset_12
, WRITE (W
));
226 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
227 // A5.2.3 [<Rn>, +/-<Rm>]
228 // A5.2.6 [<Rn>, +/-<Rm>]!
229 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a]%a", gReg
[Rn
], SIGN (U
), WRITE (W
));
231 // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
232 // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
233 shift_imm
= (OpCode
>> 7) & 0x1f;
234 shift
= (OpCode
>> 5) & 0x3;
237 } else if (shift
== 0x1) {
239 if (shift_imm
== 0) {
242 } else if (shift
== 0x12) {
244 } else if (shift_imm
== 0) {
245 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, RRX]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
251 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%a, %a, #%d]%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
, WRITE (W
));
255 // A5.2.8 [<Rn>], #+/-<offset_12>
256 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x", gReg
[Rn
], SIGN (U
), offset_12
);
257 } else if ((OpCode
& 0x03000ff0) == 0x03000000) {
258 // A5.2.9 [<Rn>], +/-<Rm>
259 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
261 // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
262 shift_imm
= (OpCode
>> 7) & 0x1f;
263 shift
= (OpCode
>> 5) & 0x3;
267 } else if (shift
== 0x1) {
269 if (shift_imm
== 0) {
272 } else if (shift
== 0x12) {
274 } else if (shift_imm
== 0) {
275 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, RRX", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
282 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a, %a, #%d", gReg
[Rn
], SIGN (U
), gReg
[Rm
], Type
, shift_imm
);
288 if ((OpCode
& 0x0e000000) == 0x00000000) {
289 // LDR/STR address mode 3
290 // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>
293 Root
= "LDR%aH %a, ";
295 Root
= "LDR%aSB %a, ";
297 Root
= "LDR%aSH %a, ";
309 Index
= AsciiSPrint (Buf
, Size
, Root
, COND (OpCode
), gReg
[Rd
]);
311 S
= (OpCode
& BIT6
) == BIT6
;
312 H
= (OpCode
& BIT5
) == BIT5
;
313 offset_8
= ((OpCode
>> 4) | (OpCode
* 0xf)) & 0xff;
315 // Immediate offset/index
317 // A5.3.2 [<Rn>, #+/-<offset_8>]
318 // A5.3.4 [<Rn>, #+/-<offset_8>]!
319 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%d]%a", gReg
[Rn
], SIGN (U
), offset_8
, WRITE (W
));
321 // A5.3.3 [<Rn>, +/-<Rm>]
322 // A5.3.5 [<Rn>, +/-<Rm>]!
323 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a%]a", gReg
[Rn
], SIGN (U
), gReg
[Rm
], WRITE (W
));
326 // Register offset/index
328 // A5.3.6 [<Rn>], #+/-<offset_8>
329 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%d", gReg
[Rn
], SIGN (U
), offset_8
);
331 // A5.3.7 [<Rn>], +/-<Rm>
332 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a%a", gReg
[Rn
], SIGN (U
), gReg
[Rm
]);
338 if ((OpCode
& 0x0fb000f0) == 0x01000050) {
339 // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
340 // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]
341 AsciiSPrint (Buf
, Size
, "SWP%a%a %a, %a, [%a]", COND (OpCode
), BYTE (B
), gReg
[Rd
], gReg
[Rm
], gReg
[Rn
]);
345 if ((OpCode
& 0xfe5f0f00) == 0xf84d0500) {
346 // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}
347 AsciiSPrint (Buf
, Size
, "SRS%a #0x%x%a", gLdmStack
[(OpCode
>> 23) & 3], OpCode
& 0x1f, WRITE (W
));
351 if ((OpCode
& 0xfe500f00) == 0xf8100500) {
352 // A4.1.59 RFE<addressing_mode> <Rn>{!}
353 AsciiSPrint (Buf
, Size
, "RFE%a %a", gLdmStack
[(OpCode
>> 23) & 3], gReg
[Rn
], WRITE (W
));
357 if ((OpCode
& 0xfff000f0) == 0xe1200070) {
358 // A4.1.7 BKPT <immed_16>
359 AsciiSPrint (Buf
, Size
, "BKPT %x", ((OpCode
>> 8) | (OpCode
& 0xf)) & 0xffff);
363 if ((OpCode
& 0xfff10020) == 0xf1000000) {
364 // A4.1.16 CPS<effect> <iflags> {, #<mode>}
365 if (((OpCode
>> 6) & 0x7) == 0) {
366 AsciiSPrint (Buf
, Size
, "CPS #0x%x", (OpCode
& 0x2f));
368 imode
= (OpCode
>> 18) & 0x3;
369 Index
= AsciiSPrint (Buf
, Size
, "CPS%a %a%a%a", (imode
== 3) ? "ID":"IE", (OpCode
& BIT8
) ? "A":"", (OpCode
& BIT7
) ? "I":"", (OpCode
& BIT6
) ? "F":"");
370 if ((OpCode
& BIT17
) != 0) {
371 AsciiSPrint (&Buf
[Index
], Size
- Index
, ", #0x%x", OpCode
& 0x1f);
377 if ((OpCode
& 0x0f000000) == 0x0f000000) {
378 // A4.1.107 SWI{<cond>} <immed_24>
379 AsciiSPrint (Buf
, Size
, "SWI%a %x", COND (OpCode
), OpCode
& 0x00ffffff);
383 if ((OpCode
& 0x0fb00000) == 0x01000000) {
384 // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR
385 AsciiSPrint (Buf
, Size
, "MRS%a %a, %a", COND (OpCode
), gReg
[Rd
], B
? "SPSR" : "CPSR");
390 if ((OpCode
& 0x0db00000) == 0x03200000) {
391 // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
393 // MSR{<cond>} CPSR_<fields>, #<immediate>
394 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));
396 // MSR{<cond>} CPSR_<fields>, <Rm>
397 AsciiSPrint (Buf
, Size
, "MRS%a %a_%a, %a", COND (OpCode
), B
? "SPSR" : "CPSR", gReg
[Rd
]);
402 if ((OpCode
& 0xff000010) == 0xfe000000) {
403 // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
404 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);
408 if ((OpCode
& 0x0e000000) == 0x0c000000) {
409 // A4.1.19 LDC and A4.1.96 SDC
410 if ((OpCode
& 0xf0000000) == 0xf0000000) {
411 Index
= AsciiSPrint (Buf
, Size
, "%a2 0x%x, CR%d, ", L
? "LDC":"SDC", (OpCode
>> 8) & 0xf, Rd
);
413 Index
= AsciiSPrint (Buf
, Size
, "%a%a 0x%x, CR%d, ", L
? "LDC":"SDC", COND (OpCode
), (OpCode
>> 8) & 0xf, Rd
);
418 // A5.5.5.5 [<Rn>], <option>
419 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], {0x%x}", gReg
[Rn
], OpCode
& 0xff);
421 // A.5.5.4 [<Rn>], #+/-<offset_8>*4
422 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a], #%a0x%x*4", gReg
[Rn
], SIGN (U
), OpCode
& 0xff);
425 // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
426 AsciiSPrint (&Buf
[Index
], Size
- Index
, "[%a, #%a0x%x*4]%a", gReg
[Rn
], SIGN (U
), OpCode
& 0xff, WRITE (W
));
431 if ((OpCode
& 0x0f000010) == 0x0e000010) {
432 // A4.1.32 MRC2, MCR2
433 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);
437 if ((OpCode
& 0x0ff00000) == 0x0c400000) {
438 // A4.1.33 MRRC2, MCRR2
439 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
);
443 AsciiSPrint (Buf
, Size
, "Faulting OpCode 0x%08x", OpCode
);