From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by mx.groups.io with SMTP id smtpd.web11.26492.1678727896978083534 for ; Mon, 13 Mar 2023 10:18:17 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=D/eU1FEJ; spf=pass (domain: kernel.org, ip: 139.178.84.217, mailfrom: ardb@kernel.org) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7DEF161381; Mon, 13 Mar 2023 17:18:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B2F2BC433A0; Mon, 13 Mar 2023 17:18:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678727895; bh=9Jr0pKk3Bj+H7S0JuwTpX7hs6Lt7uuQ4eYcPC9QUADc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D/eU1FEJ6JXNbl7e6NiP7YK6nSN425Lvx0+N6JbTLGzApKbtkBkJ5r3yck3ajKz1k uTF4MWH8y7pyf5UxADYKv/ImKWPX6cWIUwLfN/5LtpAN3iW7vUfCaDxKd0iejUTUop esoWTyuzC+9EO9aH0wlZVQkpYvFbczEUAke7gPoc2Z7lAxcZphHtT3rW3khfzntSkZ cyhJOpgmvSsBiTI+p5kV4+iq+JsVHDKRGKOkz0cKCpUhyWzL/f74a5eOwABfHexU+o 5ElvtuBK34oFaY+bOXrgOf1jB8HziEM1CqYLluMYVHQBWrEuvU0t4h6HZAMY3ZnlK4 hMBFOD08xm5HQ== From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Michael Kinney , Liming Gao , Jiewen Yao , Michael Kubacki , Sean Brogan , Rebecca Cran , Leif Lindholm , Sami Mujawar , Taylor Beebe Subject: [PATCH v5 16/38] MdePkg/BasePeCoffLib: Add API to keep track of relocation range Date: Mon, 13 Mar 2023 18:16:52 +0100 Message-Id: <20230313171714.3866151-17-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230313171714.3866151-1-ardb@kernel.org> References: <20230313171714.3866151-1-ardb@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Add a library call to obtain the start and end of the region covered by relocation fixups. This will be used in a future patch to limit the range of memory that needs to be remapped with read-write-execute permissions at ExitBootServices() time. Signed-off-by: Ard Biesheuvel --- MdePkg/Include/Library/PeCoffLib.h | 23 ++++++ MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 82 +++++++++++++++++++- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Library/PeCoffLib.h b/MdePkg/Include/Library/Pe= CoffLib.h index b45879453785..df2f7f5e5961 100644 --- a/MdePkg/Include/Library/PeCoffLib.h +++ b/MdePkg/Include/Library/PeCoffLib.h @@ -382,4 +382,27 @@ PeCoffLoaderUnloadImage ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext=0D );=0D =0D +/**=0D + Retrieve the range subject to relocation fixups from the recorded fixup = data=0D + of a runtime image=0D +=0D + @param ImageBase The base address of a PE/COFF image tha= t has been loaded=0D + and relocated into system memory.=0D + @param ImageSize The size, in bytes, of the PE/COFF imag= e.=0D + @param RelocationData A pointer to the relocation data that w= as collected when the=0D + PE/COFF image was relocated using PeCof= fLoaderRelocateImage().=0D + @param[out] RelocationRangeMin The start of the relocated range.=0D + @param[out] RelocationRangeMax The end of the relocated range.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +PeCoffLoaderGetRelocationRange (=0D + IN PHYSICAL_ADDRESS ImageBase,=0D + IN UINTN ImageSize,=0D + IN VOID *RelocationData,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMin,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMax=0D + );=0D +=0D #endif=0D diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/Bas= ePeCoffLib/BasePeCoff.c index 97a8aaf8c73d..31e1f2035963 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c @@ -936,6 +936,8 @@ PeCoffLoaderRelocateImage ( PHYSICAL_ADDRESS BaseAddress;=0D UINT32 NumberOfRvaAndSizes;=0D UINT32 TeStrippedOffset;=0D + PHYSICAL_ADDRESS *RelocRangeStart;=0D + PHYSICAL_ADDRESS *RelocRangeEnd;=0D =0D ASSERT (ImageContext !=3D NULL);=0D =0D @@ -1043,6 +1045,21 @@ PeCoffLoaderRelocateImage ( // Run the relocation information and apply the fixups=0D //=0D FixupData =3D ImageContext->FixupData;=0D + if (FixupData !=3D NULL) {=0D + FixupData =3D ALIGN_POINTER (FixupData, sizeof (PHYSICAL_ADDRESS));= =0D +=0D + //=0D + // Use the first two UINT64s in the fixup data to keep track of the = start=0D + // and end of the region that is subject to relocation fixups.=0D + //=0D + RelocRangeStart =3D (PHYSICAL_ADDRESS *)FixupData;=0D + RelocRangeEnd =3D RelocRangeStart + 1;=0D + FixupData +=3D 2 * sizeof (PHYSICAL_ADDRESS);=0D +=0D + *RelocRangeStart =3D MAX_UINT64;=0D + *RelocRangeEnd =3D 0;=0D + }=0D +=0D while ((UINTN)RelocBase < (UINTN)RelocBaseEnd) {=0D Reloc =3D (UINT16 *)((CHAR8 *)RelocBase + sizeof (EFI_IMAGE_BASE_REL= OCATION));=0D //=0D @@ -1070,6 +1087,14 @@ PeCoffLoaderRelocateImage ( return RETURN_LOAD_ERROR;=0D }=0D =0D + //=0D + // Capture this page in the recorded relocation range=0D + //=0D + if (FixupData !=3D NULL) {=0D + *RelocRangeStart =3D MIN (*RelocRangeStart, (UINTN)FixupBase);=0D + *RelocRangeEnd =3D MAX (*RelocRangeEnd, (UINTN)FixupBase + SIZE_= 4KB);=0D + }=0D +=0D //=0D // Run this relocation record=0D //=0D @@ -1470,6 +1495,9 @@ PeCoffLoaderLoadImage ( //=0D ImageContext->FixupData =3D NULL;=0D =0D + // Add two UINT64s at the start to carry the min/max of the relocated ra= nge=0D + ImageContext->FixupDataSize +=3D 2 * sizeof (PHYSICAL_ADDRESS);=0D +=0D //=0D // Load the Codeview information if present=0D //=0D @@ -1824,7 +1852,8 @@ PeCoffLoaderRelocateImageForRuntime ( // by code will not be fixed up, since that would set them back to=0D // defaults.=0D //=0D - FixupData =3D RelocationData;=0D + FixupData =3D ALIGN_POINTER (RelocationData, sizeof (PHYSICAL_ADDR= ESS));=0D + FixupData +=3D 2 * sizeof (PHYSICAL_ADDRESS);=0D RelocBaseOrig =3D RelocBase;=0D while ((UINTN)RelocBase < (UINTN)RelocBaseEnd) {=0D //=0D @@ -1994,3 +2023,54 @@ PeCoffLoaderUnloadImage ( PeCoffLoaderUnloadImageExtraAction (ImageContext);=0D return RETURN_SUCCESS;=0D }=0D +=0D +/**=0D + Retrieve the range subject to relocation fixups from the recorded fixup = data=0D + of a runtime image=0D +=0D + @param ImageBase The base address of a PE/COFF image tha= t has been loaded=0D + and relocated into system memory.=0D + @param ImageSize The size, in bytes, of the PE/COFF imag= e.=0D + @param RelocationData A pointer to the relocation data that w= as collected when the=0D + PE/COFF image was relocated using PeCof= fLoaderRelocateImage().=0D + @param[out] RelocationRangeMin The start of the relocated range.=0D + @param[out] RelocationRangeMax The end of the relocated range.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +PeCoffLoaderGetRelocationRange (=0D + IN PHYSICAL_ADDRESS ImageBase,=0D + IN UINTN ImageSize,=0D + IN VOID *RelocationData,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMin,=0D + OUT PHYSICAL_ADDRESS *RelocationRangeMax=0D + )=0D +{=0D + PHYSICAL_ADDRESS *FixupData;=0D +=0D + if ((RelocationData =3D=3D NULL) || (ImageBase =3D=3D 0x0)) {=0D + return;=0D + }=0D +=0D + FixupData =3D ALIGN_POINTER (RelocationData, sizeof (PHYSICAL_ADDRESS));= =0D +=0D + if ((FixupData[0] =3D=3D MAX_UINT64) && (FixupData[1] =3D=3D 0)) {=0D + // No fixups recorded=0D + *RelocationRangeMin =3D ImageBase;=0D + *RelocationRangeMax =3D ImageBase;=0D + return;=0D + }=0D +=0D + if ((FixupData[0] < ImageBase) ||=0D + (FixupData[1] > (ImageBase + ImageSize)))=0D + {=0D + ASSERT (FALSE);=0D + *RelocationRangeMin =3D ImageBase;=0D + *RelocationRangeMax =3D ImageBase + ImageSize;=0D + return;=0D + }=0D +=0D + *RelocationRangeMin =3D FixupData[0];=0D + *RelocationRangeMax =3D FixupData[1];=0D +}=0D --=20 2.39.2