From 3f0beb9fa3ba7436e1b0595096ffcb193f4220e1 Mon Sep 17 00:00:00 2001 From: Bruno Achauer Date: Tue, 21 Feb 2023 17:40:13 +0100 Subject: [PATCH] Ensure that ELF images are loaded at their preferred address (#1833) Currently, loading an ELF image will relocate the image (to its preferred load address) only if there is at least one ELF segment that is not completely contained in the file loaded (i.e. the memory segment size is larger than the size inside the file. This behavior is generally triggered by the segment that contains the .bss section). Consequently, images that contain initialized data only (e.g. QNX IFS files) don't get relocated, and will usually crash when jumping to the image entry point. This change checks whether the ELF image is already loaded at the preferred address, and forces image relocation if not. Signed-off-by: Bruno Achauer --- BootloaderCommonPkg/Library/ElfLib/ElfLib.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/BootloaderCommonPkg/Library/ElfLib/ElfLib.c b/BootloaderCommonPkg/Library/ElfLib/ElfLib.c index 4e863363..f53a0d76 100644 --- a/BootloaderCommonPkg/Library/ElfLib/ElfLib.c +++ b/BootloaderCommonPkg/Library/ElfLib/ElfLib.c @@ -1,7 +1,7 @@ /** @file ELF library - Copyright (c) 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -242,6 +242,7 @@ ParseElfImage ( UINTN End; UINTN Base; UINTN FileOffset; + UINT8 *CurrentLoadAddress; if (ElfCt == NULL) { return EFI_INVALID_PARAMETER; @@ -317,10 +318,14 @@ ParseElfImage ( // ElfCt->ImageSize = End - Base + 1; ElfCt->PreferredImageAddress = (VOID *) Base; + CurrentLoadAddress = ElfCt->FileBase + FileOffset; + if (ElfCt->PreferredImageAddress != CurrentLoadAddress) { + ElfCt->ReloadRequired = TRUE; + } if (ElfCt->ReloadRequired) { ElfCt->ImageAddress = NULL; } else { - ElfCt->ImageAddress = ElfCt->FileBase + FileOffset; + ElfCt->ImageAddress = CurrentLoadAddress; } CalculateElfFileSize (ElfCt, &ElfCt->FileSize);