blob: 52800f7fd145e62e7f1cc2d24ce5604d775434e1 [file] [log] [blame]
/*++
Copyright (c) 2007, Intel Corporation
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.
Module Name:
EdbDisasm.c
Abstract:
--*/
#include "Edb.h"
//
// Debugger Disasm definition
//
#define EDB_DISASM_DEFINE(func) \
UINTN \
func ( \
IN EFI_PHYSICAL_ADDRESS InstructionAddress, \
IN EFI_SYSTEM_CONTEXT SystemContext, \
OUT CHAR16 **DisasmString \
)
EDB_DISASM_DEFINE (EdbDisasmBREAK);
EDB_DISASM_DEFINE (EdbDisasmJMP);
EDB_DISASM_DEFINE (EdbDisasmJMP8);
EDB_DISASM_DEFINE (EdbDisasmCALL);
EDB_DISASM_DEFINE (EdbDisasmRET);
EDB_DISASM_DEFINE (EdbDisasmCMP);
EDB_DISASM_DEFINE (EdbDisasmUnsignedDataManip);
EDB_DISASM_DEFINE (EdbDisasmSignedDataManip);
EDB_DISASM_DEFINE (EdbDisasmMOVxx);
EDB_DISASM_DEFINE (EdbDisasmMOVsnw);
EDB_DISASM_DEFINE (EdbDisasmMOVsnd);
EDB_DISASM_DEFINE (EdbDisasmLOADSP);
EDB_DISASM_DEFINE (EdbDisasmSTORESP);
EDB_DISASM_DEFINE (EdbDisasmPUSH);
EDB_DISASM_DEFINE (EdbDisasmPOP);
EDB_DISASM_DEFINE (EdbDisasmCMPI);
EDB_DISASM_DEFINE (EdbDisasmPUSHn);
EDB_DISASM_DEFINE (EdbDisasmPOPn);
EDB_DISASM_DEFINE (EdbDisasmMOVI);
EDB_DISASM_DEFINE (EdbDisasmMOVIn);
EDB_DISASM_DEFINE (EdbDisasmMOVREL);
//
// Debugger Disasm Table
//
EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[] = {
EdbDisasmBREAK, // opcode 0x00 BREAK
EdbDisasmJMP, // opcode 0x01 JMP
EdbDisasmJMP8, // opcode 0x02 JMP8
EdbDisasmCALL, // opcode 0x03 CALL
EdbDisasmRET, // opcode 0x04 RET
EdbDisasmCMP, // opcode 0x05 CMPEQ
EdbDisasmCMP, // opcode 0x06 CMPLTE
EdbDisasmCMP, // opcode 0x07 CMPGTE
EdbDisasmCMP, // opcode 0x08 CMPULTE
EdbDisasmCMP, // opcode 0x09 CMPUGTE
EdbDisasmUnsignedDataManip, // opcode 0x0A NOT
EdbDisasmSignedDataManip, // opcode 0x0B NEG
EdbDisasmSignedDataManip, // opcode 0x0C ADD
EdbDisasmSignedDataManip, // opcode 0x0D SUB
EdbDisasmSignedDataManip, // opcode 0x0E MUL
EdbDisasmUnsignedDataManip, // opcode 0x0F MULU
EdbDisasmSignedDataManip, // opcode 0x10 DIV
EdbDisasmUnsignedDataManip, // opcode 0x11 DIVU
EdbDisasmSignedDataManip, // opcode 0x12 MOD
EdbDisasmUnsignedDataManip, // opcode 0x13 MODU
EdbDisasmUnsignedDataManip, // opcode 0x14 AND
EdbDisasmUnsignedDataManip, // opcode 0x15 OR
EdbDisasmUnsignedDataManip, // opcode 0x16 XOR
EdbDisasmUnsignedDataManip, // opcode 0x17 SHL
EdbDisasmUnsignedDataManip, // opcode 0x18 SHR
EdbDisasmSignedDataManip, // opcode 0x19 ASHR
EdbDisasmUnsignedDataManip, // opcode 0x1A EXTNDB
EdbDisasmUnsignedDataManip, // opcode 0x1B EXTNDW
EdbDisasmUnsignedDataManip, // opcode 0x1C EXTNDD
EdbDisasmMOVxx, // opcode 0x1D MOVBW
EdbDisasmMOVxx, // opcode 0x1E MOVWW
EdbDisasmMOVxx, // opcode 0x1F MOVDW
EdbDisasmMOVxx, // opcode 0x20 MOVQW
EdbDisasmMOVxx, // opcode 0x21 MOVBD
EdbDisasmMOVxx, // opcode 0x22 MOVWD
EdbDisasmMOVxx, // opcode 0x23 MOVDD
EdbDisasmMOVxx, // opcode 0x24 MOVQD
EdbDisasmMOVsnw, // opcode 0x25 MOVSNW
EdbDisasmMOVsnd, // opcode 0x26 MOVSND
NULL, // opcode 0x27
EdbDisasmMOVxx, // opcode 0x28 MOVQQ
EdbDisasmLOADSP, // opcode 0x29 LOADSP
EdbDisasmSTORESP, // opcode 0x2A STORESP
EdbDisasmPUSH, // opcode 0x2B PUSH
EdbDisasmPOP, // opcode 0x2C POP
EdbDisasmCMPI, // opcode 0x2D CMPIEQ
EdbDisasmCMPI, // opcode 0x2E CMPILTE
EdbDisasmCMPI, // opcode 0x2F CMPIGTE
EdbDisasmCMPI, // opcode 0x30 CMPIULTE
EdbDisasmCMPI, // opcode 0x31 CMPIUGTE
EdbDisasmMOVxx, // opcode 0x32 MOVNW
EdbDisasmMOVxx, // opcode 0x33 MOVND
NULL, // opcode 0x34
EdbDisasmPUSHn, // opcode 0x35 PUSHN
EdbDisasmPOPn, // opcode 0x36 POPN
EdbDisasmMOVI, // opcode 0x37 MOVI
EdbDisasmMOVIn, // opcode 0x38 MOVIN
EdbDisasmMOVREL, // opcode 0x39 MOVREL
};
UINTN
EdbDisasmBREAK (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - BREAK
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_BREAK);
if (*(UINT8 *)(UINTN)(InstructionAddress + 1) > 6) {
return 0;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"BREAK");
EdbPrintDatan (*(UINT8 *)(UINTN)(InstructionAddress + 1));
EdbPostInstructionString ();
}
return 2;
}
extern CONST UINT8 mJMPLen[];
UINTN
EdbDisasmJMP (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - JMP
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT32 Data32;
UINT64 Data64;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_JMP);
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03];
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"JMP");
// if (Modifiers & OPCODE_M_IMMDATA64) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
if (Modifiers & CONDITION_M_CONDITIONAL) {
if (Modifiers & JMP_M_CS) {
EdbPrintInstructionName (L"cs");
} else {
EdbPrintInstructionName (L"cc");
}
}
InstructionAddress += 2;
if (Modifiers & OPCODE_M_IMMDATA64) {
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
if (Modifiers & OPCODE_M_IMMDATA) {
EdbPrintData64 (Data64);
} else {
return 0;
}
} else {
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
EdbPrintRegister1 (Operands);
if ((Operands & OPERAND_M_INDIRECT1) == 0) {
if ((Modifiers & OPCODE_M_IMMDATA) == 0) {
Data32 = 0;
}
EdbPrintImmDatan (Data32);
} else {
EdbPrintRawIndexData32 (Data32);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmJMP8 (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - JMP8
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_JMP8);
Modifiers = GET_MODIFIERS (InstructionAddress);
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"JMP8");
if (Modifiers & CONDITION_M_CONDITIONAL) {
if (Modifiers & JMP_M_CS) {
EdbPrintInstructionName (L"cs");
} else {
EdbPrintInstructionName (L"cc");
}
}
EdbPrintData8 (*(UINT8 *)(UINTN)(InstructionAddress + 1));
EdbPostInstructionString ();
}
return 2;
}
UINTN
EdbDisasmCALL (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - CALL
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT32 Data32;
UINT64 Data64;
UINT64 Ip;
UINTN Result;
EFI_PHYSICAL_ADDRESS SavedInstructionAddress;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_CALL);
SavedInstructionAddress = InstructionAddress;
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03];
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"CALL");
// if (Modifiers & OPCODE_M_IMMDATA64) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
if (Operands & OPERAND_M_NATIVE_CALL) {
EdbPrintInstructionName (L"EX");
}
// if ((Operands & OPERAND_M_RELATIVE_ADDR) == 0) {
// EdbPrintInstructionName (L"a");
// }
InstructionAddress += 2;
if (Modifiers & OPCODE_M_IMMDATA64) {
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
Ip = Data64;
if (Modifiers & OPCODE_M_IMMDATA) {
Result = EdbFindAndPrintSymbol ((UINTN)Ip);
if (Result == 0) {
EdbPrintData64 (Data64);
}
} else {
return 0;
}
} else {
if (Modifiers & OPCODE_M_IMMDATA) {
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
} else {
Data32 = 0;
}
if ((Operands & OPERAND_M_OP1) == 0) {
Ip = (UINT64)Data32;
} else {
Ip = GetRegisterValue (SystemContext, (Operands & OPERAND_M_OP1));
}
if ((Operands & OPERAND_M_INDIRECT1) == 0) {
if (Operands & OPERAND_M_RELATIVE_ADDR) {
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Ip + Size));
} else {
Result = EdbFindAndPrintSymbol ((UINTN)Ip);
}
if (Result == 0) {
EdbPrintRegister1 (Operands);
if (Modifiers & OPCODE_M_IMMDATA) {
EdbPrintImmData32 (Data32);
}
}
} else {
EdbPrintRegister1 (Operands);
if (Modifiers & OPCODE_M_IMMDATA) {
EdbPrintRawIndexData32 (Data32);
}
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmRET (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - RET
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_RET);
if (*(UINT8 *)(UINTN)(InstructionAddress + 1) != 0) {
return 0;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"RET");
EdbPostInstructionString ();
}
return 2;
}
UINTN
EdbDisasmCMP (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - CMP
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Opcode;
UINT8 Modifiers;
UINT8 Operands;
UINT16 Data16;
UINTN Size;
ASSERT (
(GET_OPCODE(InstructionAddress) == OPCODE_CMPEQ) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPLTE) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPGTE) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPULTE) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPUGTE)
);
Opcode = GET_OPCODE (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
if (Modifiers & OPCODE_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"CMP");
// if (Modifiers & OPCODE_M_64BIT) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
switch (Opcode) {
case OPCODE_CMPEQ:
EdbPrintInstructionName (L"eq");
break;
case OPCODE_CMPLTE:
EdbPrintInstructionName (L"lte");
break;
case OPCODE_CMPGTE:
EdbPrintInstructionName (L"gte");
break;
case OPCODE_CMPULTE:
EdbPrintInstructionName (L"ulte");
break;
case OPCODE_CMPUGTE:
EdbPrintInstructionName (L"ugte");
break;
}
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
EdbPrintComma ();
EdbPrintRegister2 (Operands);
if (Modifiers & OPCODE_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT2) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmUnsignedDataManip (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - Unsigned Data Manipulate
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Opcode;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
ASSERT (
(GET_OPCODE(InstructionAddress) == OPCODE_NOT) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MULU) ||
(GET_OPCODE(InstructionAddress) == OPCODE_DIVU) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MODU) ||
(GET_OPCODE(InstructionAddress) == OPCODE_AND) ||
(GET_OPCODE(InstructionAddress) == OPCODE_OR) ||
(GET_OPCODE(InstructionAddress) == OPCODE_XOR) ||
(GET_OPCODE(InstructionAddress) == OPCODE_SHL) ||
(GET_OPCODE(InstructionAddress) == OPCODE_SHR) ||
(GET_OPCODE(InstructionAddress) == OPCODE_EXTNDB) ||
(GET_OPCODE(InstructionAddress) == OPCODE_EXTNDW) ||
(GET_OPCODE(InstructionAddress) == OPCODE_EXTNDD)
);
Opcode = GET_OPCODE (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
if (Modifiers & DATAMANIP_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
switch (Opcode) {
case OPCODE_NOT:
EdbPrintInstructionName (L"NOT");
break;
case OPCODE_MULU:
EdbPrintInstructionName (L"MULU");
break;
case OPCODE_DIVU:
EdbPrintInstructionName (L"DIVU");
break;
case OPCODE_MODU:
EdbPrintInstructionName (L"MODU");
break;
case OPCODE_AND:
EdbPrintInstructionName (L"AND");
break;
case OPCODE_OR:
EdbPrintInstructionName (L"OR");
break;
case OPCODE_XOR:
EdbPrintInstructionName (L"XOR");
break;
case OPCODE_SHL:
EdbPrintInstructionName (L"SHL");
break;
case OPCODE_SHR:
EdbPrintInstructionName (L"SHR");
break;
case OPCODE_EXTNDB:
EdbPrintInstructionName (L"EXTNDB");
break;
case OPCODE_EXTNDW:
EdbPrintInstructionName (L"EXTNDW");
break;
case OPCODE_EXTNDD:
EdbPrintInstructionName (L"EXTNDD");
break;
}
// if (Modifiers & DATAMANIP_M_64) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
EdbPrintRegister1 (Operands);
EdbPrintComma ();
EdbPrintRegister2 (Operands);
InstructionAddress += 2;
if (Modifiers & DATAMANIP_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT2) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmSignedDataManip (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - Signed Data Manipulate
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Opcode;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
ASSERT (
(GET_OPCODE(InstructionAddress) == OPCODE_NEG) ||
(GET_OPCODE(InstructionAddress) == OPCODE_ADD) ||
(GET_OPCODE(InstructionAddress) == OPCODE_SUB) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MUL) ||
(GET_OPCODE(InstructionAddress) == OPCODE_DIV) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOD) ||
(GET_OPCODE(InstructionAddress) == OPCODE_ASHR)
);
Opcode = GET_OPCODE (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
if (Modifiers & DATAMANIP_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
switch (Opcode) {
case OPCODE_NEG:
EdbPrintInstructionName (L"NEG");
break;
case OPCODE_ADD:
EdbPrintInstructionName (L"ADD");
break;
case OPCODE_SUB:
EdbPrintInstructionName (L"SUB");
break;
case OPCODE_MUL:
EdbPrintInstructionName (L"MUL");
break;
case OPCODE_DIV:
EdbPrintInstructionName (L"DIV");
break;
case OPCODE_MOD:
EdbPrintInstructionName (L"MOD");
break;
case OPCODE_ASHR:
EdbPrintInstructionName (L"ASHR");
break;
}
// if (Modifiers & DATAMANIP_M_64) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
EdbPrintRegister1 (Operands);
EdbPrintComma ();
EdbPrintRegister2 (Operands);
InstructionAddress += 2;
if (Modifiers & DATAMANIP_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT2) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmMOVxx (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - MOVxx
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Opcode;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
UINT32 Data32;
UINT64 Data64;
ASSERT (
(GET_OPCODE(InstructionAddress) == OPCODE_MOVBW) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVWW) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVDW) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVQW) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVBD) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVWD) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVDD) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVQD) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVQQ) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVNW) ||
(GET_OPCODE(InstructionAddress) == OPCODE_MOVND)
);
Opcode = GET_OPCODE (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
Size = 2;
if (Modifiers & (OPCODE_M_IMMED_OP1 | OPCODE_M_IMMED_OP2)) {
if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
if (Modifiers & OPCODE_M_IMMED_OP1) {
Size += 2;
}
if (Modifiers & OPCODE_M_IMMED_OP2) {
Size += 2;
}
} else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) {
if (Modifiers & OPCODE_M_IMMED_OP1) {
Size += 4;
}
if (Modifiers & OPCODE_M_IMMED_OP2) {
Size += 4;
}
} else if (Opcode == OPCODE_MOVQQ) {
if (Modifiers & OPCODE_M_IMMED_OP1) {
Size += 8;
}
if (Modifiers & OPCODE_M_IMMED_OP2) {
Size += 8;
}
}
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"MOV");
switch (Opcode) {
case OPCODE_MOVBW:
EdbPrintInstructionName (L"bw");
break;
case OPCODE_MOVWW:
EdbPrintInstructionName (L"ww");
break;
case OPCODE_MOVDW:
EdbPrintInstructionName (L"dw");
break;
case OPCODE_MOVQW:
EdbPrintInstructionName (L"qw");
break;
case OPCODE_MOVBD:
EdbPrintInstructionName (L"bd");
break;
case OPCODE_MOVWD:
EdbPrintInstructionName (L"wd");
break;
case OPCODE_MOVDD:
EdbPrintInstructionName (L"dd");
break;
case OPCODE_MOVQD:
EdbPrintInstructionName (L"qd");
break;
case OPCODE_MOVQQ:
EdbPrintInstructionName (L"qq");
break;
case OPCODE_MOVNW:
EdbPrintInstructionName (L"nw");
break;
case OPCODE_MOVND:
EdbPrintInstructionName (L"nd");
break;
}
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Modifiers & OPCODE_M_IMMED_OP1) {
if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
InstructionAddress += 2;
EdbPrintRawIndexData16 (Data16);
} else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) {
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
InstructionAddress += 4;
EdbPrintRawIndexData32 (Data32);
} else if (Opcode == OPCODE_MOVQQ) {
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
InstructionAddress += 8;
EdbPrintRawIndexData64 (Data64);
}
}
EdbPrintComma ();
EdbPrintRegister2 (Operands);
if (Modifiers & OPCODE_M_IMMED_OP2) {
if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
EdbPrintRawIndexData16 (Data16);
} else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) {
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
EdbPrintRawIndexData32 (Data32);
} else if (Opcode == OPCODE_MOVQQ) {
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
EdbPrintRawIndexData64 (Data64);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmMOVsnw (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - MOVsnw
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVSNW);
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
Size = 2;
if (Modifiers & OPCODE_M_IMMED_OP1) {
Size += 2;
}
if (Modifiers & OPCODE_M_IMMED_OP2) {
Size += 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"MOVsnw");
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Modifiers & OPCODE_M_IMMED_OP1) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
InstructionAddress += 2;
EdbPrintRawIndexData16 (Data16);
}
EdbPrintComma ();
EdbPrintRegister2 (Operands);
if (Modifiers & OPCODE_M_IMMED_OP2) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT2) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmMOVsnd (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - MOVsnd
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT32 Data32;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVSND);
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
Size = 2;
if (Modifiers & OPCODE_M_IMMED_OP1) {
Size += 4;
}
if (Modifiers & OPCODE_M_IMMED_OP2) {
Size += 4;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"MOVsnd");
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Modifiers & OPCODE_M_IMMED_OP1) {
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
InstructionAddress += 4;
EdbPrintRawIndexData32 (Data32);
}
EdbPrintComma ();
EdbPrintRegister2 (Operands);
if (Modifiers & OPCODE_M_IMMED_OP2) {
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
if (Operands & OPERAND_M_INDIRECT2) {
EdbPrintRawIndexData32 (Data32);
} else {
EdbPrintImmDatan (Data32);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmLOADSP (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - LOADSP
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Operands;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_LOADSP);
Operands = GET_OPERANDS (InstructionAddress);
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"LOADSP");
EdbPrintDedicatedRegister1 (Operands);
EdbPrintRegister2 (Operands);
EdbPostInstructionString ();
}
return 2;
}
UINTN
EdbDisasmSTORESP (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - STORESP
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Operands;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_STORESP);
Operands = GET_OPERANDS (InstructionAddress);
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"STORESP");
EdbPrintRegister1 (Operands);
EdbPrintDedicatedRegister2 (Operands);
EdbPostInstructionString ();
}
return 2;
}
UINTN
EdbDisasmPUSH (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - PUSH
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_PUSH);
Operands = GET_OPERANDS (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
if (Modifiers & PUSHPOP_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"PUSH");
// if (Modifiers & PUSHPOP_M_64) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Modifiers & PUSHPOP_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT1) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmPOP (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - POP
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_POP);
Operands = GET_OPERANDS (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
if (Modifiers & PUSHPOP_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"POP");
// if (Modifiers & PUSHPOP_M_64) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Modifiers & PUSHPOP_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT1) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmCMPI (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - CMPI
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Opcode;
UINT8 Operands;
UINT16 Data16;
UINT32 Data32;
UINTN Size;
ASSERT (
(GET_OPCODE(InstructionAddress) == OPCODE_CMPIEQ) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPILTE) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPIGTE) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPIULTE) ||
(GET_OPCODE(InstructionAddress) == OPCODE_CMPIUGTE)
);
Modifiers = GET_MODIFIERS (InstructionAddress);
Opcode = GET_OPCODE (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
if ((Operands & 0xE0) != 0) {
return 0;
}
Size = 2;
if (Operands & OPERAND_M_CMPI_INDEX) {
Size += 2;
}
if (Modifiers & OPCODE_M_CMPI32_DATA) {
Size += 4;
} else {
Size += 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"CMPI");
// if (Modifiers & OPCODE_M_CMPI64) {
// EdbPrintInstructionName (L"64");
// } else {
// EdbPrintInstructionName (L"32");
// }
if (Modifiers & OPCODE_M_CMPI32_DATA) {
EdbPrintInstructionName (L"d");
} else {
EdbPrintInstructionName (L"w");
}
switch (Opcode) {
case OPCODE_CMPIEQ:
EdbPrintInstructionName (L"eq");
break;
case OPCODE_CMPILTE:
EdbPrintInstructionName (L"lte");
break;
case OPCODE_CMPIGTE:
EdbPrintInstructionName (L"gte");
break;
case OPCODE_CMPIULTE:
EdbPrintInstructionName (L"ulte");
break;
case OPCODE_CMPIUGTE:
EdbPrintInstructionName (L"ugte");
break;
}
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Operands & OPERAND_M_CMPI_INDEX) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
InstructionAddress += 2;
EdbPrintRawIndexData16 (Data16);
}
EdbPrintComma ();
if (Modifiers & OPCODE_M_CMPI32_DATA) {
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
EdbPrintDatan (Data32);
} else {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
EdbPrintDatan (Data16);
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmPUSHn (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - PUSHn
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_PUSHN);
Operands = GET_OPERANDS (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
if (Modifiers & PUSHPOP_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"PUSHn");
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Modifiers & PUSHPOP_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT1) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmPOPn (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - POPn
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_POPN);
Operands = GET_OPERANDS (InstructionAddress);
Modifiers = GET_MODIFIERS (InstructionAddress);
if (Modifiers & PUSHPOP_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"POPn");
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Modifiers & PUSHPOP_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
if (Operands & OPERAND_M_INDIRECT1) {
EdbPrintRawIndexData16 (Data16);
} else {
EdbPrintImmDatan (Data16);
}
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmMOVI (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - MOVI
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
UINT32 Data32;
UINT64 Data64;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVI);
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
if (Operands & MOVI_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
Size += 2;
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
Size += 4;
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
Size += 8;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"MOVI");
switch (Operands & MOVI_M_MOVEWIDTH) {
case MOVI_MOVEWIDTH8:
EdbPrintInstructionName (L"b");
break;
case MOVI_MOVEWIDTH16:
EdbPrintInstructionName (L"w");
break;
case MOVI_MOVEWIDTH32:
EdbPrintInstructionName (L"d");
break;
case MOVI_MOVEWIDTH64:
EdbPrintInstructionName (L"q");
break;
}
switch (Modifiers & MOVI_M_DATAWIDTH) {
case MOVI_DATAWIDTH16:
EdbPrintInstructionName (L"w");
break;
case MOVI_DATAWIDTH32:
EdbPrintInstructionName (L"d");
break;
case MOVI_DATAWIDTH64:
EdbPrintInstructionName (L"q");
break;
}
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Operands & MOVI_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
InstructionAddress += 2;
EdbPrintRawIndexData16 (Data16);
}
EdbPrintComma ();
switch (Modifiers & MOVI_M_DATAWIDTH) {
case MOVI_DATAWIDTH16:
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
EdbPrintDatan (Data16);
break;
case MOVI_DATAWIDTH32:
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
EdbPrintDatan (Data32);
break;
case MOVI_DATAWIDTH64:
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
EdbPrintData64n (Data64);
break;
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmMOVIn (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - MOVIn
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
UINT32 Data32;
UINT64 Data64;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVIN);
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
if (Operands & MOVI_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
Size += 2;
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
Size += 4;
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
Size += 8;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"MOVIn");
switch (Modifiers & MOVI_M_DATAWIDTH) {
case MOVI_DATAWIDTH16:
EdbPrintInstructionName (L"w");
break;
case MOVI_DATAWIDTH32:
EdbPrintInstructionName (L"d");
break;
case MOVI_DATAWIDTH64:
EdbPrintInstructionName (L"q");
break;
}
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Operands & MOVI_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
InstructionAddress += 2;
EdbPrintRawIndexData16 (Data16);
}
EdbPrintComma ();
switch (Modifiers & MOVI_M_DATAWIDTH) {
case MOVI_DATAWIDTH16:
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
EdbPrintRawIndexData16 (Data16);
break;
case MOVI_DATAWIDTH32:
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
EdbPrintRawIndexData32 (Data32);
break;
case MOVI_DATAWIDTH64:
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
EdbPrintRawIndexData64 (Data64);
break;
}
EdbPostInstructionString ();
}
return Size;
}
UINTN
EdbDisasmMOVREL (
IN EFI_PHYSICAL_ADDRESS InstructionAddress,
IN EFI_SYSTEM_CONTEXT SystemContext,
OUT CHAR16 **DisasmString
)
/*++
Routine Description:
Disasm instruction - MOVREL
Arguments:
InstructionAddress - The instruction address
SystemContext - EBC system context.
DisasmString - The instruction string
Returns:
Instruction length
--*/
{
UINT8 Modifiers;
UINT8 Operands;
UINTN Size;
UINT16 Data16;
UINT32 Data32;
UINT64 Data64;
UINTN Result;
EFI_PHYSICAL_ADDRESS SavedInstructionAddress;
ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVREL);
SavedInstructionAddress = InstructionAddress;
Modifiers = GET_MODIFIERS (InstructionAddress);
Operands = GET_OPERANDS (InstructionAddress);
if (Operands & MOVI_M_IMMDATA) {
Size = 4;
} else {
Size = 2;
}
if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
Size += 2;
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
Size += 4;
} else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
Size += 8;
} else {
return 0;
}
//
// Construct Disasm String
//
if (DisasmString != NULL) {
*DisasmString = EdbPreInstructionString ();
EdbPrintInstructionName (L"MOVrel");
switch (Modifiers & MOVI_M_DATAWIDTH) {
case MOVI_DATAWIDTH16:
EdbPrintInstructionName (L"w");
break;
case MOVI_DATAWIDTH32:
EdbPrintInstructionName (L"d");
break;
case MOVI_DATAWIDTH64:
EdbPrintInstructionName (L"q");
break;
}
EdbPrintRegister1 (Operands);
InstructionAddress += 2;
if (Operands & MOVI_M_IMMDATA) {
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
InstructionAddress += 2;
EdbPrintRawIndexData16 (Data16);
}
EdbPrintComma ();
switch (Modifiers & MOVI_M_DATAWIDTH) {
case MOVI_DATAWIDTH16:
CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT16)Data16));
if (Result == 0) {
EdbPrintData16 (Data16);
}
break;
case MOVI_DATAWIDTH32:
CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT32)Data32));
if (Result == 0) {
EdbPrintData32 (Data32);
}
break;
case MOVI_DATAWIDTH64:
CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
if (sizeof(UINTN) == sizeof(UINT64)) {
Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT64)Data64));
} else {
Result = 0;
}
if (Result == 0) {
EdbPrintData64 (Data64);
}
break;
}
EdbPostInstructionString ();
}
return Size;
}