From patchwork Thu Aug 18 17:00:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 74187 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp446760qga; Thu, 18 Aug 2016 10:00:37 -0700 (PDT) X-Received: by 10.66.219.200 with SMTP id pq8mr5828950pac.75.1471539637687; Thu, 18 Aug 2016 10:00:37 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id m88si108060pfi.190.2016.08.18.10.00.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Aug 2016 10:00:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 2A33C1A1E08; Thu, 18 Aug 2016 10:00:37 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x230.google.com (mail-wm0-x230.google.com [IPv6:2a00:1450:400c:c09::230]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 8EBFB1A1E04 for ; Thu, 18 Aug 2016 10:00:35 -0700 (PDT) Received: by mail-wm0-x230.google.com with SMTP id i5so5357066wmg.0 for ; Thu, 18 Aug 2016 10:00:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=D6wQzbnd1XMVrOcDuBGwPUEMh34eZ2e754FceyIy+SQ=; b=bVJV6glayCll50Mhe9KylcRTNjHcEWWZGgdxFyIjIMwdkHaQBEeAXlgRNt8d37xsn3 jMw5lm8gF8ehgc/49NR1GNXg858N91F92Wd/twhW5FMPQL65K0VvBuK86yZY+ndykbCq JvwR6cjyl782hwC8YDabkUxv9wHy80kW+bEQY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=D6wQzbnd1XMVrOcDuBGwPUEMh34eZ2e754FceyIy+SQ=; b=KsY8JEdp9NJSDIHC2SpOI3Nv+7ZPoxuotfc6p0o0ut7Q5ZZZP0HMyAs4RMAOiAbctQ DmFMlbP4oI+XBs0Cd0ZGPhhByYs4ILWsOs7jNuUjq07muNTsUcMp0RF4OJshasn8E1lU zDbw5qWZWwCldjL3s09ZEdy44jrTyZVtKTbH9e4vd5JuvvO7mkH6GecCfsmwBUV7HgL0 uQQCc9lMa2H2yzl4/CFjliYs9znC/lSb9EvddI8b4VGHYc358KInHdYaE9PkCBdxjvm7 rLePUuOCu63nDyXVSgJaOs0JD3ly/fgNGYm0z1eqLDd8O6XqFUKHcIXq+pbZSdyYJSMV a6Aw== X-Gm-Message-State: AEkoouuhTqNznDZKOqzm/qEt6OyoZlICHkfxZpgRtNVVFNOegp6femdtu08qdQphVgbMWsTi X-Received: by 10.194.21.200 with SMTP id x8mr3184349wje.129.1471539633790; Thu, 18 Aug 2016 10:00:33 -0700 (PDT) Received: from localhost.localdomain (46.red-81-37-107.dynamicip.rima-tde.net. [81.37.107.46]) by smtp.gmail.com with ESMTPSA id qe2sm3072118wjc.28.2016.08.18.10.00.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Aug 2016 10:00:32 -0700 (PDT) From: Ard Biesheuvel To: edk2-devel@lists.01.org, liming.gao@intel.com, yonghong.zhu@intel.com Date: Thu, 18 Aug 2016 19:00:28 +0200 Message-Id: <1471539628-6257-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 Subject: [edk2] [PATCH] BaseTools/GenFv: allow TE/PE images with no .reloc section X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: leif.lindholm@linaro.org, Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Currently, GenFv warns about input files without a relocation section, but still includes the FFS file in the image, but with its ImageBase field left at zero. This confuses the loader routines in PEI core, resulting in spurious write attempts to be made at the NOR flash. When using the GCC LTO compiler for AArch64, the optimizations are so effective that in some cases, all absolute symbol references are optimized away completely, resulting in a PE/COFF image that has no .reloc section at all (i.e., the PE/COFF image is position independent, but purely by accident) This means that, while unusual, it is not an error for a XIP image to have no .reloc section. So teach GenFv about this, i.e., let it skip the relocation routines, but still update the ImageBase address in the header, and recalculate the checksums. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 223 ++++++++++---------- 1 file changed, 111 insertions(+), 112 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 7c839e277944..db0978d4089d 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -3500,63 +3500,63 @@ Returns: // if (ImageContext.RelocationsStripped) { Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - continue; - } + } else { - // - // Relocation exist and rebase - // - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1)); - - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } + // + // Relocation exist and rebase + // + // + // Load and Relocate Image Data + // + MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); + if (MemoryImagePointer == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); + return EFI_OUT_OF_RESOURCES; + } + memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); + ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1)); - // - // Copy Relocated data to raw image file. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - CopyMem ( - (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); - } + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); + free ((VOID *) MemoryImagePointer); + return Status; + } - free ((VOID *) MemoryImagePointer); - MemoryImagePointer = NULL; - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; + ImageContext.DestinationAddress = NewPe32BaseAddress; + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName); + free ((VOID *) MemoryImagePointer); + return Status; + } + + // + // Copy Relocated data to raw image file. + // + SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( + (UINTN) ImgHdr + + sizeof (UINT32) + + sizeof (EFI_IMAGE_FILE_HEADER) + + ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader + ); + + for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { + CopyMem ( + (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData, + (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), + SectionHeader->SizeOfRawData + ); + } + + free ((VOID *) MemoryImagePointer); + MemoryImagePointer = NULL; + if (PeFileBuffer != NULL) { + free (PeFileBuffer); + PeFileBuffer = NULL; + } } - + // // Update Image Base Address // @@ -3730,70 +3730,69 @@ Returns: // if (ImageContext.RelocationsStripped) { Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - continue; - } + } else { + // + // Relocation exist and rebase + // + // + // Load and Relocate Image Data + // + MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); + if (MemoryImagePointer == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); + return EFI_OUT_OF_RESOURCES; + } + memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); + ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1)); - // - // Relocation exist and rebase - // - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1)); + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); + free ((VOID *) MemoryImagePointer); + return Status; + } + // + // Relocate TeImage + // + ImageContext.DestinationAddress = NewPe32BaseAddress; + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName); + free ((VOID *) MemoryImagePointer); + return Status; + } - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - // - // Reloacate TeImage - // - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName); + // + // Copy the relocated image into raw image file. + // + SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1); + for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) { + if (!ImageContext.IsTeImage) { + CopyMem ( + (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, + (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), + SectionHeader->SizeOfRawData + ); + } else { + CopyMem ( + (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, + (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), + SectionHeader->SizeOfRawData + ); + } + } + + // + // Free the allocated memory resource + // free ((VOID *) MemoryImagePointer); - return Status; - } - - // - // Copy the relocated image into raw image file. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1); - for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) { - if (!ImageContext.IsTeImage) { - CopyMem ( - (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); - } else { - CopyMem ( - (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); + MemoryImagePointer = NULL; + if (PeFileBuffer != NULL) { + free (PeFileBuffer); + PeFileBuffer = NULL; } } - - // - // Free the allocated memory resource - // - free ((VOID *) MemoryImagePointer); - MemoryImagePointer = NULL; - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; - } - + // // Update Image Base Address //