mirror of https://github.com/acidanthera/audk.git
1908 lines
46 KiB
C
1908 lines
46 KiB
C
/*++
|
|
|
|
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;
|
|
}
|