]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePeCoffLib/BasePeCoff.c
MdePkg: Refine casting expression result to bigger size
[mirror_edk2.git] / MdePkg / Library / BasePeCoffLib / BasePeCoff.c
index 6f056e519ef6739be54fa816670932c454fc713b..8d1daba4bbe5cc5a2361ff2d3b08b1f7ad8cd160 100644 (file)
@@ -15,7 +15,7 @@
   PeCoffLoaderGetPeHeader() routine will do basic check for PE/COFF header.\r
   PeCoffLoaderGetImageInfo() routine will do basic check for whole PE/COFF image.\r
 \r
-  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
   Portions copyright (c) 2008 - 2009, Apple Inc. 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
 \r
 #include "BasePeCoffLibInternals.h"\r
 \r
+/**\r
+  Adjust some fields in section header for TE image.\r
+\r
+  @param  SectionHeader             Pointer to the section header.\r
+  @param  TeStrippedOffset          Size adjust for the TE image.\r
+\r
+**/\r
+VOID\r
+PeCoffLoaderAdjustOffsetForTeImage (\r
+  EFI_IMAGE_SECTION_HEADER              *SectionHeader,\r
+  UINT32                                TeStrippedOffset\r
+  )\r
+{\r
+  SectionHeader->VirtualAddress   -= TeStrippedOffset;\r
+  SectionHeader->PointerToRawData -= TeStrippedOffset;\r
+}\r
+\r
 /**\r
   Retrieves the magic value from the PE/COFF header.\r
 \r
@@ -157,6 +174,50 @@ PeCoffLoaderGetPeHeader (
     ImageContext->SectionAlignment  = 0;\r
     ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;\r
 \r
+    //\r
+    // Check the StrippedSize.\r
+    //\r
+    if (sizeof (EFI_TE_IMAGE_HEADER) >= (UINT32)Hdr.Te->StrippedSize) {\r
+      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    //\r
+    // Check the SizeOfHeaders field.\r
+    //\r
+    if (Hdr.Te->BaseOfCode <= Hdr.Te->StrippedSize) {\r
+      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    //\r
+    // Read last byte of Hdr.Te->SizeOfHeaders from the file.\r
+    //\r
+    Size = 1;\r
+    ReadSize = Size;\r
+    Status = ImageContext->ImageRead (\r
+                             ImageContext->Handle,\r
+                             ImageContext->SizeOfHeaders - 1,\r
+                             &Size,\r
+                             &BufferData\r
+                             );\r
+    if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+      if (Size != ReadSize) {\r
+        Status = RETURN_UNSUPPORTED;\r
+      }\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // TE Image Data Directory Entry size is non-zero, but the Data Directory Virtual Address is zero.\r
+    // This case is not a valid TE image. \r
+    //\r
+    if ((Hdr.Te->DataDirectory[0].Size != 0 && Hdr.Te->DataDirectory[0].VirtualAddress == 0) ||\r
+        (Hdr.Te->DataDirectory[1].Size != 0 && Hdr.Te->DataDirectory[1].VirtualAddress == 0)) {\r
+      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
   } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE)  {\r
     ImageContext->IsTeImage = FALSE;\r
     ImageContext->Machine = Hdr.Pe32->FileHeader.Machine;\r
@@ -188,6 +249,10 @@ PeCoffLoaderGetPeHeader (
       //\r
       // 3. Check the FileHeader.NumberOfSections field.\r
       //\r
+      if (Hdr.Pe32->OptionalHeader.SizeOfImage <= SectionHeaderOffset) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
       if ((Hdr.Pe32->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32->FileHeader.NumberOfSections) {\r
         ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
         return RETURN_UNSUPPORTED;\r
@@ -196,6 +261,14 @@ PeCoffLoaderGetPeHeader (
       //\r
       // 4. Check the OptionalHeader.SizeOfHeaders field.\r
       //\r
+      if (Hdr.Pe32->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+      if (Hdr.Pe32->OptionalHeader.SizeOfHeaders >= Hdr.Pe32->OptionalHeader.SizeOfImage) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
       if ((Hdr.Pe32->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32->FileHeader.NumberOfSections) {\r
         ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
         return RETURN_UNSUPPORTED;\r
@@ -290,6 +363,10 @@ PeCoffLoaderGetPeHeader (
       //\r
       // 3. Check the FileHeader.NumberOfSections field.\r
       //\r
+      if (Hdr.Pe32Plus->OptionalHeader.SizeOfImage <= SectionHeaderOffset) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
       if ((Hdr.Pe32Plus->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32Plus->FileHeader.NumberOfSections) {\r
         ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
         return RETURN_UNSUPPORTED;\r
@@ -298,6 +375,14 @@ PeCoffLoaderGetPeHeader (
       //\r
       // 4. Check the OptionalHeader.SizeOfHeaders field.\r
       //\r
+      if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+      if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders >= Hdr.Pe32Plus->OptionalHeader.SizeOfImage) {\r
+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
       if ((Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32Plus->FileHeader.NumberOfSections) {\r
         ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
         return RETURN_UNSUPPORTED;\r
@@ -417,6 +502,13 @@ PeCoffLoaderGetPeHeader (
       return Status;\r
     }\r
 \r
+    //\r
+    // Adjust some field in Section Header for TE image.\r
+    //\r
+    if (ImageContext->IsTeImage) {\r
+      PeCoffLoaderAdjustOffsetForTeImage (&SectionHeader, (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
+    }\r
+\r
     if (SectionHeader.SizeOfRawData > 0) {\r
       //\r
       // Section data should bigger than the Pe header.\r
@@ -514,6 +606,7 @@ PeCoffLoaderGetImageInfo (
   EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       DebugEntry;\r
   UINT32                                NumberOfRvaAndSizes;\r
   UINT16                                Magic;\r
+  UINT32                                TeStrippedOffset;\r
 \r
   if (ImageContext == NULL) {\r
     return RETURN_INVALID_PARAMETER;\r
@@ -535,6 +628,7 @@ PeCoffLoaderGetImageInfo (
   // Retrieve the base address of the image\r
   //\r
   if (!(ImageContext->IsTeImage)) {\r
+    TeStrippedOffset = 0;\r
     if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
       //\r
       // Use PE32 offset\r
@@ -547,7 +641,8 @@ PeCoffLoaderGetImageInfo (
       ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;\r
     }\r
   } else {\r
-    ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
+    TeStrippedOffset = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);\r
+    ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + TeStrippedOffset);\r
   }\r
 \r
   //\r
@@ -581,15 +676,6 @@ PeCoffLoaderGetImageInfo (
   } else {\r
     ImageContext->RelocationsStripped = FALSE;\r
   }\r
-  \r
-  //\r
-  // TE Image Relocation Data Directory Entry size is non-zero, but the Relocation Data Directory Virtual Address is zero.\r
-  // This case is not a valid TE image. \r
-  //\r
-  if ((ImageContext->IsTeImage) && (Hdr.Te->DataDirectory[0].Size != 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {\r
-    ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
 \r
   if (!(ImageContext->IsTeImage)) {\r
     if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
@@ -617,12 +703,10 @@ PeCoffLoaderGetImageInfo (
       //\r
       DebugDirectoryEntryFileOffset = 0;\r
 \r
-      SectionHeaderOffset = (UINTN)(\r
-                               ImageContext->PeCoffHeaderOffset +\r
-                               sizeof (UINT32) +\r
-                               sizeof (EFI_IMAGE_FILE_HEADER) +\r
-                               Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
-                               );\r
+      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +\r
+                            sizeof (UINT32) +\r
+                            sizeof (EFI_IMAGE_FILE_HEADER) +\r
+                            Hdr.Pe32->FileHeader.SizeOfOptionalHeader;\r
 \r
       for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
         //\r
@@ -723,9 +807,8 @@ PeCoffLoaderGetImageInfo (
           DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
         DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -\r
                                         SectionHeader.VirtualAddress +\r
-                                        SectionHeader.PointerToRawData +\r
-                                        sizeof (EFI_TE_IMAGE_HEADER) -\r
-                                        Hdr.Te->StrippedSize;\r
+                                        SectionHeader.PointerToRawData -\r
+                                        TeStrippedOffset;\r
 \r
         //\r
         // File offset of the debug directory was found, if this is not the last\r
@@ -749,7 +832,7 @@ PeCoffLoaderGetImageInfo (
       // Section Table.  \r
       //\r
       if ((++Index) == (UINTN)Hdr.Te->NumberOfSections) {\r
-        ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize);\r
+        ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) - TeStrippedOffset;\r
       }\r
 \r
       SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
@@ -791,8 +874,9 @@ PeCoffLoaderGetImageInfo (
 /**\r
   Converts an image address to the loaded address.\r
 \r
-  @param  ImageContext  The context of the image being loaded.\r
-  @param  Address       The relative virtual address to be converted to the loaded address.\r
+  @param  ImageContext      The context of the image being loaded.\r
+  @param  Address           The address to be converted to the loaded address.\r
+  @param  TeStrippedOffset  Stripped offset for TE image.\r
 \r
   @return The converted address or NULL if the address can not be converted.\r
 \r
@@ -800,18 +884,19 @@ PeCoffLoaderGetImageInfo (
 VOID *\r
 PeCoffLoaderImageAddress (\r
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,\r
-  IN     UINTN                                 Address\r
+  IN     UINTN                                 Address, \r
+  IN     UINTN                                 TeStrippedOffset\r
   )\r
 {\r
   //\r
   // Make sure that Address and ImageSize is correct for the loaded image.\r
   //\r
-  if (Address >= ImageContext->ImageSize) {\r
+  if (Address >= ImageContext->ImageSize + TeStrippedOffset) {\r
     ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
     return NULL;\r
   }\r
 \r
-  return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address);\r
+  return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address - TeStrippedOffset);\r
 }\r
 \r
 /**\r
@@ -854,6 +939,7 @@ PeCoffLoaderRelocateImage (
   EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
   EFI_IMAGE_DATA_DIRECTORY              *RelocDir;\r
   UINT64                                Adjust;\r
+  EFI_IMAGE_BASE_RELOCATION             *RelocBaseOrg;\r
   EFI_IMAGE_BASE_RELOCATION             *RelocBase;\r
   EFI_IMAGE_BASE_RELOCATION             *RelocBaseEnd;\r
   UINT16                                *Reloc;\r
@@ -867,6 +953,7 @@ PeCoffLoaderRelocateImage (
   PHYSICAL_ADDRESS                      BaseAddress;\r
   UINT32                                NumberOfRvaAndSizes;\r
   UINT16                                Magic;\r
+  UINT32                                TeStrippedOffset;\r
 \r
   ASSERT (ImageContext != NULL);\r
 \r
@@ -897,7 +984,7 @@ PeCoffLoaderRelocateImage (
 \r
   if (!(ImageContext->IsTeImage)) {\r
     Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
-\r
+    TeStrippedOffset = 0;\r
     Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
 \r
     if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
@@ -930,48 +1017,40 @@ PeCoffLoaderRelocateImage (
     // is present in the image. You have to check the NumberOfRvaAndSizes in\r
     // the optional header to verify a desired directory entry is there.\r
     //\r
-\r
-    if ((NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) && (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) {\r
-        return RETURN_LOAD_ERROR;\r
-      }\r
-    } else {\r
-      //\r
-      // Set base and end to bypass processing below.\r
-      //\r
-      RelocBase = RelocBaseEnd = NULL;\r
+    if ((NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC)) {\r
+      RelocDir = NULL;\r
     }\r
   } else {\r
     Hdr.Te             = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
-    Adjust             = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->ImageBase);\r
+    TeStrippedOffset   = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);\r
+    Adjust             = (UINT64) (BaseAddress - (Hdr.Te->ImageBase + TeStrippedOffset));\r
     if (Adjust != 0) {\r
-      Hdr.Te->ImageBase  = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
+      Hdr.Te->ImageBase  = (UINT64) (BaseAddress - TeStrippedOffset);\r
     }\r
 \r
     //\r
     // Find the relocation block\r
     //\r
     RelocDir = &Hdr.Te->DataDirectory[0];\r
-    if (RelocDir->Size > 0) {\r
-      RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
-                                      ImageContext->ImageAddress +\r
-                                      RelocDir->VirtualAddress +\r
-                                      sizeof(EFI_TE_IMAGE_HEADER) -\r
-                                      Hdr.Te->StrippedSize\r
-                                      );\r
-      RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
-    } else {\r
-      //\r
-      // Set base and end to bypass processing below.\r
-      //\r
-      RelocBase = RelocBaseEnd = NULL;    \r
+  }\r
+\r
+  if ((RelocDir != NULL) && (RelocDir->Size > 0)) {\r
+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);\r
+    RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext,\r
+                                                                            RelocDir->VirtualAddress + RelocDir->Size - 1,\r
+                                                                            TeStrippedOffset\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 = NULL;    \r
   }\r
+  RelocBaseOrg = RelocBase;\r
 \r
   //\r
   // If Adjust is not zero, then apply fix ups to the image\r
@@ -984,36 +1063,38 @@ PeCoffLoaderRelocateImage (
     while (RelocBase < RelocBaseEnd) {\r
 \r
       Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
-      RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
-      \r
       //\r
-      // Make sure RelocEnd is in the Image range.\r
+      // Add check for RelocBase->SizeOfBlock field.\r
       //\r
-      if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN) ImageContext->ImageAddress) ||\r
-          (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + (UINTN)ImageContext->ImageSize)) {\r
+      if (RelocBase->SizeOfBlock == 0) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
+      if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) {\r
         ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
         return RETURN_LOAD_ERROR;\r
       }\r
 \r
-      if (!(ImageContext->IsTeImage)) {\r
-        FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
-        if (FixupBase == NULL) {\r
-          return RETURN_LOAD_ERROR;\r
-        }\r
-      } else {\r
-        FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
-                      RelocBase->VirtualAddress +\r
-                      sizeof(EFI_TE_IMAGE_HEADER) -\r
-                      Hdr.Te->StrippedSize\r
-                      );\r
-      }    \r
+      RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
+      if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
+      FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);\r
+      if (FixupBase == NULL) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return RETURN_LOAD_ERROR;\r
+      }  \r
 \r
       //\r
       // Run this relocation record\r
       //\r
       while (Reloc < RelocEnd) {\r
-\r
-        Fixup = FixupBase + (*Reloc & 0xFFF);\r
+        Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);\r
+        if (Fixup == NULL) {\r
+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+          return RETURN_LOAD_ERROR;\r
+        }\r
         switch ((*Reloc) >> 12) {\r
         case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
           break;\r
@@ -1080,6 +1161,7 @@ PeCoffLoaderRelocateImage (
       //\r
       RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
     }\r
+    ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);\r
 \r
     //\r
     // Adjust the EntryPoint to match the linked-to address\r
@@ -1155,7 +1237,7 @@ PeCoffLoaderLoadImage (
   EFI_IMAGE_RESOURCE_DATA_ENTRY         *ResourceDataEntry;\r
   CHAR16                                *String;\r
   UINT32                                Offset;\r
-\r
+  UINT32                                TeStrippedOffset;\r
 \r
   ASSERT (ImageContext != NULL);\r
 \r
@@ -1242,6 +1324,7 @@ PeCoffLoaderLoadImage (
                       Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
       );\r
     NumberOfSections = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections);\r
+    TeStrippedOffset = 0;\r
   } else {\r
     Status = ImageContext->ImageRead (\r
                             ImageContext->Handle,\r
@@ -1251,13 +1334,12 @@ PeCoffLoaderLoadImage (
                             );\r
 \r
     Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
-\r
     FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
                       (UINTN)ImageContext->ImageAddress +\r
                       sizeof(EFI_TE_IMAGE_HEADER)\r
                       );\r
     NumberOfSections  = (UINTN) (Hdr.Te->NumberOfSections);\r
-\r
+    TeStrippedOffset  = (UINT32) Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);\r
   }\r
 \r
   if (RETURN_ERROR (Status)) {\r
@@ -1281,11 +1363,8 @@ PeCoffLoaderLoadImage (
     //\r
     // Compute sections address\r
     //\r
-    Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);\r
-    End = PeCoffLoaderImageAddress (\r
-            ImageContext,\r
-            Section->VirtualAddress + Section->Misc.VirtualSize - 1\r
-            );\r
+    Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress, TeStrippedOffset);\r
+    End  = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress + Section->Misc.VirtualSize - 1, TeStrippedOffset);\r
 \r
     //\r
     // If the size of the section is non-zero and the base address or end address resolved to 0, then fail.\r
@@ -1295,28 +1374,13 @@ PeCoffLoaderLoadImage (
       return RETURN_LOAD_ERROR;\r
     }\r
 \r
-    if (ImageContext->IsTeImage) {\r
-      Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
-      End  = (CHAR8 *)((UINTN) End +  sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
-    }\r
-\r
     if (Section->SizeOfRawData > 0) {\r
-      if (!(ImageContext->IsTeImage)) {\r
-        Status = ImageContext->ImageRead (\r
-                                ImageContext->Handle,\r
-                                Section->PointerToRawData,\r
-                                &Size,\r
-                                Base\r
-                                );\r
-      } else {\r
-        Status = ImageContext->ImageRead (\r
-                                ImageContext->Handle,\r
-                                Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize,\r
-                                &Size,\r
-                                Base\r
-                                );\r
-      }\r
-\r
+      Status = ImageContext->ImageRead (\r
+                              ImageContext->Handle,\r
+                              Section->PointerToRawData - TeStrippedOffset,\r
+                              &Size,\r
+                              Base\r
+                              );\r
       if (RETURN_ERROR (Status)) {\r
         ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
         return Status;\r
@@ -1351,7 +1415,8 @@ PeCoffLoaderLoadImage (
       //\r
       ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (\r
                                                             ImageContext,\r
-                                                            (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint\r
+                                                            (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint,\r
+                                                            0\r
                                                             );\r
     } else {\r
       //\r
@@ -1359,16 +1424,16 @@ PeCoffLoaderLoadImage (
       //\r
       ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (\r
                                                             ImageContext,\r
-                                                            (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint\r
+                                                            (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint,\r
+                                                            0\r
                                                             );\r
     }\r
   } else {\r
-    ImageContext->EntryPoint =  (PHYSICAL_ADDRESS) (\r
-                                (UINTN)ImageContext->ImageAddress  +\r
-                                (UINTN)Hdr.Te->AddressOfEntryPoint +\r
-                                (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
-                                (UINTN)Hdr.Te->StrippedSize\r
-                                );\r
+    ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (\r
+                                                          ImageContext,\r
+                                                          (UINTN)Hdr.Te->AddressOfEntryPoint,\r
+                                                          TeStrippedOffset\r
+                                                          );\r
   }\r
 \r
   //\r
@@ -1393,14 +1458,17 @@ PeCoffLoaderLoadImage (
       DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
     }\r
 \r
+    //\r
+    // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.\r
+    //\r
     if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
-      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);\r
     } else {\r
       ImageContext->FixupDataSize = 0;\r
     }\r
   } else {\r
     DirectoryEntry              = &Hdr.Te->DataDirectory[0];\r
-    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);\r
   }\r
   //\r
   // Consumer must allocate a buffer for the relocation fixup log.\r
@@ -1412,107 +1480,82 @@ PeCoffLoaderLoadImage (
   // Load the Codeview information if present\r
   //\r
   if (ImageContext->DebugDirectoryEntryRva != 0) {\r
-    if (!(ImageContext->IsTeImage)) {\r
-      DebugEntry = PeCoffLoaderImageAddress (\r
-                    ImageContext,\r
-                    ImageContext->DebugDirectoryEntryRva\r
-                    );\r
-    } else {\r
-      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
-                      ImageContext->ImageAddress +\r
-                      ImageContext->DebugDirectoryEntryRva +\r
-                      sizeof(EFI_TE_IMAGE_HEADER) -\r
-                      Hdr.Te->StrippedSize\r
-                      );\r
+    DebugEntry = PeCoffLoaderImageAddress (\r
+                ImageContext,\r
+                ImageContext->DebugDirectoryEntryRva,\r
+                TeStrippedOffset\r
+                );\r
+    if (DebugEntry == NULL) {\r
+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+      return RETURN_LOAD_ERROR;\r
     }\r
 \r
-    if (DebugEntry != NULL) {\r
-      TempDebugEntryRva = DebugEntry->RVA;\r
-      if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {\r
-        Section--;\r
-        if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
-          TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;\r
-        } else {\r
-          TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;\r
-        }\r
+    TempDebugEntryRva = DebugEntry->RVA;\r
+    if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {\r
+      Section--;\r
+      if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
+        TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;\r
+      } else {\r
+        TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;\r
       }\r
+    }\r
 \r
-      if (TempDebugEntryRva != 0) {\r
-        if (!(ImageContext->IsTeImage)) {\r
-          ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);\r
-        } else {\r
-          ImageContext->CodeView = (VOID *)(\r
-                                    (UINTN)ImageContext->ImageAddress +\r
-                                    (UINTN)TempDebugEntryRva +\r
-                                    (UINTN)sizeof (EFI_TE_IMAGE_HEADER) -\r
-                                    (UINTN) Hdr.Te->StrippedSize\r
-                                    );\r
-        }\r
+    if (TempDebugEntryRva != 0) {\r
+      ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva, TeStrippedOffset); \r
+      if (ImageContext->CodeView == NULL) {\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return RETURN_LOAD_ERROR;\r
+      }\r
+\r
+      if (DebugEntry->RVA == 0) {\r
+        Size = DebugEntry->SizeOfData;\r
+        Status = ImageContext->ImageRead (\r
+                                ImageContext->Handle,\r
+                                DebugEntry->FileOffset - TeStrippedOffset,\r
+                                &Size,\r
+                                ImageContext->CodeView\r
+                                );\r
+        //\r
+        // Should we apply fix up to this field according to the size difference between PE and TE?\r
+        // Because now we maintain TE header fields unfixed, this field will also remain as they are\r
+        // in original PE image.\r
+        //\r
 \r
-        if (ImageContext->CodeView == NULL) {\r
+        if (RETURN_ERROR (Status)) {\r
           ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
           return RETURN_LOAD_ERROR;\r
         }\r
 \r
-        if (DebugEntry->RVA == 0) {\r
-          Size = DebugEntry->SizeOfData;\r
-          if (!(ImageContext->IsTeImage)) {\r
-            Status = ImageContext->ImageRead (\r
-                                    ImageContext->Handle,\r
-                                    DebugEntry->FileOffset,\r
-                                    &Size,\r
-                                    ImageContext->CodeView\r
-                                    );\r
-          } else {\r
-            Status = ImageContext->ImageRead (\r
-                                    ImageContext->Handle,\r
-                                    DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize,\r
-                                    &Size,\r
-                                    ImageContext->CodeView\r
-                                    );\r
-            //\r
-            // Should we apply fix up to this field according to the size difference between PE and TE?\r
-            // Because now we maintain TE header fields unfixed, this field will also remain as they are\r
-            // in original PE image.\r
-            //\r
-          }\r
-\r
-          if (RETURN_ERROR (Status)) {\r
-            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
-            return RETURN_LOAD_ERROR;\r
-          }\r
+        DebugEntry->RVA = TempDebugEntryRva;\r
+      }\r
 \r
-          DebugEntry->RVA = TempDebugEntryRva;\r
+      switch (*(UINT32 *) ImageContext->CodeView) {\r
+      case CODEVIEW_SIGNATURE_NB10:\r
+        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) {\r
+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+          return RETURN_UNSUPPORTED;\r
         }\r
+        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+        break;\r
 \r
-        switch (*(UINT32 *) ImageContext->CodeView) {\r
-        case CODEVIEW_SIGNATURE_NB10:\r
-          if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) {\r
-            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
-            return RETURN_UNSUPPORTED;\r
-          }\r
-          ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
-          break;\r
-\r
-        case CODEVIEW_SIGNATURE_RSDS:\r
-          if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) {\r
-            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
-            return RETURN_UNSUPPORTED;\r
-          }\r
-          ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
-          break;\r
-\r
-        case CODEVIEW_SIGNATURE_MTOC:\r
-          if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) {\r
-            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
-            return RETURN_UNSUPPORTED;\r
-          }\r
-          ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);\r
-          break;\r
+      case CODEVIEW_SIGNATURE_RSDS:\r
+        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) {\r
+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+          return RETURN_UNSUPPORTED;\r
+        }\r
+        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+        break;\r
 \r
-        default:\r
-          break;\r
+      case CODEVIEW_SIGNATURE_MTOC:\r
+        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) {\r
+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;\r
+          return RETURN_UNSUPPORTED;\r
         }\r
+        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);\r
+        break;\r
+\r
+      default:\r
+        break;\r
       }\r
     }\r
   }\r
@@ -1537,7 +1580,7 @@ PeCoffLoaderLoadImage (
     }\r
 \r
     if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && DirectoryEntry->Size != 0) {\r
-      Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress);\r
+      Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress, 0);\r
       if (Base != NULL) {\r
         ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) Base;\r
         Offset = sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * \r
@@ -1612,7 +1655,7 @@ PeCoffLoaderLoadImage (
                   return RETURN_UNSUPPORTED;\r
                 }\r
                 ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + ResourceDirectoryEntry->u2.OffsetToData);\r
-                ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData);\r
+                ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData, 0);\r
                 break;\r
               }\r
             }\r
@@ -1819,13 +1862,6 @@ PeCoffLoaderRelocateImageForRuntime (
         FixupData = FixupData + sizeof (UINT64);\r
         break;\r
 \r
-      case EFI_IMAGE_REL_BASED_HIGHADJ:\r
-        //\r
-        // Not valid Relocation type for UEFI image, ASSERT\r
-        //\r
-        ASSERT (FALSE);\r
-        break;\r
-\r
       default:\r
         //\r
         // Only Itanium requires ConvertPeImage_Ex\r