[edk2] BaseTools/GenFv: allow TE/PE images with no .reloc section

Message ID 1471539628-6257-1-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel Aug. 18, 2016, 5 p.m.
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 <ard.biesheuvel@linaro.org>

---
 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

Patch

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
     //