]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/Common/BasePeCoff.c
BaseTools: use set instead of list for a variable to be used with in
[mirror_edk2.git] / BaseTools / Source / C / Common / BasePeCoff.c
index 5ffb5d45032468dffdcfa96c73e928d5784bd6c5..fb7ce251221d3f49082052507255a895632e3863 100644 (file)
@@ -2,8 +2,9 @@
 \r
   Functions to get info and load PE/COFF image.\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
+Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
+This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
 http://opensource.org/licenses/bsd-license.php                                            \r
@@ -56,7 +57,7 @@ PeCoffLoaderRelocateIa32Image (
   );\r
 \r
 RETURN_STATUS\r
-PeCoffLoaderRelocateX64Image (\r
+PeCoffLoaderRelocateIpfImage (\r
   IN UINT16      *Reloc,\r
   IN OUT CHAR8   *Fixup,\r
   IN OUT CHAR8   **FixupData,\r
@@ -64,8 +65,8 @@ PeCoffLoaderRelocateX64Image (
   );\r
 \r
 RETURN_STATUS\r
-PeCoffLoaderRelocateIpfImage (\r
-  IN UINT16      *Reloc,\r
+PeCoffLoaderRelocateArmImage (\r
+  IN UINT16      **Reloc,\r
   IN OUT CHAR8   *Fixup,\r
   IN OUT CHAR8   **FixupData,\r
   IN UINT64      Adjust\r
@@ -186,7 +187,8 @@ Returns:
       ImageContext->Machine != EFI_IMAGE_MACHINE_IA64 && \\r
       ImageContext->Machine != EFI_IMAGE_MACHINE_X64  && \\r
       ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \\r
-      ImageContext->Machine != EFI_IMAGE_MACHINE_EBC) {\r
+      ImageContext->Machine != EFI_IMAGE_MACHINE_EBC  && \\r
+      ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64) {\r
     if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {\r
       //\r
       // There are two types of ARM images. Pure ARM and ARM/Thumb. \r
@@ -334,7 +336,7 @@ Returns:
   //\r
   if ((!(ImageContext->IsTeImage)) && ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
     ImageContext->RelocationsStripped = TRUE;\r
-  } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0)) {\r
+  } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0) && (TeHdr->DataDirectory[0].VirtualAddress == 0)) {\r
     ImageContext->RelocationsStripped = TRUE;\r
   } else {\r
     ImageContext->RelocationsStripped = FALSE;\r
@@ -601,6 +603,7 @@ Returns:
   CHAR8                                 *FixupBase;\r
   UINT16                                *F16;\r
   UINT32                                *F32;\r
+  UINT64                                *F64;\r
   CHAR8                                 *FixupData;\r
   PHYSICAL_ADDRESS                      BaseAddress;\r
   UINT16                                MachineType;\r
@@ -621,15 +624,10 @@ Returns:
   }\r
 \r
   //\r
-  // If the destination address is not 0, use that rather than the\r
-  // image address as the relocation target.\r
+  // Use DestinationAddress field of ImageContext as the relocation address even if it is 0.\r
   //\r
-  if (ImageContext->DestinationAddress) {\r
-    BaseAddress = ImageContext->DestinationAddress;\r
-  } else {\r
-    BaseAddress = ImageContext->ImageAddress;\r
-  }\r
-\r
+  BaseAddress = ImageContext->DestinationAddress;\r
+  \r
   if (!(ImageContext->IsTeImage)) {\r
     PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN)ImageContext->ImageAddress + \r
                                             ImageContext->PeCoffHeaderOffset);\r
@@ -647,11 +645,22 @@ Returns:
       //\r
       if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
         RelocDir  = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
