| /** @file | |
| Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> | |
| 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"<Unknown Instruction>"); | |
| } | |
| } | |
| EdbPrintSource ((UINTN)InstructionAddress, TRUE); | |
| InstructionAddress += InstructionLength; | |
| } else { | |
| // | |
| // Something wrong with OPCODE | |
| // | |
| EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE); | |
| EDBPrint (L"%s\n", L"<Bad Instruction>"); | |
| break; | |
| } | |
| } else { | |
| // | |
| // Something wrong with OPCODE | |
| // | |
| EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE); | |
| EDBPrint (L"%s\n", L"<Bad Instruction>"); | |
| 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; | |
| } |