/** @file Copyright (c) 2007, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "Edb.h" extern EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[]; typedef struct { CHAR16 Name[EDB_INSTRUCTION_NAME_MAX_LENGTH]; CHAR16 Content[EDB_INSTRUCTION_CONTENT_MAX_LENGTH]; CHAR16 Tail; } EDB_INSTRUCTION_STRING; EDB_INSTRUCTION_STRING mInstructionString; UINTN mInstructionNameOffset; UINTN mInstructionContentOffset; /** Set offset for Instruction name and content. @param InstructionNameOffset - Instruction name offset @param InstructionContentOffset - Instruction content offset **/ VOID EdbSetOffset ( IN UINTN InstructionNameOffset, IN UINTN InstructionContentOffset ) { mInstructionNameOffset = InstructionNameOffset; mInstructionContentOffset = InstructionContentOffset; return ; } /** Pre instruction string construction. @return Instruction string **/ CHAR16 * EdbPreInstructionString ( VOID ) { ZeroMem (&mInstructionString, sizeof(mInstructionString)); mInstructionNameOffset = 0; mInstructionContentOffset = 0; return (CHAR16 *)&mInstructionString; } /** Post instruction string construction. @return Instruction string **/ CHAR16 * EdbPostInstructionString ( VOID ) { CHAR16 *Char; for (Char = (CHAR16 *)&mInstructionString; Char < &mInstructionString.Tail; Char++) { if (*Char == 0) { *Char = L' '; } } mInstructionString.Tail = 0; mInstructionNameOffset = 0; mInstructionContentOffset = 0; return (CHAR16 *)&mInstructionString; } /** Get Sign, NaturalUnits, and ConstantUnits of the WORD data. @param Data16 - WORD data @param NaturalUnits - Natural Units of the WORD @param ConstantUnits - Constant Units of the WORD @return Sign value of WORD **/ BOOLEAN EdbGetNaturalIndex16 ( IN UINT16 Data16, OUT UINTN *NaturalUnits, OUT UINTN *ConstantUnits ) { BOOLEAN Sign; UINTN NaturalUnitBit; Sign = (BOOLEAN)(Data16 >> 15); NaturalUnitBit = (UINTN)((Data16 >> 12) & 0x7); NaturalUnitBit *= 2; Data16 = Data16 & 0xFFF; *NaturalUnits = (UINTN)(Data16 & ((1 << NaturalUnitBit) - 1)); *ConstantUnits = (UINTN)((Data16 >> NaturalUnitBit) & ((1 << (12 - NaturalUnitBit)) - 1)); return Sign; } /** Get Sign, NaturalUnits, and ConstantUnits of the DWORD data. @param Data32 - DWORD data @param NaturalUnits - Natural Units of the DWORD @param ConstantUnits - Constant Units of the DWORD @return Sign value of DWORD **/ BOOLEAN EdbGetNaturalIndex32 ( IN UINT32 Data32, OUT UINTN *NaturalUnits, OUT UINTN *ConstantUnits ) { BOOLEAN Sign; UINTN NaturalUnitBit; Sign = (BOOLEAN)(Data32 >> 31); NaturalUnitBit = (UINTN)((Data32 >> 28) & 0x7); NaturalUnitBit *= 4; Data32 = Data32 & 0xFFFFFFF; *NaturalUnits = (UINTN)(Data32 & ((1 << NaturalUnitBit) - 1)); *ConstantUnits = (UINTN)((Data32 >> NaturalUnitBit) & ((1 << (28 - NaturalUnitBit)) - 1)); return Sign; } /** Get Sign, NaturalUnits, and ConstantUnits of the QWORD data. @param Data64 - QWORD data @param NaturalUnits - Natural Units of the QWORD @param ConstantUnits - Constant Units of the QWORD @return Sign value of QWORD **/ BOOLEAN EdbGetNaturalIndex64 ( IN UINT64 Data64, OUT UINT64 *NaturalUnits, OUT UINT64 *ConstantUnits ) { BOOLEAN Sign; UINTN NaturalUnitBit; Sign = (BOOLEAN)RShiftU64 (Data64, 63); NaturalUnitBit = (UINTN)(RShiftU64 (Data64, 60) & 0x7); NaturalUnitBit *= 8; Data64 = RShiftU64 (LShiftU64 (Data64, 4), 4); *NaturalUnits = (UINT64)(Data64 & (LShiftU64 (1, NaturalUnitBit) - 1)); *ConstantUnits = (UINT64)(RShiftU64 (Data64, NaturalUnitBit) & (LShiftU64 (1, (60 - NaturalUnitBit)) - 1)); return Sign; } /** Get Bit Width of the value. @param Value - data @return Bit width **/ UINT8 EdbGetBitWidth ( IN UINT64 Value ) { if (Value >= 10000000000000) { return 14; } else if (Value >= 1000000000000) { return 13; } else if (Value >= 100000000000) { return 12; } else if (Value >= 10000000000) { return 11; } else if (Value >= 1000000000) { return 10; } else if (Value >= 100000000) { return 9; } else if (Value >= 10000000) { return 8; } else if (Value >= 1000000) { return 7; } else if (Value >= 100000) { return 6; } else if (Value >= 10000) { return 5; } else if (Value >= 1000) { return 4; } else if (Value >= 100) { return 3; } else if (Value >= 10) { return 2; } else { return 1; } } /** Print the instruction name. @param Name - instruction name @return Instruction name offset **/ UINTN EdbPrintInstructionName ( IN CHAR16 *Name ) { EDBSPrintWithOffset ( mInstructionString.Name, EDB_INSTRUCTION_NAME_MAX_SIZE, mInstructionNameOffset, L"%s", Name ); mInstructionNameOffset += StrLen (Name); return mInstructionNameOffset; } /** Print register 1 in operands. @param Operands - instruction operands @return Instruction content offset **/ UINTN EdbPrintRegister1 ( IN UINT8 Operands ) { if ((Operands & OPERAND_M_INDIRECT1) != 0) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"@" ); mInstructionContentOffset += 1; } EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"R%d", (UINTN)(Operands & OPERAND_M_OP1) ); mInstructionContentOffset += 2; return mInstructionContentOffset; } /** Print register 2 in operands. @param Operands - instruction operands @return Instruction content offset **/ UINTN EdbPrintRegister2 ( IN UINT8 Operands ) { if ((Operands & OPERAND_M_INDIRECT2) != 0) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"@" ); mInstructionContentOffset += 1; } EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"R%d", (UINTN)((Operands & OPERAND_M_OP2) >> 4) ); mInstructionContentOffset += 2; return mInstructionContentOffset; } /** Print dedicated register 1 in operands. @param Operands - instruction operands @return Instruction content offset **/ UINTN EdbPrintDedicatedRegister1 ( IN UINT8 Operands ) { switch (Operands & OPERAND_M_OP1) { case 0: EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"[FLAGS]" ); mInstructionContentOffset += 7; break; case 1: EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"[IP]" ); mInstructionContentOffset += 4; break; } return mInstructionContentOffset; } /** Print dedicated register 2 in operands. @param Operands - instruction operands @return Instruction content offset **/ UINTN EdbPrintDedicatedRegister2 ( IN UINT8 Operands ) { switch ((Operands & OPERAND_M_OP2) >> 4) { case 0: EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"[FLAGS]" ); mInstructionContentOffset += 7; break; case 1: EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"[IP]" ); mInstructionContentOffset += 4; break; } return mInstructionContentOffset; } /** Print the hexical UINTN index data to instruction content. @param Sign - Signed bit of UINTN data @param NaturalUnits - natural units of UINTN data @param ConstantUnits - natural units of UINTN data @return Instruction content offset **/ UINTN EdbPrintIndexData ( IN BOOLEAN Sign, IN UINTN NaturalUnits, IN UINTN ConstantUnits ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(%s%d,%s%d)", Sign ? L"-" : L"+", NaturalUnits, Sign ? L"-" : L"+", ConstantUnits ); mInstructionContentOffset = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits); return mInstructionContentOffset; } /** Print the hexical QWORD index data to instruction content. @param Sign - Signed bit of QWORD data @param NaturalUnits - natural units of QWORD data @param ConstantUnits - natural units of QWORD data @return Instruction content offset **/ UINTN EdbPrintIndexData64 ( IN BOOLEAN Sign, IN UINT64 NaturalUnits, IN UINT64 ConstantUnits ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(%s%ld,%s%ld)", Sign ? L"-" : L"+", NaturalUnits, Sign ? L"-" : L"+", ConstantUnits ); mInstructionContentOffset = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits); return mInstructionContentOffset; } /** Print the hexical WORD raw index data to instruction content. @param Data16 - WORD data @return Instruction content offset **/ UINTN EdbPrintRawIndexData16 ( IN UINT16 Data16 ) { BOOLEAN Sign; UINTN NaturalUnits; UINTN ConstantUnits; UINTN Offset; Sign = EdbGetNaturalIndex16 (Data16, &NaturalUnits, &ConstantUnits); Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits); return Offset; } /** Print the hexical DWORD raw index data to instruction content. @param Data32 - DWORD data @return Instruction content offset **/ UINTN EdbPrintRawIndexData32 ( IN UINT32 Data32 ) { BOOLEAN Sign; UINTN NaturalUnits; UINTN ConstantUnits; UINTN Offset; Sign = EdbGetNaturalIndex32 (Data32, &NaturalUnits, &ConstantUnits); Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits); return Offset; } /** Print the hexical QWORD raw index data to instruction content. @param Data64 - QWORD data @return Instruction content offset **/ UINTN EdbPrintRawIndexData64 ( IN UINT64 Data64 ) { BOOLEAN Sign; UINT64 NaturalUnits; UINT64 ConstantUnits; UINTN Offset; Sign = EdbGetNaturalIndex64 (Data64, &NaturalUnits, &ConstantUnits); Offset = EdbPrintIndexData64 (Sign, NaturalUnits, ConstantUnits); return Offset; } /** Print the hexical BYTE immediate data to instruction content. @param Data - BYTE data @return Instruction content offset **/ UINTN EdbPrintImmData8 ( IN UINT8 Data ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(0x%02x)", (UINTN)Data ); mInstructionContentOffset += 6; return mInstructionContentOffset; } /** Print the hexical WORD immediate data to instruction content. @param Data - WORD data @return Instruction content offset **/ UINTN EdbPrintImmData16 ( IN UINT16 Data ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(0x%04x)", (UINTN)Data ); mInstructionContentOffset += 8; return mInstructionContentOffset; } /** Print the hexical DWORD immediate data to instruction content. @param Data - DWORD data @return Instruction content offset **/ UINTN EdbPrintImmData32 ( IN UINT32 Data ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(0x%08x)", (UINTN)Data ); mInstructionContentOffset += 12; return mInstructionContentOffset; } /** Print the hexical QWORD immediate data to instruction content. @param Data - QWORD data @return Instruction content offset **/ UINTN EdbPrintImmData64 ( IN UINT64 Data ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(0x%016lx)", Data ); mInstructionContentOffset += 20; return mInstructionContentOffset; } /** Print the decimal UINTN immediate data to instruction content. @param Data - UINTN data @return Instruction content offset **/ UINTN EdbPrintImmDatan ( IN UINTN Data ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(%d)", (UINTN)Data ); mInstructionContentOffset = mInstructionContentOffset + 2 + EdbGetBitWidth (Data); return mInstructionContentOffset; } /** Print the decimal QWORD immediate data to instruction content. @param Data64 - QWORD data @return Instruction content offset **/ UINTN EdbPrintImmData64n ( IN UINT64 Data64 ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"(%ld)", Data64 ); mInstructionContentOffset = mInstructionContentOffset + 2 + EdbGetBitWidth (Data64); return mInstructionContentOffset; } /** Print the hexical BYTE to instruction content. @param Data8 - BYTE data @return Instruction content offset **/ UINTN EdbPrintData8 ( IN UINT8 Data8 ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"0x%02x", (UINTN)Data8 ); mInstructionContentOffset += 4; return mInstructionContentOffset; } /** Print the hexical WORD to instruction content. @param Data16 - WORD data @return Instruction content offset **/ UINTN EdbPrintData16 ( IN UINT16 Data16 ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"0x%04x", (UINTN)Data16 ); mInstructionContentOffset += 6; return mInstructionContentOffset; } /** Print the hexical DWORD to instruction content. @param Data32 - DWORD data @return Instruction content offset **/ UINTN EdbPrintData32 ( IN UINT32 Data32 ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"0x%08x", (UINTN)Data32 ); mInstructionContentOffset += 10; return mInstructionContentOffset; } /** Print the hexical QWORD to instruction content. @param Data64 - QWORD data @return Instruction content offset **/ UINTN EdbPrintData64 ( IN UINT64 Data64 ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"0x%016lx", (UINT64)Data64 ); mInstructionContentOffset += 18; return mInstructionContentOffset; } /** Print the decimal unsigned UINTN to instruction content. @param Data - unsigned UINTN data @return Instruction content offset **/ UINTN EdbPrintDatan ( IN UINTN Data ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"%d", (UINTN)Data ); mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data); return mInstructionContentOffset; } /** Print the decimal unsigned QWORD to instruction content. @param Data64 - unsigned QWORD data @return Instruction content offset **/ UINTN EdbPrintData64n ( IN UINT64 Data64 ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"%ld", Data64 ); mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data64); return mInstructionContentOffset; } /** Print the decimal signed BYTE to instruction content. @param Data8 - signed BYTE data @return Instruction content offset **/ UINTN EdbPrintData8s ( IN UINT8 Data8 ) { BOOLEAN Sign; Sign = (BOOLEAN)(Data8 >> 7); EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"%s%d", Sign ? L"-" : L"+", (UINTN)(Data8 & 0x7F) ); mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data8 & 0x7F); return mInstructionContentOffset; } /** Print the decimal signed WORD to instruction content. @param Data16 - signed WORD data @return Instruction content offset **/ UINTN EdbPrintData16s ( IN UINT16 Data16 ) { BOOLEAN Sign; Sign = (BOOLEAN)(Data16 >> 15); EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"%s%d", Sign ? L"-" : L"+", (UINTN)(Data16 & 0x7FFF) ); mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data16 & 0x7FFF); return mInstructionContentOffset; } /** Print the decimal signed DWORD to instruction content. @param Data32 - signed DWORD data @return Instruction content offset **/ UINTN EdbPrintData32s ( IN UINT32 Data32 ) { BOOLEAN Sign; Sign = (BOOLEAN)(Data32 >> 31); EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"%s%d", Sign ? L"-" : L"+", (UINTN)(Data32 & 0x7FFFFFFF) ); mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data32 & 0x7FFFFFFF); return mInstructionContentOffset; } /** Print the decimal signed QWORD to instruction content. @param Data64 - signed QWORD data @return Instruction content offset **/ UINTN EdbPrintData64s ( IN UINT64 Data64 ) { BOOLEAN Sign; INT64 Data64s; Sign = (BOOLEAN)RShiftU64 (Data64, 63); Data64s = (INT64)RShiftU64 (LShiftU64 (Data64, 1), 1); EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"%s%ld", Sign ? L"-" : L"+", (UINT64)Data64s ); mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data64s); return mInstructionContentOffset; } /** Print the comma to instruction content. @return Instruction content offset **/ UINTN EdbPrintComma ( VOID ) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L", " ); mInstructionContentOffset += 2; return mInstructionContentOffset; } /** Find the symbol string according to address, then print it. @param Address - instruction address @retval 1 - symbol string is found and printed @retval 0 - symbol string not found **/ UINTN EdbFindAndPrintSymbol ( IN UINTN Address ) { CHAR8 *SymbolStr; SymbolStr = FindSymbolStr (Address); if (SymbolStr != NULL) { EDBSPrintWithOffset ( mInstructionString.Content, EDB_INSTRUCTION_CONTENT_MAX_SIZE, mInstructionContentOffset, L"[%a]", SymbolStr ); return 1; } return 0; } /** Print the EBC byte code. @param InstructionAddress - instruction address @param InstructionNumber - instruction number **/ VOID EdbPrintRaw ( IN EFI_PHYSICAL_ADDRESS InstructionAddress, IN UINTN InstructionNumber ) { UINTN LineNumber; UINTN ByteNumber; UINTN LineIndex; UINTN ByteIndex; CHAR8 *SymbolStr; if (InstructionNumber == 0) { return ; } LineNumber = InstructionNumber / EDB_BYTECODE_NUMBER_IN_LINE; ByteNumber = InstructionNumber % EDB_BYTECODE_NUMBER_IN_LINE; if (ByteNumber == 0) { LineNumber -= 1; ByteNumber = EDB_BYTECODE_NUMBER_IN_LINE; } // // Print Symbol // SymbolStr = FindSymbolStr ((UINTN)InstructionAddress); if (SymbolStr != NULL) { EDBPrint (L"[%a]:\n", SymbolStr); } for (LineIndex = 0; LineIndex < LineNumber; LineIndex++) { EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress); for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE; ByteIndex++) { EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress); InstructionAddress += 1; } EDBPrint (L"\n"); } EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress); for (ByteIndex = 0; ByteIndex < ByteNumber; ByteIndex++) { EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress); InstructionAddress += 1; } for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE - ByteNumber; ByteIndex++) { EDBPrint (L" "); } return ; } /** Print the EBC asm code. @param DebuggerPrivate - EBC Debugger private data structure @param SystemContext - EBC system context. @retval EFI_SUCCESS - show disasm successfully **/ EFI_STATUS EdbShowDisasm ( IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN EFI_SYSTEM_CONTEXT SystemContext ) { EFI_PHYSICAL_ADDRESS InstructionAddress; UINTN InstructionNumber; UINTN InstructionLength; UINT8 Opcode; CHAR16 *InstructionString; // UINTN Result; InstructionAddress = DebuggerPrivate->InstructionScope; for (InstructionNumber = 0; InstructionNumber < DebuggerPrivate->InstructionNumber; InstructionNumber++) { // // Break each 0x10 instruction // if (((InstructionNumber % EFI_DEBUGGER_LINE_NUMBER_IN_PAGE) == 0) && (InstructionNumber != 0)) { if (SetPageBreak ()) { break; } } Opcode = GET_OPCODE(InstructionAddress); if ((Opcode < OPCODE_MAX) && (mEdbDisasmInstructionTable[Opcode] != NULL)) { InstructionLength = mEdbDisasmInstructionTable [Opcode] (InstructionAddress, SystemContext, &InstructionString); if (InstructionLength != 0) { // // Print Source // // Result = EdbPrintSource ((UINTN)InstructionAddress, FALSE); if (!DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly) { EdbPrintRaw (InstructionAddress, InstructionLength); if (InstructionString != NULL) { EDBPrint (L"%s\n", InstructionString); } else { EDBPrint (L"%s\n", L""); } } EdbPrintSource ((UINTN)InstructionAddress, TRUE); InstructionAddress += InstructionLength; } else { // // Something wrong with OPCODE // EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE); EDBPrint (L"%s\n", L""); break; } } else { // // Something wrong with OPCODE // EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE); EDBPrint (L"%s\n", L""); break; } } return EFI_SUCCESS; } /** Get register value according to the system context, and register index. @param SystemContext - EBC system context. @param Index - EBC register index @return register value **/ UINT64 GetRegisterValue ( IN EFI_SYSTEM_CONTEXT SystemContext, IN UINT8 Index ) { switch (Index) { case 0: return SystemContext.SystemContextEbc->R0; case 1: return SystemContext.SystemContextEbc->R1; case 2: return SystemContext.SystemContextEbc->R2; case 3: return SystemContext.SystemContextEbc->R3; case 4: return SystemContext.SystemContextEbc->R4; case 5: return SystemContext.SystemContextEbc->R5; case 6: return SystemContext.SystemContextEbc->R6; case 7: return SystemContext.SystemContextEbc->R7; default: ASSERT (FALSE); break; } return 0; }