https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2c9dbacebbee6b53bf331e...
commit 2c9dbacebbee6b53bf331e032d9f2af4e4f828eb Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sat Jan 1 02:24:52 2022 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sat Jan 1 05:04:22 2022 +0100
[FREELDR] Fix displayed information in the Exception BSOD. CORE-16748
- Display the correct TR register value.
- Ensure that the x86 segment register values displayed are really 2-byte long.
Segment registers are intrinsically 16 bits. Even if the x86 KTRAP_FRAME structure stores them as ULONG, only their lower 16 bits are initialized. We thus cast them to USHORT before display.
These segment registers are saved in a stack-based KTRAP_FRAME by the CPU trap mechanism (for SS), and by 'push CS' etc. instructions for the others, and from Intel documentation, we know that: " If the source operand is a segment register (16 bits) and the operand size is 64-bits, a zero-extended value is pushed on the stack; if the operand size is 32-bits, either a zero-extended value is pushed on the stack or the segment selector is written on the stack using a 16-bit move. For the last case, all recent Core and Atom processors perform a 16-bit move, leaving the upper portion of the stack location unmodified. " So it may happen, when using the push, that either they get zero-extended, or garbage gets stored in the higher bits, and these need to be trimmed. --- boot/freeldr/freeldr/arch/i386/i386bug.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/boot/freeldr/freeldr/arch/i386/i386bug.c b/boot/freeldr/freeldr/arch/i386/i386bug.c index f94639650f4..908ad46950c 100644 --- a/boot/freeldr/freeldr/arch/i386/i386bug.c +++ b/boot/freeldr/freeldr/arch/i386/i386bug.c @@ -140,18 +140,22 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST TrapFrame->Dr6); PrintText(" DR7: %.8lx\n\n", TrapFrame->Dr7); + + /* NOTE: Segment registers are intrinsically 16 bits. Even if the x86 + * KTRAP_FRAME structure stores them as ULONG, only their lower 16 bits + * are initialized. We thus cast them to USHORT before display. */ PrintText("CS: %.4lx EIP: %.8lx\n", - TrapFrame->SegCs, TrapFrame->Eip); + (USHORT)TrapFrame->SegCs, TrapFrame->Eip); PrintText("DS: %.4lx ERROR CODE: %.8lx\n", - TrapFrame->SegDs, TrapFrame->ErrCode); + (USHORT)TrapFrame->SegDs, TrapFrame->ErrCode); PrintText("ES: %.4lx EFLAGS: %.8lx\n", - TrapFrame->SegEs, TrapFrame->EFlags); + (USHORT)TrapFrame->SegEs, TrapFrame->EFlags); PrintText("FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n", - TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit); + (USHORT)TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit); PrintText("GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n", - TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit); + (USHORT)TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit); PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n", - TrapFrame->HardwareSegSs, Special->Ldtr, Special->Idtr.Limit); + (USHORT)TrapFrame->HardwareSegSs, Special->Ldtr, Special->Tr);
i386PrintFrames(TrapFrame); // Display frames InstructionPointer = (PUCHAR)TrapFrame->Eip; @@ -176,7 +180,7 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST PrintText("GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n", TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit); PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n", - TrapFrame->SegSs, Special->Ldtr, Special->Idtr.Limit); + TrapFrame->SegSs, Special->Ldtr, Special->Tr); InstructionPointer = (PUCHAR)TrapFrame->Rip; #endif PrintText("\nInstruction stream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x \n",