-        RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
-        RelocBaseEnd = PeCoffLoaderImageAddress (\r
-                        ImageContext,\r
-                        RelocDir->VirtualAddress + RelocDir->Size - 1\r
-                        );\r
+        if ((RelocDir != NULL) && (RelocDir->Size > 0)) {\r
+          RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+          RelocBaseEnd = PeCoffLoaderImageAddress (\r
+                           ImageContext,\r
+                           RelocDir->VirtualAddress + RelocDir->Size - 1\r
+                           );\r
+          if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {\r
+            ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+            return RETURN_LOAD_ERROR;\r
+          }\r
+        } else {\r
+          //\r
+          // Set base and end to bypass processing below.\r
+          //\r
+          RelocBase = RelocBaseEnd = 0;\r
+        }\r
       } else {\r
         //\r
         // Set base and end to bypass processing below.\r
@@ -671,11 +680,22 @@ Returns:
       //\r
       if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
         RelocDir  = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
-        RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
-        RelocBaseEnd = PeCoffLoaderImageAddress (\r
-                        ImageContext,\r
-                        RelocDir->VirtualAddress + RelocDir->Size - 1\r
-                        );\r
+        if ((RelocDir != NULL) && (RelocDir->Size > 0)) {\r
+          RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+          RelocBaseEnd = PeCoffLoaderImageAddress (\r
+                           ImageContext,\r
+                           RelocDir->VirtualAddress + RelocDir->Size - 1\r
+                          );\r
+          if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {\r
+            ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+            return RETURN_LOAD_ERROR;\r
+          }\r
+        } else {\r
+          //\r
+          // Set base and end to bypass processing below.\r
+          //\r
+          RelocBase = RelocBaseEnd = 0;\r
+        }\r
       } else {\r
         //\r
         // Set base and end to bypass processing below.\r
@@ -712,6 +732,10 @@ Returns:
     RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
     if (!(ImageContext->IsTeImage)) {\r
       FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
+      if (FixupBase == NULL) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
     } else {\r
       FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
                     RelocBase->VirtualAddress +\r
@@ -765,6 +789,16 @@ Returns:
         }\r
         break;\r
 \r
+      case EFI_IMAGE_REL_BASED_DIR64:\r
+        F64   = (UINT64 *) Fixup;\r
+        *F64  = *F64 + (UINT64) Adjust;\r
+        if (FixupData != NULL) {\r
+          FixupData             = ALIGN_POINTER (FixupData, sizeof (UINT64));\r
+          *(UINT64 *) FixupData = *F64;\r
+          FixupData             = FixupData + sizeof (UINT64);\r
+        }\r
+        break;\r
+\r
       case EFI_IMAGE_REL_BASED_HIGHADJ:\r
         //\r
         // Return the same EFI_UNSUPPORTED return code as\r
@@ -777,11 +811,10 @@ Returns:
       default:\r
         switch (MachineType) {\r
         case EFI_IMAGE_MACHINE_IA32:\r
-        case EFI_IMAGE_MACHINE_ARMT:\r
           Status = PeCoffLoaderRelocateIa32Image (Reloc, Fixup, &FixupData, Adjust);\r
           break;\r
-        case EFI_IMAGE_MACHINE_X64:\r
-          Status = PeCoffLoaderRelocateX64Image (Reloc, Fixup, &FixupData, Adjust);\r
+        case EFI_IMAGE_MACHINE_ARMT:\r
+          Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);\r
           break;\r
         case EFI_IMAGE_MACHINE_IA64:\r
           Status = PeCoffLoaderRelocateIpfImage (Reloc, Fixup, &FixupData, Adjust);\r
@@ -974,14 +1007,7 @@ Returns:
             ImageContext,\r
             Section->VirtualAddress + Section->Misc.VirtualSize - 1\r
             );\r
-    if (ImageContext->IsTeImage) {\r
-      Base  = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
-      End   = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
-    }\r
 \r
-    if (End > MaxEnd) {\r
-      MaxEnd = End;\r
-    }\r
     //\r
     // If the base start or end address resolved to 0, then fail.\r
     //\r
@@ -990,6 +1016,16 @@ Returns:
       return RETURN_LOAD_ERROR;\r
     }\r
 \r
+       \r
+    if (ImageContext->IsTeImage) {\r
+      Base  = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
+      End   = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
+    }\r
+\r
+    if (End > MaxEnd) {\r
+      MaxEnd = End;\r
+    }\r
+\r
     //\r
     // Read the section\r
     //\r
@@ -1044,12 +1080,10 @@ Returns:
                                                                 PeHdr->Pe32.OptionalHeader.AddressOfEntryPoint\r
                                                                 );\r
   } else {\r
-    ImageContext->EntryPoint =  (PHYSICAL_ADDRESS) (\r
-                       (UINTN)ImageContext->ImageAddress +\r
-                       (UINTN)TeHdr->AddressOfEntryPoint +\r
-                       (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
-          (UINTN) TeHdr->StrippedSize\r
-      );\r
+    ImageContext->EntryPoint = (UINTN)ImageContext->ImageAddress +\r
+                               (UINTN)TeHdr->AddressOfEntryPoint +\r
+                               (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
+                               (UINTN) TeHdr->StrippedSize;\r
   }\r
 \r
   //\r