SemihostLib|Include/Library/Semihosting.h\r
UncachedMemoryAllocationLib|Include/Library/UncachedMemoryAllocationLib.h\r
DefaultExceptioHandlerLib|Include/Library/DefaultExceptioHandlerLib.h\r
-\r
+ ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h\r
+ \r
[Guids.common]\r
gArmTokenSpaceGuid = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }\r
\r
ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+ ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
[LibraryClasses.ARM]
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
--- /dev/null
+/** @file
+
+ Copyright (c) 2008-2010 Apple Inc. All rights reserved.<BR>
+
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __ARM_DISASSEBLER_LIB_H__
+#define __ARM_DISASSEBLER_LIB_H__
+
+/**
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
+ point to next instructin.
+
+ We cheat and only decode instructions that access
+ memory. If the instruction is not found we dump the instruction in hex.
+
+ @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
+ @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
+ @param Buf Buffer to sprintf disassembly into.
+ @param Size Size of Buf in bytes.
+
+**/
+VOID
+DisassembleInstruction (
+ IN UINT8 **OpCodePtr,
+ IN BOOLEAN Thumb,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size
+ );
+
+#endif
--- /dev/null
+/** @file\r
+ Default exception handler\r
+\r
+ Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+ \r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/ArmDisassemblerLib.h>\r
+\r
+CHAR8 *gCondition[] = {\r
+ "EQ",\r
+ "NE",\r
+ "CS",\r
+ "CC",\r
+ "MI",\r
+ "PL",\r
+ "VS",\r
+ "VC",\r
+ "HI",\r
+ "LS",\r
+ "GE",\r
+ "LT",\r
+ "GT",\r
+ "LE",\r
+ "",\r
+ "2"\r
+};\r
+\r
+#define COND(_a) gCondition[(_a) >> 28]\r
+\r
+CHAR8 *gReg[] = {\r
+ "r0",\r
+ "r1",\r
+ "r2",\r
+ "r3",\r
+ "r4",\r
+ "r5",\r
+ "r6",\r
+ "r7",\r
+ "r8",\r
+ "r9",\r
+ "r10",\r
+ "r11",\r
+ "r12",\r
+ "sp",\r
+ "lr",\r
+ "pc"\r
+};\r
+\r
+CHAR8 *gLdmAdr[] = {\r
+ "DA",\r
+ "IA",\r
+ "DB",\r
+ "IB"\r
+};\r
+\r
+CHAR8 *gLdmStack[] = {\r
+ "FA",\r
+ "FD",\r
+ "EA",\r
+ "ED"\r
+};\r
+\r
+#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])\r
+\r
+\r
+#define SIGN(_U) ((_U) ? "" : "-")\r
+#define WRITE(_W) ((_W) ? "!" : "")\r
+#define BYTE(_B) ((_B) ? "B":"")\r
+#define USER(_B) ((_B) ? "^" : "")\r
+\r
+CHAR8 mMregListStr[4*15 + 1];\r
+\r
+CHAR8 *\r
+MRegList (\r
+ UINT32 OpCode\r
+ )\r
+{\r
+ UINTN Index, Start, End;\r
+ CHAR8 *Str;\r
+ BOOLEAN First;\r
+ \r
+ Str = mMregListStr;\r
+ *Str = '\0';\r
+ AsciiStrCat (Str, "{");\r
+ for (Index = 0, First = TRUE; Index <= 15; Index++) {\r
+ if ((OpCode & (1 << Index)) != 0) {\r
+ Start = End = Index;\r
+ for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {\r
+ End = Index;\r
+ }\r
+ \r
+ if (!First) {\r
+ AsciiStrCat (Str, ",");\r
+ } else {\r
+ First = FALSE;\r
+ }\r
+ \r
+ if (Start == End) {\r
+ AsciiStrCat (Str, gReg[Start]);\r
+ AsciiStrCat (Str, ", ");\r
+ } else {\r
+ AsciiStrCat (Str, gReg[Start]);\r
+ AsciiStrCat (Str, "-");\r
+ AsciiStrCat (Str, gReg[End]);\r
+ }\r
+ }\r
+ }\r
+ if (First) {\r
+ AsciiStrCat (Str, "ERROR");\r
+ }\r
+ AsciiStrCat (Str, "}");\r
+ \r
+ // BugBug: Make caller pass in buffer it is cleaner\r
+ return mMregListStr;\r
+}\r
+\r
+CHAR8 *\r
+FieldMask (\r
+ IN UINT32 Mask\r
+ )\r
+{\r
+ return "";\r
+}\r
+\r
+UINT32\r
+RotateRight (\r
+ IN UINT32 Op,\r
+ IN UINT32 Shift\r
+ )\r
+{\r
+ return (Op >> Shift) | (Op << (32 - Shift));\r
+}\r
+\r
+\r
+/**\r
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
+ point to next instructin. \r
+ \r
+ We cheat and only decode instructions that access \r
+ memory. If the instruction is not found we dump the instruction in hex.\r
+ \r
+ @param OpCodePtr Pointer to pointer of ARM instruction to disassemble. \r
+ @param Buf Buffer to sprintf disassembly into.\r
+ @param Size Size of Buf in bytes. \r
+ \r
+**/\r
+VOID\r
+DisassembleArmInstruction (\r
+ IN UINT32 **OpCodePtr,\r
+ OUT CHAR8 *Buf,\r
+ OUT UINTN Size\r
+ )\r
+{\r
+ UINT32 OpCode = **OpCodePtr;\r
+ CHAR8 *Type, *Root;\r
+ BOOLEAN I, P, U, B, W, L, S, H;\r
+ UINT32 Rn, Rd, Rm;\r
+ UINT32 imode, offset_8, offset_12;\r
+ UINT32 Index;\r
+ UINT32 shift_imm, shift;\r
+\r
+ I = (OpCode & BIT25) == BIT25;\r
+ P = (OpCode & BIT24) == BIT24;\r
+ U = (OpCode & BIT23) == BIT23;\r
+ B = (OpCode & BIT22) == BIT22; // Also called S\r
+ W = (OpCode & BIT21) == BIT21; \r
+ L = (OpCode & BIT20) == BIT20;\r
+ S = (OpCode & BIT6) == BIT6;\r
+ H = (OpCode & BIT5) == BIT5;\r
+ Rn = (OpCode >> 16) & 0xf;\r
+ Rd = (OpCode >> 12) & 0xf;\r
+ Rm = (OpCode & 0xf);\r
+\r
+ // LDREX, STREX\r
+ if ((OpCode & 0x0fe000f0) == 0x01800090) {\r
+ if (L) {\r
+ // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>] \r
+ AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]); \r
+ } else {\r
+ // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]\r
+ AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]); \r
+ } \r
+ return;\r
+ }\r
+ \r
+ // LDM/STM\r
+ if ((OpCode & 0x0e000000) == 0x08000000) {\r
+ if (L) {\r
+ // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r
+ // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^\r
+ // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^\r
+ 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)); \r
+ } else {\r
+ // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r
+ // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^\r
+ 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)); \r
+ } \r
+ return;\r
+ }\r
+\r
+ // LDR/STR Address Mode 2\r
+ if ( ((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {\r
+ offset_12 = OpCode & 0xfff;\r
+ if ((OpCode & 0xfd70f000 ) == 0xf550f000) {\r
+ Index = AsciiSPrint (Buf, Size, "PLD");\r
+ } else {\r
+ Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", L ? "LDR" : "STR", COND (OpCode), BYTE (B), (!P & W) ? "T":"", gReg[Rd]); \r
+ }\r
+ if (P) {\r
+ if (!I) {\r
+ // A5.2.2 [<Rn>, #+/-<offset_12>]\r
+ // A5.2.5 [<Rn>, #+/-<offset_12>]\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (U), offset_12, WRITE (W));\r
+ } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r
+ // A5.2.3 [<Rn>, +/-<Rm>]\r
+ // A5.2.6 [<Rn>, +/-<Rm>]!\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (U), WRITE (W));\r
+ } else {\r
+ // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]\r
+ // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!\r
+ shift_imm = (OpCode >> 7) & 0x1f;\r
+ shift = (OpCode >> 5) & 0x3;\r
+ if (shift == 0x0) {\r
+ Type = "LSL";\r
+ } else if (shift == 0x1) {\r
+ Type = "LSR";\r
+ if (shift_imm == 0) {\r
+ shift_imm = 32;\r
+ }\r
+ } else if (shift == 0x12) {\r
+ Type = "ASR";\r
+ } else if (shift_imm == 0) {\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r
+ return;\r
+ } else {\r
+ Type = "ROR";\r
+ }\r
+ \r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm, WRITE (W));\r
+ }\r
+ } else { // !P\r
+ if (!I) {\r
+ // A5.2.8 [<Rn>], #+/-<offset_12>\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (U), offset_12);\r
+ } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r
+ // A5.2.9 [<Rn>], +/-<Rm>\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r
+ } else {\r
+ // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>\r
+ shift_imm = (OpCode >> 7) & 0x1f;\r
+ shift = (OpCode >> 5) & 0x3;\r
+\r
+ if (shift == 0x0) {\r
+ Type = "LSL";\r
+ } else if (shift == 0x1) {\r
+ Type = "LSR";\r
+ if (shift_imm == 0) {\r
+ shift_imm = 32;\r
+ }\r
+ } else if (shift == 0x12) {\r
+ Type = "ASR";\r
+ } else if (shift_imm == 0) {\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);\r
+ // FIx me\r
+ return;\r
+ } else {\r
+ Type = "ROR";\r
+ }\r
+ \r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm);\r
+ }\r
+ }\r
+ return; \r
+ }\r
+ \r
+ if ((OpCode & 0x0e000000) == 0x00000000) {\r
+ // LDR/STR address mode 3\r
+ // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>\r
+ if (L) {\r
+ if (!S) {\r
+ Root = "LDR%aH %a, ";\r
+ } else if (!H) {\r
+ Root = "LDR%aSB %a, ";\r
+ } else {\r
+ Root = "LDR%aSH %a, ";\r
+ }\r
+ } else {\r
+ if (!S) {\r
+ Root = "STR%aH %a ";\r
+ } else if (!H) {\r
+ Root = "LDR%aD %a ";\r
+ } else {\r
+ Root = "STR%aD %a ";\r
+ }\r
+ }\r
+ \r
+ Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]); \r
+\r
+ S = (OpCode & BIT6) == BIT6;\r
+ H = (OpCode & BIT5) == BIT5;\r
+ offset_8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;\r
+ if (P & !W) {\r
+ // Immediate offset/index\r
+ if (B) {\r
+ // A5.3.2 [<Rn>, #+/-<offset_8>]\r
+ // A5.3.4 [<Rn>, #+/-<offset_8>]!\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (U), offset_8, WRITE (W));\r
+ } else {\r
+ // A5.3.3 [<Rn>, +/-<Rm>]\r
+ // A5.3.5 [<Rn>, +/-<Rm>]!\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r
+ }\r
+ } else {\r
+ // Register offset/index\r
+ if (B) {\r
+ // A5.3.6 [<Rn>], #+/-<offset_8>\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (U), offset_8);\r
+ } else {\r
+ // A5.3.7 [<Rn>], +/-<Rm>\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ if ((OpCode & 0x0fb000f0) == 0x01000050) {\r
+ // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r
+ // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r
+ AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (B), gReg[Rd], gReg[Rm], gReg[Rn]);\r
+ return;\r
+ }\r
+ \r
+ if ((OpCode & 0xfe5f0f00) == 0xf84d0500) {\r
+ // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}\r
+ AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (W));\r
+ return;\r
+ }\r
+\r
+ if ((OpCode & 0xfe500f00) == 0xf8100500) {\r
+ // A4.1.59 RFE<addressing_mode> <Rn>{!}\r
+ AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (W));\r
+ return;\r
+ }\r
+ \r
+ if ((OpCode & 0xfff000f0) == 0xe1200070) {\r
+ // A4.1.7 BKPT <immed_16>\r
+ AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);\r
+ return;\r
+ } \r
+ \r
+ if ((OpCode & 0xfff10020) == 0xf1000000) {\r
+ // A4.1.16 CPS<effect> <iflags> {, #<mode>}\r
+ if (((OpCode >> 6) & 0x7) == 0) {\r
+ AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));\r
+ } else {\r
+ imode = (OpCode >> 18) & 0x3;\r
+ Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");\r
+ if ((OpCode & BIT17) != 0) {\r
+ AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);\r
+ }\r
+ }\r
+ return;\r
+ } \r
+ \r
+ if ((OpCode & 0x0f000000) == 0x0f000000) {\r
+ // A4.1.107 SWI{<cond>} <immed_24>\r
+ AsciiSPrint (Buf, Size, "SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);\r
+ return;\r
+ } \r
+\r
+ if ((OpCode & 0x0fb00000) == 0x01000000) {\r
+ // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR\r
+ AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], B ? "SPSR" : "CPSR");\r
+ return;\r
+ } \r
+\r
+\r
+ if ((OpCode & 0x0db00000) == 0x03200000) {\r
+ // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>\r
+ if (I) {\r
+ // MSR{<cond>} CPSR_<fields>, #<immediate>\r
+ 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));\r
+ } else {\r
+ // MSR{<cond>} CPSR_<fields>, <Rm>\r
+ AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), B ? "SPSR" : "CPSR", gReg[Rd]);\r
+ }\r
+ return;\r
+ } \r
+\r
+ if ((OpCode & 0xff000010) == 0xfe000000) {\r
+ // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>\r
+ 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);\r
+ return;\r
+ }\r
+ \r
+ if ((OpCode & 0x0e000000) == 0x0c000000) {\r
+ // A4.1.19 LDC and A4.1.96 SDC\r
+ if ((OpCode & 0xf0000000) == 0xf0000000) {\r
+ Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", L ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);\r
+ } else {\r
+ Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", L ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);\r
+ }\r
+ \r
+ if (!P) {\r
+ if (!W) { \r
+ // A5.5.5.5 [<Rn>], <option>\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff); \r
+ } else {\r
+ // A.5.5.4 [<Rn>], #+/-<offset_8>*4\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (U), OpCode & 0xff); \r
+ }\r
+ } else {\r
+ // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!\r
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (U), OpCode & 0xff, WRITE (W)); \r
+ }\r
+ \r
+ }\r
+ \r
+ if ((OpCode & 0x0f000010) == 0x0e000010) {\r
+ // A4.1.32 MRC2, MCR2 \r
+ 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);\r
+ return; \r
+ }\r
+\r
+ if ((OpCode & 0x0ff00000) == 0x0c400000) {\r
+ // A4.1.33 MRRC2, MCRR2 \r
+ 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);\r
+ return; \r
+ }\r
+\r
+ AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);\r
+ \r
+ *OpCodePtr += 1;\r
+ return;\r
+}\r
+\r
--- /dev/null
+#/** @file\r
+# Semihosting serail port lib\r
+#\r
+# Copyright (c) 2008, Apple Inc.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = SemiHostingSerialPortLib\r
+ FILE_GUID = 7ACEC173-F15D-426C-8F2F-BD86B4183EF1\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = ArmDisassemblerLib\r
+\r
+\r
+[Sources.common]\r
+ ArmDisassembler.c\r
+ ThumbDisassembler.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ ArmPkg/ArmPkg.dec\r
+\r
+[LibraryClasses]\r
+ UefiLib\r
+ BaseLib\r
+ PrintLib\r
+ DebugLib\r
+ PeCoffGetEntryPointLib\r
+\r
+\r
--- /dev/null
+/** @file\r
+ Default exception handler\r
+\r
+ Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
+ \r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+extern CHAR8 *gReg[];\r
+\r
+#define LOAD_STORE_FORMAT1 1\r
+#define LOAD_STORE_FORMAT2 2\r
+#define LOAD_STORE_FORMAT3 3\r
+#define LOAD_STORE_FORMAT4 4\r
+#define LOAD_STORE_MULTIPLE_FORMAT1 5 \r
+#define LOAD_STORE_MULTIPLE_FORMAT2 6 \r
+#define IMMED_8 7\r
+#define CONDITIONAL_BRANCH 8\r
+#define UNCONDITIONAL_BRANCH 9\r
+#define UNCONDITIONAL_BRANCH_SHORT 109\r
+#define BRANCH_EXCHANGE 10\r
+#define DATA_FORMAT1 11\r
+#define DATA_FORMAT2 12\r
+#define DATA_FORMAT3 13\r
+#define DATA_FORMAT4 14\r
+#define DATA_FORMAT5 15\r
+#define DATA_FORMAT6_SP 16\r
+#define DATA_FORMAT6_PC 116\r
+#define DATA_FORMAT7 17\r
+#define DATA_FORMAT8 19\r
+#define CPS_FORMAT 20\r
+#define ENDIAN_FORMAT 21\r
+ \r
+\r
+typedef struct {\r
+ CHAR8 *Start;\r
+ UINT32 OpCode;\r
+ UINT32 Mask;\r
+ UINT32 AddressMode;\r
+} THUMB_INSTRUCTIONS;\r
+\r
+THUMB_INSTRUCTIONS gOpThumb[] = {\r
+// Thumb 16-bit instrucitons\r
+// Op Mask Format\r
+ { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },\r
+\r
+ { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },\r
+ { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },\r
+ { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 },\r
+ { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 }, // A8.6.9\r
+ { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC },\r
+ { "ADD" , 0xa100, 0xf100, DATA_FORMAT6_SP }, \r
+ { "ADD" , 0xb000, 0xff10, DATA_FORMAT7 },\r
+\r
+ { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 },\r
+\r
+ { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 },\r
+ { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 },\r
+\r
+ { "B" , 0xd000, 0xf000, CONDITIONAL_BRANCH },\r
+ { "B" , 0xe000, 0xf100, UNCONDITIONAL_BRANCH_SHORT },\r
+ { "BL" , 0xf100, 0xf100, UNCONDITIONAL_BRANCH },\r
+ { "BLX" , 0xe100, 0xf100, UNCONDITIONAL_BRANCH },\r
+ { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE },\r
+ { "BX" , 0x4700, 0xff80, BRANCH_EXCHANGE },\r
+\r
+ { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 },\r
+ { "BKPT", 0xdf00, 0xff00, IMMED_8 },\r
+ { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 },\r
+\r
+ { "CMP" , 0x2800, 0xf100, DATA_FORMAT3 },\r
+ { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 },\r
+ { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 },\r
+\r
+ { "CPS" , 0xb660, 0xffe8, CPS_FORMAT },\r
+ { "CPY" , 0x4600, 0xff00, DATA_FORMAT8 },\r
+ { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },\r
+\r
+ { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
+ { "LDR" , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },\r
+ { "LDR" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
+ { "LDR" , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },\r
+ { "LDR" , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },\r
+ { "LDRB" , 0x7800, 0xf800, LOAD_STORE_FORMAT1 },\r
+ { "LDRB" , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },\r
+ { "LDRH" , 0x8800, 0xf800, LOAD_STORE_FORMAT1 },\r
+ { "LDRH" , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },\r
+ { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },\r
+ { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },\r
+ \r
+ { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 },\r
+ { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },\r
+ { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },\r
+ { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },\r
+\r
+ { "MOV" , 0x2000, 0xf800, DATA_FORMAT3 },\r
+ { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },\r
+ { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },\r
+\r
+ { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },\r
+ { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
+ { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },\r
+ { "ORR" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
+ { "POP" , 0xbc00, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r
+ { "POP" , 0xe400, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r
+ \r
+ { "REV" , 0xba00, 0xffc0, DATA_FORMAT5 },\r
+ { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 },\r
+ { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 },\r
+\r
+ { "ROR" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
+ { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
+ { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT },\r
+\r
+ { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
+ { "STR" , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },\r
+ { "STR" , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },\r
+ { "STR" , 0x4000, 0xf800, LOAD_STORE_FORMAT3 },\r
+ { "STR" , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },\r
+ { "STRB" , 0x7000, 0xf800, LOAD_STORE_FORMAT1 },\r
+ { "STRB" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
+ { "STRH" , 0x8000, 0xf800, LOAD_STORE_FORMAT1 },\r
+ { "STRH" , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },\r
+\r
+ { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },\r
+ { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },\r
+ { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },\r
+ { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },\r
+\r
+ { "SWI" , 0xdf00, 0xff00, IMMED_8 },\r
+ { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },\r
+ { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },\r
+ { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },\r
+ { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },\r
+ { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }\r
+};\r
+\r
+#if 0 \r
+THUMB_INSTRUCTIONS gOpThumb2[] = {\r
+ ,\r
+ \r
+ // 32-bit Thumb instructions op1 01\r
+ \r
+ // 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx Load/store multiple\r
+ { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT }, // SRSDB<c> SP{!},#<mode>\r
+ { "SRS" , 0xe98dc000, 0xffdffff0, SRS_IA_FORMAT }, // SRS{IA}<c> SP{!},#<mode>\r
+ { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT }, // RFEDB<c> <Rn>{!}\r
+ { "RFE" , 0xe990c000, 0xffd0ffff, RFE_IA_FORMAT }, // RFE{IA}<c> <Rn>{!}\r
+ \r
+ { "STM" , 0xe8800000, 0xffd00000, STM_FORMAT }, // STM<c>.W <Rn>{!},<registers>\r
+ { "LDM" , 0xe8900000, 0xffd00000, STM_FORMAT }, // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r
+ { "POP" , 0xe8bd0000, 0xffff2000, REGLIST_FORMAT }, // POP<c>.W <registers> >1 register\r
+ { "POP" , 0xf85d0b04, 0xffff0fff, RT_FORMAT }, // POP<c>.W <registers> 1 register\r
+\r
+ { "STMDB", 0xe9000000, 0xffd00000, STM_FORMAT }, // STMDB\r
+ { "PUSH" , 0xe8bd0000, 0xffffa000, REGLIST_FORMAT }, // PUSH<c>.W <registers> >1 register\r
+ { "PUSH" , 0xf84d0b04, 0xffff0fff, RT_FORMAT }, // PUSH<c>.W <registers> 1 register\r
+ { "LDMDB", 0xe9102000, 0xffd02000, STM_FORMAT }, // LDMDB<c> <Rn>{!},<registers>\r
+\r
+ // 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx Load/store dual,\r
+ { "STREX" , 0xe0400000, 0xfff000f0, 3REG_IMM8_FORMAT }, // STREX<c> <Rd>,<Rt>,[<Rn>{,#<imm>}]\r
+ { "STREXB", 0xe8c00f40, 0xfff00ff0, 3REG_FORMAT }, // STREXB<c> <Rd>,<Rt>,[<Rn>]\r
+ { "STREXD", 0xe8c00070, 0xfff000f0, 4REG_FORMAT }, // STREXD<c> <Rd>,<Rt>,<Rt2>,[<Rn>]\r
+ { "STREXH", 0xe8c00f70, 0xfff00ff0, 3REG_FORMAT }, // STREXH<c> <Rd>,<Rt>,[<Rn>]\r
+ { "STRH", 0xf8c00000, 0xfff00000, 2REG_IMM8_FORMAT }, // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]\r
+ { "STRH", 0xf8200000, 0xfff00000, }, // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r
+\r
+\r
+\r
+ // 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx Data-processing\r
+ // 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor\r
+ \r
+ // 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing modified immediate\r
+ // 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing plain immediate\r
+ // 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx Branches\r
+ \r
+ // 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx Store single data item\r
+ // 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx SIMD or load/store\r
+ // 1111 100x x001 xxxx xxxx xxxx xxxx xxxx Load byte, memory hints \r
+ // 1111 100x x011 xxxx xxxx xxxx xxxx xxxx Load halfword, memory hints\r
+ // 1111 100x x101 xxxx xxxx xxxx xxxx xxxx Load word \r
+\r
+ // 1111 1 010 xxxx xxxx xxxx xxxx xxxx xxxx Data-processing register\r
+ // 1111 1 011 0xxx xxxx xxxx xxxx xxxx xxxx Multiply\r
+ // 1111 1 011 1xxx xxxx xxxx xxxx xxxx xxxx Long Multiply\r
+ // 1111 1 1xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor \r
+};\r
+#endif\r
+\r
+CHAR8 mThumbMregListStr[4*15 + 1];\r
+\r
+CHAR8 *\r
+ThumbMRegList (\r
+ UINT32 OpCode\r
+ )\r
+{\r
+ UINTN Index, Start, End;\r
+ CHAR8 *Str;\r
+ BOOLEAN First;\r
+ \r
+ Str = mThumbMregListStr;\r
+ *Str = '\0';\r
+ AsciiStrCat (Str, "{");\r
+ // R0 - R7, PC\r
+ for (Index = 0, First = TRUE; Index <= 9; Index++) {\r
+ if ((OpCode & (1 << Index)) != 0) {\r
+ Start = End = Index;\r
+ for (Index++; ((OpCode & (1 << Index)) != 0) && (Index <= 9); Index++) {\r
+ End = Index;\r
+ }\r
+ \r
+ if (!First) {\r
+ AsciiStrCat (Str, ",");\r
+ } else {\r
+ First = FALSE;\r
+ }\r
+ \r
+ if (Start == End) {\r
+ AsciiStrCat (Str, gReg[(Start == 9)?15:Start]);\r
+ AsciiStrCat (Str, ", ");\r
+ } else {\r
+ AsciiStrCat (Str, gReg[Start]);\r
+ AsciiStrCat (Str, "-");\r
+ AsciiStrCat (Str, gReg[(End == 9)?15:End]);\r
+ }\r
+ }\r
+ }\r
+ if (First) {\r
+ AsciiStrCat (Str, "ERROR");\r
+ }\r
+ AsciiStrCat (Str, "}");\r
+ \r
+ // BugBug: Make caller pass in buffer it is cleaner\r
+ return mThumbMregListStr;\r
+}\r
+\r
+UINT32\r
+SignExtend (\r
+ IN UINT32 Data\r
+ )\r
+{\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
+ point to next instructin. \r
+ \r
+ We cheat and only decode instructions that access \r
+ memory. If the instruction is not found we dump the instruction in hex.\r
+ \r
+ @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. \r
+ @param Buf Buffer to sprintf disassembly into.\r
+ @param Size Size of Buf in bytes. \r
+ \r
+**/\r
+VOID\r
+DisassembleThumbInstruction (\r
+ IN UINT16 **OpCodePtrPtr,\r
+ OUT CHAR8 *Buf,\r
+ OUT UINTN Size\r
+ )\r
+{\r
+ UINT16 *OpCodePtr;\r
+ UINT16 OpCode;\r
+ UINT16 OpCode32;\r
+ UINT32 Index;\r
+ UINT32 Offset;\r
+ UINT16 Rd, Rn, Rm;\r
+ INT32 target_addr;\r
+ BOOLEAN H1, H2, imod;\r
+ UINT32 PC;\r
+\r
+ OpCodePtr = *OpCodePtrPtr;\r
+ OpCode = **OpCodePtrPtr;\r
+ \r
+ // Thumb2 is a stream of 16-bit instructions not a 32-bit instruction.\r
+ OpCode32 = (OpCode << 16) | *(OpCodePtr + 1);\r
+\r
+ // These register names match branch form, but not others\r
+ Rd = OpCode & 0x7;\r
+ Rn = (OpCode >> 3) & 0x7;\r
+ Rm = (OpCode >> 6) & 0x7;\r
+ H1 = (OpCode & BIT7) != 0;\r
+ H2 = (OpCode & BIT6) != 0;\r
+ imod = (OpCode & BIT4) != 0;\r
+ PC = (UINT32)(UINTN)*OpCodePtr;\r
+\r
+ // Increment by the minimum instruction size, Thumb2 could be bigger\r
+ *OpCodePtrPtr += 1;\r
+ \r
+ for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
+ if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {\r
+ Offset = AsciiSPrint (Buf, Size, "%a", gOpThumb[Index].Start); \r
+ switch (gOpThumb[Index].AddressMode) {\r
+ case LOAD_STORE_FORMAT1:\r
+ // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, (OpCode >> 7) & 7, (OpCode >> 6) & 0x1f); \r
+ break;\r
+ case LOAD_STORE_FORMAT2:\r
+ // A6.5.1 <Rd>, [<Rn>, <Rm>]\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, (OpCode >> 3) & 7, Rm); \r
+ break;\r
+ case LOAD_STORE_FORMAT3:\r
+ // A6.5.1 <Rd>, [PC, #<8_bit_offset>]\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff); \r
+ break;\r
+ case LOAD_STORE_FORMAT4:\r
+ // FIX ME!!!!!\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff); \r
+ break;\r
+ \r
+ case LOAD_STORE_MULTIPLE_FORMAT1:\r
+ // <Rn>!, <registers> \r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (!BIT8 & OpCode)); \r
+ break;\r
+ case LOAD_STORE_MULTIPLE_FORMAT2:\r
+ // <Rn>!, <registers> \r
+ // BIT8 is PC \r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode)); \r
+ break;\r
+ \r
+ case IMMED_8:\r
+ // A6.7 <immed_8>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff); \r
+ break;\r
+\r
+ case CONDITIONAL_BRANCH:\r
+ // A6.3.1 B<cond> <target_address>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, "%a 0x%04x", PC + 4 + SignExtend ((OpCode & 0xff) << 1)); \r
+ break;\r
+ case UNCONDITIONAL_BRANCH_SHORT:\r
+ // A6.3.2 B <target_address>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend ((OpCode & 0x3ff) << 1)); \r
+ break;\r
+ case UNCONDITIONAL_BRANCH:\r
+ // A6.3.2 BL|BLX <target_address> ; Produces two 16-bit instructions \r
+ target_addr = *(OpCodePtr - 1);\r
+ if ((target_addr & 0xf800) == 0xf000) {\r
+ target_addr = ((target_addr & 0x3ff) << 12) | (OpCode & 0x3ff);\r
+ } else {\r
+ target_addr = OpCode & 0x3ff;\r
+ }\r
+ // PC + 2 +/- target_addr\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 2 + SignExtend (target_addr)); \r
+ break;\r
+ case BRANCH_EXCHANGE:\r
+ // A6.3.3 BX|BLX <Rm>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d", gReg[Rn | (H2 ? 8:0)]); \r
+ break;\r
+\r
+ case DATA_FORMAT1:\r
+ // A6.4.3 <Rd>, <Rn>, <Rm>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm); \r
+ break;\r
+ case DATA_FORMAT2:\r
+ // A6.4.3 <Rd>, <Rn>, #3_bit_immed\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm); \r
+ break;\r
+ case DATA_FORMAT3:\r
+ // A6.4.3 <Rd>|<Rn>, #8_bit_immed\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", (OpCode >> 8) & 0x7, OpCode & 0xff); \r
+ break;\r
+ case DATA_FORMAT4:\r
+ // A6.4.3 <Rd>|<Rm>, #immed_5\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f); \r
+ break;\r
+ case DATA_FORMAT5:\r
+ // A6.4.3 <Rd>|<Rm>, <Rm>|<Rs>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn); \r
+ break;\r
+ case DATA_FORMAT6_SP:\r
+ // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff); \r
+ break;\r
+ case DATA_FORMAT6_PC:\r
+ // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff); \r
+ break;\r
+ case DATA_FORMAT7:\r
+ // A6.4.3 SP, SP, #<7_Bit_immed>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp 0x%x", (OpCode & 0x7f)*4); \r
+ break;\r
+ case DATA_FORMAT8:\r
+ // A6.4.3 <Rd>|<Rn>, <Rm>\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]); \r
+ break;\r
+ \r
+ case CPS_FORMAT:\r
+ // A7.1.24\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, "%a %a%a%a", imod ? "ID":"IE", ((OpCode & BIT2) == 0) ? "":"a", ((OpCode & BIT1) == 0) ? "":"i", ((OpCode & BIT0) == 0) ? "":"f"); \r
+ break;\r
+\r
+ case ENDIAN_FORMAT:\r
+ // A7.1.24\r
+ AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE"); \r
+ break;\r
+ }\r
+ }\r
+ }\r
+#if 0 \r
+ // Thumb2 are 32-bit instructions\r
+ *OpCodePtrPtr += 1;\r
+ for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
+ if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) {\r
+ }\r
+ }\r
+#endif\r
+ // Unknown instruction is 16-bits\r
+ *OpCodePtrPtr -= 1;\r
+ AsciiSPrint (Buf, Size, "0x%04x", OpCode);\r
+}\r
+\r
+\r
+\r
+VOID\r
+DisassembleArmInstruction (\r
+ IN UINT32 **OpCodePtr,\r
+ OUT CHAR8 *Buf,\r
+ OUT UINTN Size\r
+ );\r
+\r
+\r
+/**\r
+ Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to \r
+ point to next instructin. \r
+ \r
+ We cheat and only decode instructions that access \r
+ memory. If the instruction is not found we dump the instruction in hex.\r
+ \r
+ @param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble. \r
+ @param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream\r
+ @param Buf Buffer to sprintf disassembly into.\r
+ @param Size Size of Buf in bytes. \r
+ \r
+**/\r
+VOID\r
+DisassembleInstruction (\r
+ IN UINT8 **OpCodePtr,\r
+ IN BOOLEAN Thumb,\r
+ OUT CHAR8 *Buf,\r
+ OUT UINTN Size\r
+ )\r
+{\r
+ if (Thumb) {\r
+ DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size);\r
+ } else {\r
+ DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size);\r
+ }\r
+}\r
+ \r
+++ /dev/null
-/** @file\r
- Default exception handler\r
-\r
- Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
- \r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Base.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/PrintLib.h>\r
-\r
-\r
-CHAR8 *gCondition[] = {\r
- "EQ",\r
- "NE",\r
- "CS",\r
- "CC",\r
- "MI",\r
- "PL",\r
- "VS",\r
- "VC",\r
- "HI",\r
- "LS",\r
- "GE",\r
- "LT",\r
- "GT",\r
- "LE",\r
- "",\r
- "2"\r
-};\r
-\r
-#define COND(_a) gCondition[(_a) >> 28]\r
-\r
-CHAR8 *gReg[] = {\r
- "r0",\r
- "r1",\r
- "r2",\r
- "r3",\r
- "r4",\r
- "r5",\r
- "r6",\r
- "r7",\r
- "r8",\r
- "r9",\r
- "r10",\r
- "r11",\r
- "r12",\r
- "sp",\r
- "lr",\r
- "pc"\r
-};\r
-\r
-CHAR8 *gLdmAdr[] = {\r
- "DA",\r
- "IA",\r
- "DB",\r
- "IB"\r
-};\r
-\r
-CHAR8 *gLdmStack[] = {\r
- "FA",\r
- "FD",\r
- "EA",\r
- "ED"\r
-};\r
-\r
-#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])\r
-\r
-\r
-#define SIGN(_U) ((_U) ? "" : "-")\r
-#define WRITE(_W) ((_W) ? "!" : "")\r
-#define BYTE(_B) ((_B) ? "B":"")\r
-#define USER(_B) ((_B) ? "^" : "")\r
-\r
-CHAR8 mMregListStr[4*15 + 1];\r
-\r
-CHAR8 *\r
-MRegList (\r
- UINT32 OpCode\r
- )\r
-{\r
- UINTN Index, Start, End;\r
- CHAR8 *Str;\r
- BOOLEAN First;\r
- \r
- Str = mMregListStr;\r
- *Str = '\0';\r
- AsciiStrCat (Str, "{");\r
- for (Index = 0, First = TRUE; Index <= 15; Index++) {\r
- if ((OpCode & (1 << Index)) != 0) {\r
- Start = End = Index;\r
- for (Index++; ((OpCode & (1 << Index)) != 0) && Index <= 15; Index++) {\r
- End = Index;\r
- }\r
- \r
- if (!First) {\r
- AsciiStrCat (Str, ",");\r
- } else {\r
- First = FALSE;\r
- }\r
- \r
- if (Start == End) {\r
- AsciiStrCat (Str, gReg[Start]);\r
- AsciiStrCat (Str, ", ");\r
- } else {\r
- AsciiStrCat (Str, gReg[Start]);\r
- AsciiStrCat (Str, "-");\r
- AsciiStrCat (Str, gReg[End]);\r
- }\r
- }\r
- }\r
- if (First) {\r
- AsciiStrCat (Str, "ERROR");\r
- }\r
- AsciiStrCat (Str, "}");\r
- \r
- // BugBug: Make caller pass in buffer it is cleaner\r
- return mMregListStr;\r
-}\r
-\r
-CHAR8 *\r
-FieldMask (\r
- IN UINT32 Mask\r
- )\r
-{\r
- return "";\r
-}\r
-\r
-UINT32\r
-RotateRight (\r
- IN UINT32 Op,\r
- IN UINT32 Shift\r
- )\r
-{\r
- return (Op >> Shift) | (Op << (32 - Shift));\r
-}\r
-\r
-\r
-/**\r
- DEBUG print the faulting instruction. We cheat and only decode instructions that access \r
- memory. If the instruction is not found we dump the instruction in hex.\r
- \r
- @param Insturction ARM instruction to disassemble. \r
- \r
-**/\r
-VOID\r
-DisassembleArmInstruction (\r
- IN UINT32 *OpCodePtr,\r
- OUT CHAR8 *Buf,\r
- OUT UINTN Size\r
- )\r
-{\r
- UINT32 OpCode = *OpCodePtr;\r
- CHAR8 *Type, *Root;\r
- BOOLEAN I, P, U, B, W, L, S, H;\r
- UINT32 Rn, Rd, Rm;\r
- UINT32 imode, offset_8, offset_12;\r
- UINT32 Index;\r
- UINT32 shift_imm, shift;\r
-\r
- I = (OpCode & BIT25) == BIT25;\r
- P = (OpCode & BIT24) == BIT24;\r
- U = (OpCode & BIT23) == BIT23;\r
- B = (OpCode & BIT22) == BIT22; // Also called S\r
- W = (OpCode & BIT21) == BIT21; \r
- L = (OpCode & BIT20) == BIT20;\r
- S = (OpCode & BIT6) == BIT6;\r
- H = (OpCode & BIT5) == BIT5;\r
- Rn = (OpCode >> 16) & 0xf;\r
- Rd = (OpCode >> 12) & 0xf;\r
- Rm = (OpCode & 0xf);\r
-\r
- // LDREX, STREX\r
- if ((OpCode & 0x0fe000f0) == 0x01800090) {\r
- if (L) {\r
- // A4.1.27 LDREX{<cond>} <Rd>, [<Rn>] \r
- AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]); \r
- } else {\r
- // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]\r
- AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]); \r
- } \r
- return;\r
- }\r
- \r
- // LDM/STM\r
- if ((OpCode & 0x0e000000) == 0x08000000) {\r
- if (L) {\r
- // A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r
- // A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^\r
- // A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^\r
- 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)); \r
- } else {\r
- // A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>\r
- // A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^\r
- 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)); \r
- } \r
- return;\r
- }\r
-\r
- // LDR/STR Address Mode 2\r
- if ( ((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {\r
- offset_12 = OpCode & 0xfff;\r
- if ((OpCode & 0xfd70f000 ) == 0xf550f000) {\r
- Index = AsciiSPrint (Buf, Size, "PLD");\r
- } else {\r
- Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", L ? "LDR" : "STR", COND (OpCode), BYTE (B), (!P & W) ? "T":"", gReg[Rd]); \r
- }\r
- if (P) {\r
- if (!I) {\r
- // A5.2.2 [<Rn>, #+/-<offset_12>]\r
- // A5.2.5 [<Rn>, #+/-<offset_12>]\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x]%a", gReg[Rn], SIGN (U), offset_12, WRITE (W));\r
- } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r
- // A5.2.3 [<Rn>, +/-<Rm>]\r
- // A5.2.6 [<Rn>, +/-<Rm>]!\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a]%a", gReg[Rn], SIGN (U), WRITE (W));\r
- } else {\r
- // A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]\r
- // A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!\r
- shift_imm = (OpCode >> 7) & 0x1f;\r
- shift = (OpCode >> 5) & 0x3;\r
- if (shift == 0x0) {\r
- Type = "LSL";\r
- } else if (shift == 0x1) {\r
- Type = "LSR";\r
- if (shift_imm == 0) {\r
- shift_imm = 32;\r
- }\r
- } else if (shift == 0x12) {\r
- Type = "ASR";\r
- } else if (shift_imm == 0) {\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r
- return;\r
- } else {\r
- Type = "ROR";\r
- }\r
- \r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm, WRITE (W));\r
- }\r
- } else { // !P\r
- if (!I) {\r
- // A5.2.8 [<Rn>], #+/-<offset_12>\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (U), offset_12);\r
- } else if ((OpCode & 0x03000ff0) == 0x03000000) {\r
- // A5.2.9 [<Rn>], +/-<Rm>\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r
- } else {\r
- // A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>\r
- shift_imm = (OpCode >> 7) & 0x1f;\r
- shift = (OpCode >> 5) & 0x3;\r
-\r
- if (shift == 0x0) {\r
- Type = "LSL";\r
- } else if (shift == 0x1) {\r
- Type = "LSR";\r
- if (shift_imm == 0) {\r
- shift_imm = 32;\r
- }\r
- } else if (shift == 0x12) {\r
- Type = "ASR";\r
- } else if (shift_imm == 0) {\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);\r
- // FIx me\r
- return;\r
- } else {\r
- Type = "ROR";\r
- }\r
- \r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (U), gReg[Rm], Type, shift_imm);\r
- }\r
- }\r
- return; \r
- }\r
- \r
- if ((OpCode & 0x0e000000) == 0x00000000) {\r
- // LDR/STR address mode 3\r
- // LDR|STR{<cond>}H|SH|SB|D <Rd>, <addressing_mode>\r
- if (L) {\r
- if (!S) {\r
- Root = "LDR%aH %a, ";\r
- } else if (!H) {\r
- Root = "LDR%aSB %a, ";\r
- } else {\r
- Root = "LDR%aSH %a, ";\r
- }\r
- } else {\r
- if (!S) {\r
- Root = "STR%aH %a ";\r
- } else if (!H) {\r
- Root = "LDR%aD %a ";\r
- } else {\r
- Root = "STR%aD %a ";\r
- }\r
- }\r
- \r
- Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]); \r
-\r
- S = (OpCode & BIT6) == BIT6;\r
- H = (OpCode & BIT5) == BIT5;\r
- offset_8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;\r
- if (P & !W) {\r
- // Immediate offset/index\r
- if (B) {\r
- // A5.3.2 [<Rn>, #+/-<offset_8>]\r
- // A5.3.4 [<Rn>, #+/-<offset_8>]!\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (U), offset_8, WRITE (W));\r
- } else {\r
- // A5.3.3 [<Rn>, +/-<Rm>]\r
- // A5.3.5 [<Rn>, +/-<Rm>]!\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));\r
- }\r
- } else {\r
- // Register offset/index\r
- if (B) {\r
- // A5.3.6 [<Rn>], #+/-<offset_8>\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (U), offset_8);\r
- } else {\r
- // A5.3.7 [<Rn>], +/-<Rm>\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (U), gReg[Rm]);\r
- }\r
- }\r
- return;\r
- }\r
-\r
- if ((OpCode & 0x0fb000f0) == 0x01000050) {\r
- // A4.1.108 SWP SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r
- // A4.1.109 SWPB SWP{<cond>}B <Rd>, <Rm>, [<Rn>]\r
- AsciiSPrint (Buf, Size, "SWP%a%a %a, %a, [%a]", COND (OpCode), BYTE (B), gReg[Rd], gReg[Rm], gReg[Rn]);\r
- return;\r
- }\r
- \r
- if ((OpCode & 0xfe5f0f00) == 0xf84d0500) {\r
- // A4.1.90 SRS SRS<addressing_mode> #<mode>{!}\r
- AsciiSPrint (Buf, Size, "SRS%a #0x%x%a", gLdmStack[(OpCode >> 23) & 3], OpCode & 0x1f, WRITE (W));\r
- return;\r
- }\r
-\r
- if ((OpCode & 0xfe500f00) == 0xf8100500) {\r
- // A4.1.59 RFE<addressing_mode> <Rn>{!}\r
- AsciiSPrint (Buf, Size, "RFE%a %a", gLdmStack[(OpCode >> 23) & 3], gReg[Rn], WRITE (W));\r
- return;\r
- }\r
- \r
- if ((OpCode & 0xfff000f0) == 0xe1200070) {\r
- // A4.1.7 BKPT <immed_16>\r
- AsciiSPrint (Buf, Size, "BKPT %x", ((OpCode >> 8) | (OpCode & 0xf)) & 0xffff);\r
- return;\r
- } \r
- \r
- if ((OpCode & 0xfff10020) == 0xf1000000) {\r
- // A4.1.16 CPS<effect> <iflags> {, #<mode>}\r
- if (((OpCode >> 6) & 0x7) == 0) {\r
- AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));\r
- } else {\r
- imode = (OpCode >> 18) & 0x3;\r
- Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");\r
- if ((OpCode & BIT17) != 0) {\r
- AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);\r
- }\r
- }\r
- return;\r
- } \r
- \r
- if ((OpCode & 0x0f000000) == 0x0f000000) {\r
- // A4.1.107 SWI{<cond>} <immed_24>\r
- AsciiSPrint (Buf, Size, "SWI%a %x", COND (OpCode), OpCode & 0x00ffffff);\r
- return;\r
- } \r
-\r
- if ((OpCode & 0x0fb00000) == 0x01000000) {\r
- // A4.1.38 MRS{<cond>} <Rd>, CPSR MRS{<cond>} <Rd>, SPSR\r
- AsciiSPrint (Buf, Size, "MRS%a %a, %a", COND (OpCode), gReg[Rd], B ? "SPSR" : "CPSR");\r
- return;\r
- } \r
-\r
-\r
- if ((OpCode & 0x0db00000) == 0x03200000) {\r
- // A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>\r
- if (I) {\r
- // MSR{<cond>} CPSR_<fields>, #<immediate>\r
- 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));\r
- } else {\r
- // MSR{<cond>} CPSR_<fields>, <Rm>\r
- AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), B ? "SPSR" : "CPSR", gReg[Rd]);\r
- }\r
- return;\r
- } \r
-\r
- if ((OpCode & 0xff000010) == 0xfe000000) {\r
- // A4.1.13 CDP{<cond>} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>\r
- 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);\r
- return;\r
- }\r
- \r
- if ((OpCode & 0x0e000000) == 0x0c000000) {\r
- // A4.1.19 LDC and A4.1.96 SDC\r
- if ((OpCode & 0xf0000000) == 0xf0000000) {\r
- Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", L ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);\r
- } else {\r
- Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", L ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);\r
- }\r
- \r
- if (!P) {\r
- if (!W) { \r
- // A5.5.5.5 [<Rn>], <option>\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff); \r
- } else {\r
- // A.5.5.4 [<Rn>], #+/-<offset_8>*4\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (U), OpCode & 0xff); \r
- }\r
- } else {\r
- // A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!\r
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (U), OpCode & 0xff, WRITE (W)); \r
- }\r
- \r
- }\r
- \r
- if ((OpCode & 0x0f000010) == 0x0e000010) {\r
- // A4.1.32 MRC2, MCR2 \r
- 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);\r
- return; \r
- }\r
-\r
- if ((OpCode & 0x0ff00000) == 0x0c400000) {\r
- // A4.1.33 MRRC2, MCRR2 \r
- 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);\r
- return; \r
- }\r
-\r
- AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);\r
- return;\r
-}\r
-\r
#include <Library/BaseLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/ArmDisassemblerLib.h>\r
\r
#include <Guid/DebugImageInfoTable.h>\r
#include <Protocol/DebugSupport.h>\r
#include <Protocol/LoadedImage.h>\r
\r
\r
-VOID\r
-DisassembleArmInstruction (\r
- IN UINT32 *OpCodePtr,\r
- OUT CHAR8 *Buf,\r
- OUT UINTN Size\r
- );\r
-\r
-VOID\r
-DisassembleThumbInstruction (\r
- IN UINT16 *OpCodePtr,\r
- OUT CHAR8 *Buf,\r
- OUT UINTN Size\r
- );\r
-\r
-\r
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;\r
\r
\r
UINT32 Offset;\r
CHAR8 CpsrStr[32]; // char per bit. Lower 5-bits are mode that is a 3 char string\r
CHAR8 Buffer[80];\r
+ UINT8 *DisAsm;\r
\r
CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);\r
DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));\r
DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));\r
\r
// If we come from an image it is safe to show the instruction. We know it should not fault\r
- if ((SystemContext.SystemContextArm->CPSR & 0x20) == 0) {\r
- // ARM\r
- DisassembleArmInstruction ((UINT32 *)(UINTN)SystemContext.SystemContextArm->PC, Buffer, sizeof (Buffer));\r
- DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
- } else {\r
- // Thumb\r
- DisassembleThumbInstruction ((UINT16 *)(UINTN)SystemContext.SystemContextArm->PC, Buffer, sizeof (Buffer));\r
- DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
- }\r
+ DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;\r
+ DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, Buffer, sizeof (Buffer));\r
+ DEBUG ((EFI_D_ERROR, "\n%a", Buffer));\r
+\r
}\r
DEBUG_CODE_END ();\r
DEBUG ((EFI_D_ERROR, "\n R0 0x%08x R1 0x%08x R2 0x%08x R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));\r
\r
[Defines]\r
INF_VERSION = 0x00010005\r
- BASE_NAME = SemiHostingSerialPortLib\r
+ BASE_NAME = DefaultExceptionHandlerLib\r
FILE_GUID = EACDB354-DF1A-4AF9-A171-499737ED818F\r
MODULE_TYPE = UEFI_DRIVER\r
VERSION_STRING = 1.0\r
\r
[Sources.common]\r
DefaultExceptionHandler.c\r
- ArmDisassembler.c\r
- ThumbDisassembler.c\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
PrintLib\r
DebugLib\r
PeCoffGetEntryPointLib\r
+ ArmDisassemblerLib\r
\r
\r
+++ /dev/null
-/** @file\r
- Default exception handler\r
-\r
- Copyright (c) 2008-2010, Apple Inc. All rights reserved.\r
- \r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Base.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/PrintLib.h>\r
-\r
-extern CHAR8 *gReg[];\r
-\r
-#define LOAD_STORE_FORMAT1 1\r
-#define LOAD_STORE_FORMAT2 2\r
-#define LOAD_STORE_FORMAT3 3\r
-#define LOAD_STORE_FORMAT4 4\r
-#define LOAD_STORE_MULTIPLE_FORMAT1 5 \r
-#define LOAD_STORE_MULTIPLE_FORMAT2 6 \r
-#define IMMED_8 7\r
-#define CONDITIONAL_BRANCH 8\r
-#define UNCONDITIONAL_BRANCH 9\r
-#define UNCONDITIONAL_BRANCH_SHORT 109\r
-#define BRANCH_EXCHANGE 10\r
-#define DATA_FORMAT1 11\r
-#define DATA_FORMAT2 12\r
-#define DATA_FORMAT3 13\r
-#define DATA_FORMAT4 14\r
-#define DATA_FORMAT5 15\r
-#define DATA_FORMAT6_SP 16\r
-#define DATA_FORMAT6_PC 116\r
-#define DATA_FORMAT7 17\r
-#define DATA_FORMAT8 19\r
-#define CPS_FORMAT 20\r
-#define ENDIAN_FORMAT 21\r
- \r
-\r
-typedef struct {\r
- CHAR8 *Start;\r
- UINT32 OpCode;\r
- UINT32 Mask;\r
- UINT32 AddressMode;\r
-} THUMB_INSTRUCTIONS;\r
-\r
-THUMB_INSTRUCTIONS gOp[] = {\r
-// Thumb 16-bit instrucitons\r
-// Op Mask Format\r
- { "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },\r
-\r
- { "ADD" , 0x1c00, 0xfe00, DATA_FORMAT2 },\r
- { "ADD" , 0x3000, 0xf800, DATA_FORMAT3 },\r
- { "ADD" , 0x1800, 0xfe00, DATA_FORMAT1 },\r
- { "ADD" , 0x4400, 0xff00, DATA_FORMAT8 }, // A8.6.9\r
- { "ADD" , 0xa000, 0xf100, DATA_FORMAT6_PC },\r
- { "ADD" , 0xa100, 0xf100, DATA_FORMAT6_SP }, \r
- { "ADD" , 0xb000, 0xff10, DATA_FORMAT7 },\r
-\r
- { "AND" , 0x4000, 0xffc0, DATA_FORMAT5 },\r
-\r
- { "ASR" , 0x1000, 0xf800, DATA_FORMAT4 },\r
- { "ASR" , 0x4100, 0xffc0, DATA_FORMAT5 },\r
-\r
- { "B" , 0xd000, 0xf000, CONDITIONAL_BRANCH },\r
- { "B" , 0xe000, 0xf100, UNCONDITIONAL_BRANCH_SHORT },\r
- { "BL" , 0xf100, 0xf100, UNCONDITIONAL_BRANCH },\r
- { "BLX" , 0xe100, 0xf100, UNCONDITIONAL_BRANCH },\r
- { "BLX" , 0x4780, 0xff80, BRANCH_EXCHANGE },\r
- { "BX" , 0x4700, 0xff80, BRANCH_EXCHANGE },\r
-\r
- { "BIC" , 0x4380, 0xffc0, DATA_FORMAT5 },\r
- { "BKPT", 0xdf00, 0xff00, IMMED_8 },\r
- { "CMN" , 0x42c0, 0xffc0, DATA_FORMAT5 },\r
-\r
- { "CMP" , 0x2800, 0xf100, DATA_FORMAT3 },\r
- { "CMP" , 0x4280, 0xffc0, DATA_FORMAT5 },\r
- { "CMP" , 0x4500, 0xff00, DATA_FORMAT8 },\r
-\r
- { "CPS" , 0xb660, 0xffe8, CPS_FORMAT },\r
- { "CPY" , 0x4600, 0xff00, DATA_FORMAT8 },\r
- { "EOR" , 0x4040, 0xffc0, DATA_FORMAT5 },\r
-\r
- { "LDMIA" , 0xc800, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
- { "LDR" , 0x6800, 0xf800, LOAD_STORE_FORMAT1 },\r
- { "LDR" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
- { "LDR" , 0x4800, 0xf800, LOAD_STORE_FORMAT3 },\r
- { "LDR" , 0x9800, 0xf800, LOAD_STORE_FORMAT4 },\r
- { "LDRB" , 0x7800, 0xf800, LOAD_STORE_FORMAT1 },\r
- { "LDRB" , 0x5c00, 0xfe00, LOAD_STORE_FORMAT2 },\r
- { "LDRH" , 0x8800, 0xf800, LOAD_STORE_FORMAT1 },\r
- { "LDRH" , 0x7a00, 0xfe00, LOAD_STORE_FORMAT2 },\r
- { "LDRSB" , 0x5600, 0xfe00, LOAD_STORE_FORMAT2 },\r
- { "LDRSH" , 0x5e00, 0xfe00, LOAD_STORE_FORMAT2 },\r
- \r
- { "LSL" , 0x0000, 0xf800, DATA_FORMAT4 },\r
- { "LSL" , 0x4080, 0xffc0, DATA_FORMAT5 },\r
- { "LSR" , 0x0001, 0xf800, DATA_FORMAT4 },\r
- { "LSR" , 0x40c0, 0xffc0, DATA_FORMAT5 },\r
-\r
- { "MOV" , 0x2000, 0xf800, DATA_FORMAT3 },\r
- { "MOV" , 0x1c00, 0xffc0, DATA_FORMAT3 },\r
- { "MOV" , 0x4600, 0xff00, DATA_FORMAT8 },\r
-\r
- { "MUL" , 0x4340, 0xffc0, DATA_FORMAT5 },\r
- { "MVN" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
- { "NEG" , 0x4240, 0xffc0, DATA_FORMAT5 },\r
- { "ORR" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
- { "POP" , 0xbc00, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r
- { "POP" , 0xe400, 0xfe00, LOAD_STORE_MULTIPLE_FORMAT2 },\r
- \r
- { "REV" , 0xba00, 0xffc0, DATA_FORMAT5 },\r
- { "REV16" , 0xba40, 0xffc0, DATA_FORMAT5 },\r
- { "REVSH" , 0xbac0, 0xffc0, DATA_FORMAT5 },\r
-\r
- { "ROR" , 0x41c0, 0xffc0, DATA_FORMAT5 },\r
- { "SBC" , 0x4180, 0xffc0, DATA_FORMAT5 },\r
- { "SETEND" , 0xb650, 0xfff0, ENDIAN_FORMAT },\r
-\r
- { "STMIA" , 0xc000, 0xf800, LOAD_STORE_MULTIPLE_FORMAT1 },\r
- { "STR" , 0x6000, 0xf800, LOAD_STORE_FORMAT1 },\r
- { "STR" , 0x5000, 0xfe00, LOAD_STORE_FORMAT2 },\r
- { "STR" , 0x4000, 0xf800, LOAD_STORE_FORMAT3 },\r
- { "STR" , 0x9000, 0xf800, LOAD_STORE_FORMAT4 },\r
- { "STRB" , 0x7000, 0xf800, LOAD_STORE_FORMAT1 },\r
- { "STRB" , 0x5800, 0xfe00, LOAD_STORE_FORMAT2 },\r
- { "STRH" , 0x8000, 0xf800, LOAD_STORE_FORMAT1 },\r
- { "STRH" , 0x5200, 0xfe00, LOAD_STORE_FORMAT2 },\r
-\r
- { "SUB" , 0x1e00, 0xfe00, DATA_FORMAT2 },\r
- { "SUB" , 0x3800, 0xf800, DATA_FORMAT3 },\r
- { "SUB" , 0x1a00, 0xfe00, DATA_FORMAT1 },\r
- { "SUB" , 0xb080, 0xff80, DATA_FORMAT7 },\r
-\r
- { "SWI" , 0xdf00, 0xff00, IMMED_8 },\r
- { "SXTB", 0xb240, 0xffc0, DATA_FORMAT5 },\r
- { "SXTH", 0xb200, 0xffc0, DATA_FORMAT5 },\r
- { "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },\r
- { "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },\r
- { "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }\r
- \r
-#if 0 \r
- ,\r
- \r
- // 32-bit Thumb instructions op1 01\r
- \r
- // 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx Load/store multiple\r
- { "SRSDB", 0xe80dc000, 0xffdffff0, SRS_FORMAT }, // SRSDB<c> SP{!},#<mode>\r
- { "SRS" , 0xe98dc000, 0xffdffff0, SRS_IA_FORMAT }, // SRS{IA}<c> SP{!},#<mode>\r
- { "RFEDB", 0xe810c000, 0xffd0ffff, RFE_FORMAT }, // RFEDB<c> <Rn>{!}\r
- { "RFE" , 0xe990c000, 0xffd0ffff, RFE_IA_FORMAT }, // RFE{IA}<c> <Rn>{!}\r
- \r
- { "STM" , 0xe8800000, 0xffd00000, STM_FORMAT }, // STM<c>.W <Rn>{!},<registers>\r
- { "LDM" , 0xe8900000, 0xffd00000, STM_FORMAT }, // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r
- { "POP" , 0xe8bd0000, 0xffff2000, REGLIST_FORMAT }, // POP<c>.W <registers> >1 register\r
- { "POP" , 0xf85d0b04, 0xffff0fff, RT_FORMAT }, // POP<c>.W <registers> 1 register\r
-\r
- { "STMDB", 0xe9000000, 0xffd00000, STM_FORMAT }, // STMDB\r
- { "PUSH" , 0xe8bd0000, 0xffffa000, REGLIST_FORMAT }, // PUSH<c>.W <registers> >1 register\r
- { "PUSH" , 0xf84d0b04, 0xffff0fff, RT_FORMAT }, // PUSH<c>.W <registers> 1 register\r
- { "LDMDB", 0xe9102000, 0xffd02000, STM_FORMAT }, // LDMDB<c> <Rn>{!},<registers>\r
-\r
- // 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx Load/store dual,\r
- { "STREX" , 0xe0400000, 0xfff000f0, 3REG_IMM8_FORMAT }, // STREX<c> <Rd>,<Rt>,[<Rn>{,#<imm>}]\r
- { "STREXB", 0xe8c00f40, 0xfff00ff0, 3REG_FORMAT }, // STREXB<c> <Rd>,<Rt>,[<Rn>]\r
- { "STREXD", 0xe8c00070, 0xfff000f0, 4REG_FORMAT }, // STREXD<c> <Rd>,<Rt>,<Rt2>,[<Rn>]\r
- { "STREXH", 0xe8c00f70, 0xfff00ff0, 3REG_FORMAT }, // STREXH<c> <Rd>,<Rt>,[<Rn>]\r
- { "STRH", 0xf8c00000, 0xfff00000, 2REG_IMM8_FORMAT }, // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]\r
- { "STRH", 0xf8200000, 0xfff00000, }, // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]\r
-\r
-\r
-\r
- // 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx Data-processing\r
- // 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor\r
- \r
- // 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing modified immediate\r
- // 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx Data-processing plain immediate\r
- // 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx Branches\r
- \r
- // 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx Store single data item\r
- // 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx SIMD or load/store\r
- // 1111 100x x001 xxxx xxxx xxxx xxxx xxxx Load byte, memory hints \r
- // 1111 100x x011 xxxx xxxx xxxx xxxx xxxx Load halfword, memory hints\r
- // 1111 100x x101 xxxx xxxx xxxx xxxx xxxx Load word \r
-\r
- // 1111 1 010 xxxx xxxx xxxx xxxx xxxx xxxx Data-processing register\r
- // 1111 1 011 0xxx xxxx xxxx xxxx xxxx xxxx Multiply\r
- // 1111 1 011 1xxx xxxx xxxx xxxx xxxx xxxx Long Multiply\r
- // 1111 1 1xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor \r
-#endif\r
-};\r
-\r
-\r
-CHAR8 mThumbMregListStr[4*15 + 1];\r
-\r
-CHAR8 *\r
-ThumbMRegList (\r
- UINT32 OpCode\r
- )\r
-{\r
- UINTN Index, Start, End;\r
- CHAR8 *Str;\r
- BOOLEAN First;\r
- \r
- Str = mThumbMregListStr;\r
- *Str = '\0';\r
- AsciiStrCat (Str, "{");\r
- // R0 - R7, PC\r
- for (Index = 0, First = TRUE; Index <= 9; Index++) {\r
- if ((OpCode & (1 << Index)) != 0) {\r
- Start = End = Index;\r
- for (Index++; ((OpCode & (1 << Index)) != 0) && (Index <= 9); Index++) {\r
- End = Index;\r
- }\r
- \r
- if (!First) {\r
- AsciiStrCat (Str, ",");\r
- } else {\r
- First = FALSE;\r
- }\r
- \r
- if (Start == End) {\r
- AsciiStrCat (Str, gReg[(Start == 9)?15:Start]);\r
- AsciiStrCat (Str, ", ");\r
- } else {\r
- AsciiStrCat (Str, gReg[Start]);\r
- AsciiStrCat (Str, "-");\r
- AsciiStrCat (Str, gReg[(End == 9)?15:End]);\r
- }\r
- }\r
- }\r
- if (First) {\r
- AsciiStrCat (Str, "ERROR");\r
- }\r
- AsciiStrCat (Str, "}");\r
- \r
- // BugBug: Make caller pass in buffer it is cleaner\r
- return mThumbMregListStr;\r
-}\r
-\r
-UINT32\r
-SignExtend (\r
- IN UINT32 Data\r
- )\r
-{\r
- return 0;\r
-}\r
-\r
-/**\r
- DEBUG print the faulting instruction. We cheat and only decode instructions that access \r
- memory. If the instruction is not found we dump the instruction in hex.\r
- \r
- @param Insturction ARM instruction to disassemble. \r
- \r
-**/\r
-VOID\r
-DisassembleThumbInstruction (\r
- IN UINT16 *OpCodePtr,\r
- OUT CHAR8 *Buf,\r
- OUT UINTN Size\r
- )\r
-{\r
- UINT16 OpCode = *OpCodePtr;\r
- UINT32 Index;\r
- UINT32 Offset;\r
- UINT16 Rd, Rn, Rm;\r
- INT32 target_addr;\r
- BOOLEAN H1, H2, imod;\r
- UINT32 PC;\r
-\r
- // These register names match branch form, but not others\r
- Rd = OpCode & 0x7;\r
- Rn = (OpCode >> 3) & 0x7;\r
- Rm = (OpCode >> 6) & 0x7;\r
- H1 = (OpCode & BIT7) != 0;\r
- H2 = (OpCode & BIT6) != 0;\r
- imod = (OpCode & BIT4) != 0;\r
- PC = (UINT32)(UINTN)*OpCodePtr;\r
-\r
- for (Index = 0; Index < sizeof (gOp)/sizeof (THUMB_INSTRUCTIONS); Index++) {\r
- if ((OpCode & gOp[Index].Mask) == gOp[Index].OpCode) {\r
- Offset = AsciiSPrint (Buf, Size, "%a", gOp[Index].Start); \r
- switch (gOp[Index].AddressMode) {\r
- case LOAD_STORE_FORMAT1:\r
- // A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, (OpCode >> 7) & 7, (OpCode >> 6) & 0x1f); \r
- break;\r
- case LOAD_STORE_FORMAT2:\r
- // A6.5.1 <Rd>, [<Rn>, <Rm>]\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d, r%d]", Rd, (OpCode >> 3) & 7, Rm); \r
- break;\r
- case LOAD_STORE_FORMAT3:\r
- // A6.5.1 <Rd>, [PC, #<8_bit_offset>]\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [pc, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff); \r
- break;\r
- case LOAD_STORE_FORMAT4:\r
- // FIX ME!!!!!\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [sp, #0x%x]", (OpCode >> 8) & 7, OpCode & 0xff); \r
- break;\r
- \r
- case LOAD_STORE_MULTIPLE_FORMAT1:\r
- // <Rn>!, <registers> \r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (!BIT8 & OpCode)); \r
- break;\r
- case LOAD_STORE_MULTIPLE_FORMAT2:\r
- // <Rn>!, <registers> \r
- // BIT8 is PC \r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d!, %a", (OpCode >> 8) & 7, ThumbMRegList (OpCode)); \r
- break;\r
- \r
- case IMMED_8:\r
- // A6.7 <immed_8>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%x", OpCode & 0xff); \r
- break;\r
-\r
- case CONDITIONAL_BRANCH:\r
- // A6.3.1 B<cond> <target_address>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, "%a 0x%04x", PC + 4 + SignExtend ((OpCode & 0xff) << 1)); \r
- break;\r
- case UNCONDITIONAL_BRANCH_SHORT:\r
- // A6.3.2 B <target_address>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 4 + SignExtend ((OpCode & 0x3ff) << 1)); \r
- break;\r
- case UNCONDITIONAL_BRANCH:\r
- // A6.3.2 BL|BLX <target_address> ; Produces two 16-bit instructions \r
- target_addr = *(OpCodePtr - 1);\r
- if ((target_addr & 0xf800) == 0xf000) {\r
- target_addr = ((target_addr & 0x3ff) << 12) | (OpCode & 0x3ff);\r
- } else {\r
- target_addr = OpCode & 0x3ff;\r
- }\r
- // PC + 2 +/- target_addr\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " 0x%04x", PC + 2 + SignExtend (target_addr)); \r
- break;\r
- case BRANCH_EXCHANGE:\r
- // A6.3.3 BX|BLX <Rm>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d", gReg[Rn | (H2 ? 8:0)]); \r
- break;\r
-\r
- case DATA_FORMAT1:\r
- // A6.4.3 <Rd>, <Rn>, <Rm>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, r%d", Rd, Rn, Rm); \r
- break;\r
- case DATA_FORMAT2:\r
- // A6.4.3 <Rd>, <Rn>, #3_bit_immed\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rd, Rn, Rm); \r
- break;\r
- case DATA_FORMAT3:\r
- // A6.4.3 <Rd>|<Rn>, #8_bit_immed\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", (OpCode >> 8) & 0x7, OpCode & 0xff); \r
- break;\r
- case DATA_FORMAT4:\r
- // A6.4.3 <Rd>|<Rm>, #immed_5\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d, 0x%x", Rn, Rd, (OpCode >> 6) & 0x1f); \r
- break;\r
- case DATA_FORMAT5:\r
- // A6.4.3 <Rd>|<Rm>, <Rm>|<Rs>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, r%d", Rd, Rn); \r
- break;\r
- case DATA_FORMAT6_SP:\r
- // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, sp, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff); \r
- break;\r
- case DATA_FORMAT6_PC:\r
- // A6.4.3 <Rd>, <reg>, #<8_Bit_immed>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, pc, 0x%x", (OpCode >> 8) & 7, OpCode & 0xff); \r
- break;\r
- case DATA_FORMAT7:\r
- // A6.4.3 SP, SP, #<7_Bit_immed>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " sp, sp 0x%x", (OpCode & 0x7f)*4); \r
- break;\r
- case DATA_FORMAT8:\r
- // A6.4.3 <Rd>|<Rn>, <Rm>\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " %a, %a", gReg[Rd | (H1 ? 8:0)], gReg[Rn | (H2 ? 8:0)]); \r
- break;\r
- \r
- case CPS_FORMAT:\r
- // A7.1.24\r
- AsciiSPrint (&Buf[Offset], Size - Offset, "%a %a%a%a", imod ? "ID":"IE", ((OpCode & BIT2) == 0) ? "":"a", ((OpCode & BIT1) == 0) ? "":"i", ((OpCode & BIT0) == 0) ? "":"f"); \r
- break;\r
-\r
- case ENDIAN_FORMAT:\r
- // A7.1.24\r
- AsciiSPrint (&Buf[Offset], Size - Offset, " %a", (OpCode & BIT3) == 0 ? "LE":"BE"); \r
- break;\r
- }\r
- }\r
- }\r
- \r
-\r
-}\r
-\r
- \r
EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
GdbSerialLib|Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
+ ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
[LibraryClasses.common.SEC]