From patchwork Fri Jul 3 09:40:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 50619 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f72.google.com (mail-la0-f72.google.com [209.85.215.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id E7B84214B3 for ; Fri, 3 Jul 2015 09:41:13 +0000 (UTC) Received: by laer2 with SMTP id r2sf26697504lae.3 for ; Fri, 03 Jul 2015 02:41:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:reply-to:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :content-type:content-transfer-encoding:errors-to:x-original-sender :x-original-authentication-results:mailing-list; bh=48e4VqPg+CYcDC7VsIP5X/I4ACHoHCblS0JAQHQ71GQ=; b=XjAPbxB20xwCY3UL4DsrY84G5DLBuoSIIL6BYDuxvjDnirc7EImHKcv2G1JU1grNn3 Vxo+MlxRntMdnjoaJ45KJD17aTFsZq2zYAIFEZrj8jK6q8yHBWjr+DWQBKZsHOeTLNIU aU3TY47lNYunqZ6aJR1sbCVOCJnSG3Ulsy1YuU4Svp/0UenM5BByslBQMmayMn8wId6M mxZ+mPLjBtmNqQDJpgFVT+N3SzVaiWWUWYoMJrd57QEL5/qK4ze3d90KZ/o/5hQwc/9O vKz8G7tYgoICg9mcGbwR11/E4kBtbYJtiQGuVacBwWQqaY4PnY06la0yuCA601BgVTIk MfHA== X-Gm-Message-State: ALoCoQnmpfBmH3R+s6zdBnQpZAlv7DEbS/645GNfEyT69hb2nNhjkYNzJLNo3pTfCvhf1BehRpos X-Received: by 10.112.188.233 with SMTP id gd9mr22152466lbc.12.1435916472899; Fri, 03 Jul 2015 02:41:12 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.8.111 with SMTP id q15ls401117laa.28.gmail; Fri, 03 Jul 2015 02:41:12 -0700 (PDT) X-Received: by 10.152.205.67 with SMTP id le3mr34888425lac.50.1435916472745; Fri, 03 Jul 2015 02:41:12 -0700 (PDT) Received: from mail-la0-f42.google.com (mail-la0-f42.google.com. [209.85.215.42]) by mx.google.com with ESMTPS id gz7si6738553lac.176.2015.07.03.02.41.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Jul 2015 02:41:12 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) client-ip=209.85.215.42; Received: by lagc2 with SMTP id c2so78747720lag.3 for ; Fri, 03 Jul 2015 02:41:12 -0700 (PDT) X-Received: by 10.112.126.101 with SMTP id mx5mr35581559lbb.35.1435916472275; Fri, 03 Jul 2015 02:41:12 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp1046509lbb; Fri, 3 Jul 2015 02:41:11 -0700 (PDT) X-Received: by 10.107.11.17 with SMTP id v17mr51110660ioi.83.1435916469895; Fri, 03 Jul 2015 02:41:09 -0700 (PDT) Received: from lists.sourceforge.net (lists.sourceforge.net. [216.34.181.88]) by mx.google.com with ESMTPS id z5si4883501igg.2.2015.07.03.02.41.02 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 03 Jul 2015 02:41:09 -0700 (PDT) Received-SPF: pass (google.com: domain of edk2-devel-bounces@lists.sourceforge.net designates 216.34.181.88 as permitted sender) client-ip=216.34.181.88; Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ZAxSl-0005p8-4P; Fri, 03 Jul 2015 09:40:51 +0000 Received: from sog-mx-3.v43.ch3.sourceforge.com ([172.29.43.193] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ZAxSj-0005ow-QS for edk2-devel@lists.sourceforge.net; Fri, 03 Jul 2015 09:40:49 +0000 Received-SPF: pass (sog-mx-3.v43.ch3.sourceforge.com: domain of linaro.org designates 209.85.212.182 as permitted sender) client-ip=209.85.212.182; envelope-from=ard.biesheuvel@linaro.org; helo=mail-wi0-f182.google.com; Received: from mail-wi0-f182.google.com ([209.85.212.182]) by sog-mx-3.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1ZAxSi-0003hV-Bo for edk2-devel@lists.sourceforge.net; Fri, 03 Jul 2015 09:40:49 +0000 Received: by wiwl6 with SMTP id l6so221432620wiw.0 for ; Fri, 03 Jul 2015 02:40:42 -0700 (PDT) X-Received: by 10.180.77.68 with SMTP id q4mr23912786wiw.22.1435916442321; Fri, 03 Jul 2015 02:40:42 -0700 (PDT) Received: from localhost.localdomain ([185.13.106.72]) by mx.google.com with ESMTPSA id fa8sm12986803wib.14.2015.07.03.02.40.37 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Jul 2015 02:40:41 -0700 (PDT) From: Ard Biesheuvel To: edk2-devel@lists.sourceforge.net, michael.d.kinney@intel.com, Jiewen.Yao@intel.com, liming.gao@intel.com, jordan.l.justen@intel.com Date: Fri, 3 Jul 2015 11:40:06 +0200 Message-Id: <1435916407-29683-6-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1435916407-29683-1-git-send-email-ard.biesheuvel@linaro.org> References: <1435916407-29683-1-git-send-email-ard.biesheuvel@linaro.org> X-Spam-Score: -1.5 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record -0.0 AWL AWL: Adjusted score from AWL reputation of From: address X-Headers-End: 1ZAxSi-0003hV-Bo Subject: [edk2] [PATCH 5/6] MdePkg/BasePeCoffLib: relocate for runtime using ConvertPointer callback X-BeenThere: edk2-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list Reply-To: edk2-devel@lists.sourceforge.net List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.sourceforge.net X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 The OS is not required to preserve the relative offsets between RuntimeServicesCode and RuntimeServicesData memory regions when switching to virtual mode. This does not present any problems as long as PE/COFF images in memory are covered by only a single region. However, with the introduction of the MemoryProtectionAttribute feature in UEFI v2.5, the firmware may decide to split those regions into separate code and data regions. So rather than reapplying the relocations for the entire image based on a single adjustment value (which is derived from the physical to virtual shift of ImageBase), we need to invoke ConvertPointer () on each relocation target. So modify PeCoffLoaderRelocateImageForRuntime () to take a callback function pointer instead of a fixed adjustment value, and invoke the callback for each re-relocated value. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- MdePkg/Include/Library/PeCoffLib.h | 28 ++++++++++++---- MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c | 19 ++++++----- MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 35 +++++++++++--------- MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h | 16 ++++----- MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c | 32 +++++++++--------- MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c | 16 ++++----- 6 files changed, 83 insertions(+), 63 deletions(-) diff --git a/MdePkg/Include/Library/PeCoffLib.h b/MdePkg/Include/Library/PeCoffLib.h index 9ed6d61be01c..ed75f3613306 100644 --- a/MdePkg/Include/Library/PeCoffLib.h +++ b/MdePkg/Include/Library/PeCoffLib.h @@ -335,6 +335,22 @@ PeCoffLoaderImageReadFromMemory ( OUT VOID *Buffer ); +/** + Translates a physical to virtual address for PE/COFF runtime re-relocation + + @param[in, out] Address A pointer to a pointer that is to be fixed to be the value needed + for the new virtual address mappings being applied. + + @retval EFI_SUCCESS The pointer pointed to by Address was modified. + @retval EFI_INVALID_PARAMETER Address is NULL. + @retval EFI_NOT_FOUND The value pointed to by Address could not be converted. + +**/ +typedef +RETURN_STATUS +(EFIAPI *PE_COFF_LOADER_CONVERT_POINTER) ( + IN OUT VOID **Address + ); /** Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI @@ -352,8 +368,8 @@ PeCoffLoaderImageReadFromMemory ( @param ImageBase The base address of a PE/COFF image that has been loaded and relocated into system memory. - @param VirtImageBase The request virtual address that the PE/COFF image is to - be fixed up for. + @param ConvertPointer Address of a PE_COFF_LOADER_CONVERT_POINTER callback function + that performs physical to virtual conversions @param ImageSize The size, in bytes, of the PE/COFF image. @param RelocationData A pointer to the relocation data that was collected when the PE/COFF image was relocated using PeCoffLoaderRelocateImage(). @@ -362,10 +378,10 @@ PeCoffLoaderImageReadFromMemory ( VOID EFIAPI PeCoffLoaderRelocateImageForRuntime ( - IN PHYSICAL_ADDRESS ImageBase, - IN PHYSICAL_ADDRESS VirtImageBase, - IN UINTN ImageSize, - IN VOID *RelocationData + IN PHYSICAL_ADDRESS ImageBase, + IN PE_COFF_LOADER_CONVERT_POINTER ConvertPointer, + IN UINTN ImageSize, + IN VOID *RelocationData ); /** diff --git a/MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c b/MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c index d6bf42738d2b..ba09e1f16018 100644 --- a/MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c +++ b/MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c @@ -205,20 +205,20 @@ PeCoffLoaderImageFormatSupported ( instruction sets. This is used to re-relocated the image into the EFI virtual space for runtime calls. - @param Reloc The pointer to the relocation record. - @param Fixup The pointer to the address to fix up. - @param FixupData The pointer to a buffer to log the fixups. - @param Adjust The offset to adjust the fixup. + @param Reloc The pointer to the relocation record. + @param Fixup The pointer to the address to fix up. + @param FixupData The pointer to a buffer to log the fixups. + @param ConvertPointer Pointer to a physical to virtual conversion function @return Status code. **/ RETURN_STATUS PeHotRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN PE_COFF_LOADER_CONVERT_POINTER ConvertPointer ) { UINT16 *Fixup16; @@ -231,7 +231,8 @@ PeHotRelocateImageEx ( case EFI_IMAGE_REL_BASED_ARM_MOV32T: *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64)); if (*(UINT64 *) (*FixupData) == ReadUnaligned64 ((UINT64 *)Fixup16)) { - FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust; + FixupVal = ThumbMovwMovtImmediateAddress (Fixup16); + ConvertPointer ((VOID **) &FixupVal); ThumbMovwMovtImmediatePatch (Fixup16, FixupVal); } break; diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c index 23cb691ad729..e4de6fae7ce9 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c @@ -1692,8 +1692,8 @@ PeCoffLoaderLoadImage ( @param ImageBase The base address of a PE/COFF image that has been loaded and relocated into system memory. - @param VirtImageBase The request virtual address that the PE/COFF image is to - be fixed up for. + @param ConvertPointer Address of a PE_COFF_LOADER_CONVERT_POINTER callback function + that performs physical to virtual conversions @param ImageSize The size, in bytes, of the PE/COFF image. @param RelocationData A pointer to the relocation data that was collected when the PE/COFF image was relocated using PeCoffLoaderRelocateImage(). @@ -1702,14 +1702,13 @@ PeCoffLoaderLoadImage ( VOID EFIAPI PeCoffLoaderRelocateImageForRuntime ( - IN PHYSICAL_ADDRESS ImageBase, - IN PHYSICAL_ADDRESS VirtImageBase, - IN UINTN ImageSize, - IN VOID *RelocationData + IN PHYSICAL_ADDRESS ImageBase, + IN PE_COFF_LOADER_CONVERT_POINTER ConvertPointer, + IN UINTN ImageSize, + IN VOID *RelocationData ) { CHAR8 *OldBase; - CHAR8 *NewBase; EFI_IMAGE_DOS_HEADER *DosHdr; EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; UINT32 NumberOfRvaAndSizes; @@ -1725,15 +1724,13 @@ PeCoffLoaderRelocateImageForRuntime ( UINT32 *Fixup32; UINT64 *Fixup64; CHAR8 *FixupData; - UINTN Adjust; RETURN_STATUS Status; UINT16 Magic; UINT8 HighLowMask [SIZE_4KB / (8 * sizeof(UINT32))]; UINTN HighLowMaskIndex; + UINTN ConvertAddress; OldBase = (CHAR8 *)((UINTN)ImageBase); - NewBase = (CHAR8 *)((UINTN)VirtImageBase); - Adjust = (UINTN) NewBase - (UINTN) OldBase; // // Find the image's relocate dir info @@ -1842,7 +1839,9 @@ PeCoffLoaderRelocateImageForRuntime ( if (*(UINT32 *) FixupData == *Fixup32 || (HighLowMask [HighLowMaskIndex >> 3] & (1 << (HighLowMaskIndex & 7))) != 0) { - *Fixup16 = (UINT16) ((*Fixup32 + (UINT32) Adjust) >> 16); + ConvertAddress = *(UINT32 *) FixupData; + ConvertPointer ((VOID **) &ConvertAddress); + *Fixup16 = (UINT16) (ConvertAddress >> 16); // // Mark this location in the page as requiring the low relocation to @@ -1862,7 +1861,9 @@ PeCoffLoaderRelocateImageForRuntime ( if (*(UINT32 *) FixupData == *(UINT32 *)Fixup || (HighLowMask [HighLowMaskIndex >> 3] & (1 << (HighLowMaskIndex & 7))) != 0) { - *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) Adjust & 0xffff)); + ConvertAddress = *(UINT32 *) FixupData; + ConvertPointer ((VOID **) &ConvertAddress); + *Fixup16 = (UINT16) (ConvertAddress & 0xffff); // // Mark this location in the page as requiring the high relocation to @@ -1879,7 +1880,9 @@ PeCoffLoaderRelocateImageForRuntime ( Fixup32 = (UINT32 *) Fixup; FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32)); if (*(UINT32 *) FixupData == *Fixup32) { - *Fixup32 = *Fixup32 + (UINT32) Adjust; + ConvertAddress = *Fixup32; + ConvertPointer ((VOID **) &ConvertAddress); + *Fixup32 = (UINT32) ConvertAddress; } FixupData = FixupData + sizeof (UINT32); @@ -1889,7 +1892,9 @@ PeCoffLoaderRelocateImageForRuntime ( Fixup64 = (UINT64 *)Fixup; FixupData = ALIGN_POINTER (FixupData, sizeof (UINT64)); if (*(UINT64 *) FixupData == *Fixup64) { - *Fixup64 = *Fixup64 + (UINT64)Adjust; + ConvertAddress = (UINTN) *Fixup64; + ConvertPointer ((VOID **) &ConvertAddress); + *Fixup64 = ConvertAddress; } FixupData = FixupData + sizeof (UINT64); @@ -1899,7 +1904,7 @@ PeCoffLoaderRelocateImageForRuntime ( // // Only Itanium requires ConvertPeImage_Ex // - Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust); + Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, ConvertPointer); if (RETURN_ERROR (Status)) { return ; } diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h index 0851acc18c19..9ffc59318f9b 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h @@ -50,20 +50,20 @@ PeCoffLoaderRelocateImageEx ( instruction sets. This is used to re-relocated the image into the EFI virtual space for runtime calls. - @param Reloc The pointer to the relocation record. - @param Fixup The pointer to the address to fix up. - @param FixupData The pointer to a buffer to log the fixups. - @param Adjust The offset to adjust the fixup. + @param Reloc The pointer to the relocation record. + @param Fixup The pointer to the address to fix up. + @param FixupData The pointer to a buffer to log the fixups. + @param ConvertPointer Pointer to a physical to virtual conversion function @return Status code. **/ RETURN_STATUS PeHotRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN PE_COFF_LOADER_CONVERT_POINTER ConvertPointer ); diff --git a/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c b/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c index a590f3906fab..bd371a33a445 100644 --- a/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c +++ b/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c @@ -242,25 +242,23 @@ PeCoffLoaderImageFormatSupported ( /** - ImageRead function that operates on a memory buffer whos base is passed into - FileHandle. - - @param Reloc Ponter to baes of the input stream - @param Fixup Offset to the start of the buffer - @param FixupData The number of bytes to copy into the buffer - @param Adjust Location to place results of read - - @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into - the buffer. - @retval RETURN_UNSUPPORTED Un-recoganized relocation entry - type. + Performs an Itanium-based specific re-relocation fixup and is a no-op on other + instruction sets. This is used to re-relocated the image into the EFI virtual + space for runtime calls. + + @param Reloc The pointer to the relocation record. + @param Fixup The pointer to the address to fix up. + @param FixupData The pointer to a buffer to log the fixups. + @param ConvertPointer Pointer to a physical to virtual conversion function + + @return Status code. **/ RETURN_STATUS PeHotRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN PE_COFF_LOADER_CONVERT_POINTER ConvertPointer ) { UINT64 *Fixup64; @@ -325,7 +323,7 @@ PeHotRelocateImageEx ( // // Update 64-bit address // - FixupVal += Adjust; + ConvertPointer ((VOID **) &FixupVal); // // Insert IMM64 into bundle diff --git a/MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c b/MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c index 01825c85392b..8ddf6fe722f8 100644 --- a/MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c +++ b/MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c @@ -69,20 +69,20 @@ PeCoffLoaderImageFormatSupported ( instruction sets. This is used to re-relocated the image into the EFI virtual space for runtime calls. - @param Reloc The pointer to the relocation record. - @param Fixup The pointer to the address to fix up. - @param FixupData The pointer to a buffer to log the fixups. - @param Adjust The offset to adjust the fixup. + @param Reloc The pointer to the relocation record. + @param Fixup The pointer to the address to fix up. + @param FixupData The pointer to a buffer to log the fixups. + @param ConvertPointer Pointer to a physical to virtual conversion function @return Status code. **/ RETURN_STATUS PeHotRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN PE_COFF_LOADER_CONVERT_POINTER ConvertPointer ) { return RETURN_UNSUPPORTED;