[UEFILDR][FREELDR] Some x64 ABI violations and memory map fixes (#8668)

* [UEFILDR][FREELDR] Don't let LoaderPangesSpanned span half of mem space
* [FREELDR][UEFILDR] Fix x64 ABI Violations
This commit is contained in:
Justin Miller
2026-02-14 16:26:20 -08:00
committed by GitHub
parent 23d38f4b64
commit c8907598f5
4 changed files with 27 additions and 12 deletions

View File

@@ -32,6 +32,14 @@ _exituefi:
xor rbp, rbp
mov rsp, qword ptr UefiServiceStack[rip]
/*
* Maintain the MS x64 ABI for calls into C/firmware:
* - 16-byte alignment at call site
* - 32-byte shadow space reserved by the caller
*/
and rsp, -16
sub rsp, HEX(20)
/* Call the entry routine, passing the parameters */
mov rax, UefiExitBootServices[rip]
call rax
@@ -57,9 +65,18 @@ _exituefi:
// void _changestack(VOID)
PUBLIC _changestack
_changestack:
/* Preserve the current stack pointer as an argument */
mov rax, rsp
/* Switch to the basic stack top */
mov rsp, BasicStack[rip]
push rax
/* Ensure proper MS x64 ABI alignment and shadow space */
and rsp, -16
sub rsp, HEX(20)
/* ExecuteLoaderCleanly(PVOID PreviousStack) */
mov rcx, rax
call ExecuteLoaderCleanly[rip]
ret

View File

@@ -82,6 +82,7 @@ Quit:
return 0;
}
DECLSPEC_NORETURN
void
ExecuteLoaderCleanly(PVOID PreviousStack)
{
@@ -89,6 +90,7 @@ ExecuteLoaderCleanly(PVOID PreviousStack)
UefiServiceStack = PreviousStack;
RunLoader();
Reboot();
UNREACHABLE;
}

View File

@@ -27,7 +27,6 @@ AddMemoryDescriptor(
/* GLOBALS *******************************************************************/
extern ULONG LoaderPagesSpanned;
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
extern EFI_HANDLE GlobalImageHandle;
@@ -215,16 +214,6 @@ UefiMemGetMemoryMap(ULONG *MemoryMapSize)
}
}
/* Sometimes our loader can be loaded into higher memory than we ever allocate */
if (MemoryType == LoaderLoadedProgram)
{
if (((MapEntry->PhysicalStart + (MapEntry->NumberOfPages * PAGE_SIZE)) >> EFI_PAGE_SHIFT) > LoaderPagesSpanned)
{
/* This value needs to be adjusted if this occurs */
LoaderPagesSpanned = ((MapEntry->PhysicalStart + (MapEntry->NumberOfPages * PAGE_SIZE)) >> EFI_PAGE_SHIFT);
}
}
/* We really don't want to touch these reserved spots at all */
if (MemoryType != LoaderReserve)
{

View File

@@ -326,6 +326,13 @@ WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
#ifdef UEFIBOOT
extern PVOID OsLoaderBase;
extern SIZE_T OsLoaderSize;
/* UEFILDR can be above the 2GB-ish range, we don't want to map the whole area */
Status = MempSetupPaging((ULONG_PTR)OsLoaderBase / PAGE_SIZE, OsLoaderSize / PAGE_SIZE, FALSE);
#endif
// Map our loader image, so we can continue running
/*Status = MempSetupPaging(OsLoaderBase >> MM_PAGE_SHIFT, OsLoaderSize >> MM_PAGE_SHIFT);
if (!Status)