mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[FREELDR:UEFI] Fix amd64 assembly calling convention and GDT reload (#8698)
- Fix #GP crash on UEFI x64 boot caused by `call ExecuteLoaderCleanly[rip]` and `mov rax, UefiExitBootServices[rip]; call rax` generating indirect calls that read function code bytes as a pointer. - Reload CS and data segments after `lgdt` to avoid #GP from stale UEFI selectors (e.g. CS=0x38) exceeding the new GDT limit.
This commit is contained in:
@@ -41,8 +41,7 @@ _exituefi:
|
||||
sub rsp, HEX(20)
|
||||
|
||||
/* Call the entry routine, passing the parameters */
|
||||
mov rax, UefiExitBootServices[rip]
|
||||
call rax
|
||||
call UefiExitBootServices
|
||||
|
||||
/* Retore old stack */
|
||||
mov rsp, rbx
|
||||
@@ -53,12 +52,44 @@ _exituefi:
|
||||
pop rsi
|
||||
pop rbp
|
||||
|
||||
/*
|
||||
* We are now outside firmware services and about to replace the GDT.
|
||||
* Keep maskable interrupts disabled during this transition window.
|
||||
*/
|
||||
cli
|
||||
|
||||
#ifdef _USE_ML
|
||||
lgdt fword ptr [_gdtptr]
|
||||
#else
|
||||
lgdt cs:[_gdtptr][rip] /* GAS isn't my friend - avoid letting it generate absolute addressing */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Reload CS with a valid selector from the new GDT.
|
||||
* The UEFI firmware's CS (e.g. 0x38) may exceed our GDT limit,
|
||||
* so we must load CS=0x10 (long mode code segment) via far return.
|
||||
*/
|
||||
#ifdef _USE_ML
|
||||
lea rax, [reload_cs]
|
||||
#else
|
||||
lea rax, reload_cs[rip]
|
||||
#endif
|
||||
push HEX(10)
|
||||
push rax
|
||||
.byte HEX(48), HEX(CB) /* retfq */
|
||||
|
||||
reload_cs:
|
||||
/* Reload data segments with DS selector 0x18 */
|
||||
mov ax, HEX(18)
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
/* SS must use a ring-0 writable data selector */
|
||||
mov ax, HEX(28)
|
||||
mov ss, ax
|
||||
|
||||
/* All done */
|
||||
ret
|
||||
|
||||
@@ -77,7 +108,7 @@ _changestack:
|
||||
|
||||
/* ExecuteLoaderCleanly(PVOID PreviousStack) */
|
||||
mov rcx, rax
|
||||
call ExecuteLoaderCleanly[rip]
|
||||
call ExecuteLoaderCleanly
|
||||
ret
|
||||
|
||||
.align 8
|
||||
@@ -89,10 +120,11 @@ gdt:
|
||||
.word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 20: 16-bit real mode CS */
|
||||
.word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 28: 16-bit real mode DS */
|
||||
.word HEX(FFFF), HEX(0000), HEX(9B00), HEX(00CF) /* 30: compat mode CS */
|
||||
.word HEX(0000), HEX(0000), HEX(9800), HEX(0020) /* 38: long mode CS (UEFI selector compatibility) */
|
||||
|
||||
/* GDT table pointer */
|
||||
_gdtptr:
|
||||
.word HEX(37) /* Limit */
|
||||
.word HEX(3F) /* Limit */
|
||||
#ifdef _USE_ML
|
||||
.quad gdt /* Base Address */
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user