ArmVirtPkg/PrePi: use standard PeCoff routines for self-relocation

Instead of having a GCC specific routine to perform self-relocation
based on ELF metadata, use the PE/COFF metadata and the existing
PeCoff library routines. This reduces the amount of bespoke assembler
code that is a burden to maintain, and is not portable across the set
of toolchains we support.

This does require some special care, as we have no control over how
the C code references global symbols, so we need to emit these
references from the calling assembler code. Otherwise, they may be
emitted as absolute references, in which case they need to be fixed
up themselves, leading to a circular dependency.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Sami Mujawar <Sami.Mujawar@arm.com>
This commit is contained in:
Ard Biesheuvel
2020-06-08 13:07:54 +02:00
committed by mergify[bot]
parent fd708fe0e1
commit b16fd231f6
6 changed files with 68 additions and 87 deletions

View File

@@ -9,6 +9,7 @@
#include <PiPei.h>
#include <Pi/PiBootMode.h>
#include <Library/PeCoffLib.h>
#include <Library/PrePiLib.h>
#include <Library/PrintLib.h>
#include <Library/PrePiHobListPointerLib.h>
@@ -128,3 +129,37 @@ CEntryPoint (
// DXE Core should always load and never return
ASSERT (FALSE);
}
VOID
RelocatePeCoffImage (
IN EFI_PEI_FV_HANDLE FwVolHeader,
IN PE_COFF_LOADER_READ_FILE ImageRead
)
{
EFI_PEI_FILE_HANDLE FileHandle;
VOID *SectionData;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_STATUS Status;
FileHandle = NULL;
Status = FfsFindNextFile (EFI_FV_FILETYPE_SECURITY_CORE, FwVolHeader,
&FileHandle);
ASSERT_EFI_ERROR (Status);
Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData);
if (EFI_ERROR (Status)) {
Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData);
}
ASSERT_EFI_ERROR (Status);
ZeroMem (&ImageContext, sizeof ImageContext);
ImageContext.Handle = (EFI_HANDLE)SectionData;
ImageContext.ImageRead = ImageRead;
PeCoffLoaderGetImageInfo (&ImageContext);
if (ImageContext.ImageAddress != (UINTN)SectionData) {
ImageContext.ImageAddress = (UINTN)SectionData;
PeCoffLoaderRelocateImage (&ImageContext);
}
}