summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c')
-rw-r--r--ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c150
1 files changed, 79 insertions, 71 deletions
diff --git a/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
index 03a9f1fbe2..0e09062957 100644
--- a/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
+++ b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c
@@ -13,7 +13,7 @@
#include <Library/PrintLib.h>
#include <Library/ArmDisassemblerLib.h>
-CHAR8 *gCondition[] = {
+CHAR8 *gCondition[] = {
"EQ",
"NE",
"CS",
@@ -34,7 +34,7 @@ CHAR8 *gCondition[] = {
#define COND(_a) gCondition[((_a) >> 28)]
-CHAR8 *gReg[] = {
+CHAR8 *gReg[] = {
"r0",
"r1",
"r2",
@@ -53,37 +53,36 @@ CHAR8 *gReg[] = {
"pc"
};
-CHAR8 *gLdmAdr[] = {
+CHAR8 *gLdmAdr[] = {
"DA",
"IA",
"DB",
"IB"
};
-CHAR8 *gLdmStack[] = {
+CHAR8 *gLdmStack[] = {
"FA",
"FD",
"EA",
"ED"
};
-#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
+#define LDM_EXT(_reg, _off) ((_reg == 13) ? gLdmStack[(_off)] : gLdmAdr[(_off)])
+#define SIGN(_U) ((_U) ? "" : "-")
+#define WRITE(_Write) ((_Write) ? "!" : "")
+#define BYTE(_B) ((_B) ? "B":"")
+#define USER(_B) ((_B) ? "^" : "")
-#define SIGN(_U) ((_U) ? "" : "-")
-#define WRITE(_Write) ((_Write) ? "!" : "")
-#define BYTE(_B) ((_B) ? "B":"")
-#define USER(_B) ((_B) ? "^" : "")
-
-CHAR8 mMregListStr[4*15 + 1];
+CHAR8 mMregListStr[4*15 + 1];
CHAR8 *
MRegList (
UINT32 OpCode
)
{
- UINTN Index, Start, End;
- BOOLEAN First;
+ UINTN Index, Start, End;
+ BOOLEAN First;
mMregListStr[0] = '\0';
AsciiStrCatS (mMregListStr, sizeof mMregListStr, "{");
@@ -110,9 +109,11 @@ MRegList (
}
}
}
+
if (First) {
AsciiStrCatS (mMregListStr, sizeof mMregListStr, "ERROR");
}
+
AsciiStrCatS (mMregListStr, sizeof mMregListStr, "}");
// BugBug: Make caller pass in buffer it is cleaner
@@ -129,14 +130,13 @@ FieldMask (
UINT32
RotateRight (
- IN UINT32 Op,
- IN UINT32 Shift
+ IN UINT32 Op,
+ IN UINT32 Shift
)
{
return (Op >> Shift) | (Op << (32 - Shift));
}
-
/**
Place a disassembly of **OpCodePtr into buffer, and update OpCodePtr to
point to next instruction.
@@ -152,39 +152,38 @@ RotateRight (
**/
VOID
DisassembleArmInstruction (
- IN UINT32 **OpCodePtr,
- OUT CHAR8 *Buf,
- OUT UINTN Size,
- IN BOOLEAN Extended
+ IN UINT32 **OpCodePtr,
+ OUT CHAR8 *Buf,
+ OUT UINTN Size,
+ IN BOOLEAN Extended
)
{
- UINT32 OpCode;
- CHAR8 *Type;
- CHAR8 *Root;
- BOOLEAN Imm, Pre, Up, WriteBack, Write, Load, Sign, Half;
- UINT32 Rn, Rd, Rm;
- UINT32 IMod, Offset8, Offset12;
- UINT32 Index;
- UINT32 ShiftImm, Shift;
+ UINT32 OpCode;
+ CHAR8 *Type;
+ CHAR8 *Root;
+ BOOLEAN Imm, Pre, Up, WriteBack, Write, Load, Sign, Half;
+ UINT32 Rn, Rd, Rm;
+ UINT32 IMod, Offset8, Offset12;
+ UINT32 Index;
+ UINT32 ShiftImm, Shift;
OpCode = **OpCodePtr;
- Imm = (OpCode & BIT25) == BIT25; // I
- Pre = (OpCode & BIT24) == BIT24; // P
- Up = (OpCode & BIT23) == BIT23; // U
+ Imm = (OpCode & BIT25) == BIT25; // I
+ Pre = (OpCode & BIT24) == BIT24; // P
+ Up = (OpCode & BIT23) == BIT23; // U
WriteBack = (OpCode & BIT22) == BIT22; // B, also called S
- Write = (OpCode & BIT21) == BIT21; // W
- Load = (OpCode & BIT20) == BIT20; // L
- Sign = (OpCode & BIT6) == BIT6; // S
- Half = (OpCode & BIT5) == BIT5; // H
- Rn = (OpCode >> 16) & 0xf;
- Rd = (OpCode >> 12) & 0xf;
- Rm = (OpCode & 0xf);
-
+ Write = (OpCode & BIT21) == BIT21; // W
+ Load = (OpCode & BIT20) == BIT20; // L
+ Sign = (OpCode & BIT6) == BIT6; // S
+ Half = (OpCode & BIT5) == BIT5; // H
+ Rn = (OpCode >> 16) & 0xf;
+ Rd = (OpCode >> 12) & 0xf;
+ Rm = (OpCode & 0xf);
if (Extended) {
Index = AsciiSPrint (Buf, Size, "0x%08x ", OpCode);
- Buf += Index;
+ Buf += Index;
Size -= Index;
}
@@ -194,9 +193,10 @@ DisassembleArmInstruction (
// A4.1.27 LDREX{<cond>} <Rd>, [<Rn>]
AsciiSPrint (Buf, Size, "LDREX%a %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn]);
} else {
- // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
+ // A4.1.103 STREX{<cond>} <Rd>, <Rm>, [<Rn>]
AsciiSPrint (Buf, Size, "STREX%a %a, %a, [%a]", COND (OpCode), gReg[Rd], gReg[Rn], gReg[Rn]);
}
+
return;
}
@@ -206,23 +206,25 @@ DisassembleArmInstruction (
// A4.1.20 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers>
// A4.1.21 LDM{<cond>}<addressing_mode> <Rn>, <registers_without_pc>^
// A4.1.22 LDM{<cond>}<addressing_mode> <Rn>{!}, <registers_and_pc>^
- AsciiSPrint (Buf, Size, "LDM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (Write), MRegList (OpCode), USER (WriteBack));
+ AsciiSPrint (Buf, Size, "LDM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn, (OpCode >> 23) & 3), gReg[Rn], WRITE (Write), MRegList (OpCode), USER (WriteBack));
} else {
// A4.1.97 STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
// A4.1.98 STM{<cond>}<addressing_mode> <Rn>, <registers>^
- AsciiSPrint (Buf, Size, "STM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn ,(OpCode >> 23) & 3), gReg[Rn], WRITE (Write), MRegList (OpCode), USER (WriteBack));
+ AsciiSPrint (Buf, Size, "STM%a%a, %a%a, %a", COND (OpCode), LDM_EXT (Rn, (OpCode >> 23) & 3), gReg[Rn], WRITE (Write), MRegList (OpCode), USER (WriteBack));
}
+
return;
}
// LDR/STR Address Mode 2
- if ( ((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000 ) == 0xf550f000) ) {
+ if (((OpCode & 0x0c000000) == 0x04000000) || ((OpCode & 0xfd70f000) == 0xf550f000)) {
Offset12 = OpCode & 0xfff;
- if ((OpCode & 0xfd70f000 ) == 0xf550f000) {
+ if ((OpCode & 0xfd70f000) == 0xf550f000) {
Index = AsciiSPrint (Buf, Size, "PLD");
} else {
- Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", Load ? "LDR" : "STR", COND (OpCode), BYTE (WriteBack), (!(Pre) && Write) ? "T":"", gReg[Rd]);
+ Index = AsciiSPrint (Buf, Size, "%a%a%a%a %a, ", Load ? "LDR" : "STR", COND (OpCode), BYTE (WriteBack), (!(Pre) && Write) ? "T" : "", gReg[Rd]);
}
+
if (Pre) {
if (!Imm) {
// A5.2.2 [<Rn>, #+/-<offset_12>]
@@ -236,7 +238,7 @@ DisassembleArmInstruction (
// A5.2.4 [<Rn>, +/-<Rm>, LSL #<shift_imm>]
// A5.2.7 [<Rn>, +/-<Rm>, LSL #<shift_imm>]!
ShiftImm = (OpCode >> 7) & 0x1f;
- Shift = (OpCode >> 5) & 0x3;
+ Shift = (OpCode >> 5) & 0x3;
if (Shift == 0x0) {
Type = "LSL";
} else if (Shift == 0x1) {
@@ -255,7 +257,8 @@ DisassembleArmInstruction (
AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, #%d]%a", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm, WRITE (Write));
}
- } else { // !Pre
+ } else {
+ // !Pre
if (!Imm) {
// A5.2.8 [<Rn>], #+/-<offset_12>
AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x", gReg[Rn], SIGN (Up), Offset12);
@@ -265,7 +268,7 @@ DisassembleArmInstruction (
} else {
// A5.2.10 [<Rn>], +/-<Rm>, LSL #<shift_imm>
ShiftImm = (OpCode >> 7) & 0x1f;
- Shift = (OpCode >> 5) & 0x3;
+ Shift = (OpCode >> 5) & 0x3;
if (Shift == 0x0) {
Type = "LSL";
@@ -287,6 +290,7 @@ DisassembleArmInstruction (
AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, #%d", gReg[Rn], SIGN (Up), gReg[Rm], Type, ShiftImm);
}
}
+
return;
}
@@ -313,30 +317,31 @@ DisassembleArmInstruction (
Index = AsciiSPrint (Buf, Size, Root, COND (OpCode), gReg[Rd]);
- Sign = (OpCode & BIT6) == BIT6;
- Half = (OpCode & BIT5) == BIT5;
+ Sign = (OpCode & BIT6) == BIT6;
+ Half = (OpCode & BIT5) == BIT5;
Offset8 = ((OpCode >> 4) | (OpCode * 0xf)) & 0xff;
if (Pre & !Write) {
// Immediate offset/index
if (WriteBack) {
// A5.3.2 [<Rn>, #+/-<offset_8>]
// A5.3.4 [<Rn>, #+/-<offset_8>]!
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (Up), Offset8, WRITE (Write));
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%d]%a", gReg[Rn], SIGN (Up), Offset8, WRITE (Write));
} else {
// A5.3.3 [<Rn>, +/-<Rm>]
// A5.3.5 [<Rn>, +/-<Rm>]!
- AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%]a", gReg[Rn], SIGN (Up), gReg[Rm], WRITE (Write));
}
} else {
// Register offset/index
if (WriteBack) {
// A5.3.6 [<Rn>], #+/-<offset_8>
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (Up), Offset8);
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%d", gReg[Rn], SIGN (Up), Offset8);
} else {
// A5.3.7 [<Rn>], +/-<Rm>
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a", gReg[Rn], SIGN (Up), gReg[Rm]);
}
}
+
return;
}
@@ -370,16 +375,21 @@ DisassembleArmInstruction (
if (((OpCode >> 6) & 0x7) == 0) {
AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));
} else {
- IMod = (OpCode >> 18) & 0x3;
- Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a",
- (IMod == 3) ? "ID":"IE",
- ((OpCode & BIT8) != 0) ? "A":"",
- ((OpCode & BIT7) != 0) ? "I":"",
- ((OpCode & BIT6) != 0) ? "F":"");
+ IMod = (OpCode >> 18) & 0x3;
+ Index = AsciiSPrint (
+ Buf,
+ Size,
+ "CPS%a %a%a%a",
+ (IMod == 3) ? "ID" : "IE",
+ ((OpCode & BIT8) != 0) ? "A" : "",
+ ((OpCode & BIT7) != 0) ? "I" : "",
+ ((OpCode & BIT6) != 0) ? "F" : ""
+ );
if ((OpCode & BIT17) != 0) {
AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);
}
}
+
return;
}
@@ -395,16 +405,16 @@ DisassembleArmInstruction (
return;
}
-
if ((OpCode & 0x0db00000) == 0x01200000) {
// A4.1.38 MSR{<cond>} CPSR_<fields>, #<immediate> MSR{<cond>} CPSR_<fields>, <Rm>
if (Imm) {
// MSR{<cond>} CPSR_<fields>, #<immediate>
- AsciiSPrint (Buf, Size, "MRS%a %a_%a, #0x%x", COND (OpCode), WriteBack ? "SPSR" : "CPSR", FieldMask ((OpCode >> 16) & 0xf), RotateRight (OpCode & 0xf, ((OpCode >> 8) & 0xf) *2));
+ AsciiSPrint (Buf, Size, "MRS%a %a_%a, #0x%x", COND (OpCode), WriteBack ? "SPSR" : "CPSR", FieldMask ((OpCode >> 16) & 0xf), RotateRight (OpCode & 0xf, ((OpCode >> 8) & 0xf) *2));
} else {
// MSR{<cond>} CPSR_<fields>, <Rm>
AsciiSPrint (Buf, Size, "MRS%a %a_%a, %a", COND (OpCode), WriteBack ? "SPSR" : "CPSR", gReg[Rd]);
}
+
return;
}
@@ -417,35 +427,34 @@ DisassembleArmInstruction (
if ((OpCode & 0x0e000000) == 0x0c000000) {
// A4.1.19 LDC and A4.1.96 SDC
if ((OpCode & 0xf0000000) == 0xf0000000) {
- Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", Load ? "LDC":"SDC", (OpCode >> 8) & 0xf, Rd);
+ Index = AsciiSPrint (Buf, Size, "%a2 0x%x, CR%d, ", Load ? "LDC" : "SDC", (OpCode >> 8) & 0xf, Rd);
} else {
- Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", Load ? "LDC":"SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);
+ Index = AsciiSPrint (Buf, Size, "%a%a 0x%x, CR%d, ", Load ? "LDC" : "SDC", COND (OpCode), (OpCode >> 8) & 0xf, Rd);
}
if (!Pre) {
if (!Write) {
// A5.5.5.5 [<Rn>], <option>
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff);
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], {0x%x}", gReg[Rn], OpCode & 0xff);
} else {
// A.5.5.4 [<Rn>], #+/-<offset_8>*4
- AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (Up), OpCode & 0xff);
+ AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a0x%x*4", gReg[Rn], SIGN (Up), OpCode & 0xff);
}
} else {
// A5.5.5.2 [<Rn>, #+/-<offset_8>*4 ]!
AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a0x%x*4]%a", gReg[Rn], SIGN (Up), OpCode & 0xff, WRITE (Write));
}
-
}
if ((OpCode & 0x0f000010) == 0x0e000010) {
// A4.1.32 MRC2, MCR2
- AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, CR%d, CR%d, 0x%x", Load ? "MRC":"MCR", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], Rn, Rm, (OpCode >> 5) &0x7);
+ AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, CR%d, CR%d, 0x%x", Load ? "MRC" : "MCR", COND (OpCode), (OpCode >> 8) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], Rn, Rm, (OpCode >> 5) &0x7);
return;
}
if ((OpCode & 0x0ff00000) == 0x0c400000) {
// A4.1.33 MRRC2, MCRR2
- AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, %a, CR%d", Load ? "MRRC":"MCRR", COND (OpCode), (OpCode >> 4) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], gReg[Rn], Rm);
+ AsciiSPrint (Buf, Size, "%a%a 0x%x, 0x%x, %a, %a, CR%d", Load ? "MRRC" : "MCRR", COND (OpCode), (OpCode >> 4) & 0xf, (OpCode >> 20) & 0xf, gReg[Rd], gReg[Rn], Rm);
return;
}
@@ -454,4 +463,3 @@ DisassembleArmInstruction (
*OpCodePtr += 1;
return;
}
-