]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c
Fix buffer overflow when the raw size of a section and the virtual size of a section...
[mirror_edk2.git] / Tools / Source / TianoTools / PeiRebase / PeiRebaseExe.c
index 7b48b67d2464c54927421f098ce4454716b52ba5..35329c74d69cbf08c53b5118f3dc341244fee4f2 100644 (file)
@@ -1,13 +1,13 @@
 /*++\r
 \r
-Copyright (c)  1999 - 2005 Intel Corporation. All rights reserved\r
-This software and associated documentation (if any) is furnished\r
-under a license and may only be used or copied in accordance\r
-with the terms of the license. Except as permitted by such\r
-license, no part of this software or documentation may be\r
-reproduced, stored in a retrieval system, or transmitted in any\r
-form or by any means without the express written consent of\r
-Intel Corporation.\r
+Copyright (c)  1999-2006 Intel Corporation. All rights reserved\r
+This program and the accompanying materials are licensed and made available \r
+under the terms and conditions of the BSD License which accompanies this \r
+distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 \r
 Module Name:\r
@@ -31,6 +31,7 @@ Abstract:
 #include <Common/FirmwareFileSystem.h>\r
 #include <Library/PeCoffLib.h>\r
 \r
+#include "CommonLib.h"\r
 #include "ParseInf.h"\r
 #include "FvLib.h"\r
 #include "EfiUtilityMsgs.h"\r
@@ -62,11 +63,13 @@ Arguments:
                   format is a hex number preceded by 0x.\r
   InputFileName   The name of the input FV file.\r
   OutputFileName  The name of the output FV file.\r
+  MapFileName     The name of the map file of relocation info.\r
 \r
   Arguments come in pair in any order.\r
     -I InputFileName \r
     -O OutputFileName\r
     -B BaseAddress \r
+    -M MapFileName \r
 \r
 Returns:\r
 \r
@@ -82,11 +85,13 @@ Returns:
   UINT8                       Index;\r
   CHAR8                       InputFileName[_MAX_PATH];\r
   CHAR8                       OutputFileName[_MAX_PATH];\r
+  CHAR8                       MapFileName[_MAX_PATH];\r
   EFI_PHYSICAL_ADDRESS        BaseAddress;\r
   BOOLEAN                     BaseAddressSet;\r
   EFI_STATUS                  Status;\r
   FILE                        *InputFile;\r
   FILE                        *OutputFile;\r
+  FILE                        *MapFile;\r
   UINT64                      FvOffset;\r
   UINT32                      FileCount;\r
   int                         BytesRead;\r
@@ -108,11 +113,13 @@ Returns:
     PrintUsage ();\r
     return STATUS_ERROR;\r
   }\r
+\r
   //\r
   // Initialize variables\r
   //\r
   InputFileName[0]  = 0;\r
   OutputFileName[0] = 0;\r
+  MapFileName[0]    = 0;\r
   BaseAddress       = 0;\r
   BaseAddressSet    = FALSE;\r
   FvOffset          = 0;\r
@@ -120,7 +127,9 @@ Returns:
   ErasePolarity     = FALSE;\r
   InputFile         = NULL;\r
   OutputFile        = NULL;\r
+  MapFile           = NULL;\r
   FvImage           = NULL;\r
+\r
   //\r
   // Parse the command line arguments\r
   //\r
@@ -185,6 +194,17 @@ Returns:
       }\r
       break;\r
 \r
+    case 'M':\r
+    case 'm':\r
+      if (strlen (MapFileName) == 0) {\r
+        strcpy (MapFileName, argv[Index + 1]);\r
+      } else {\r
+        PrintUsage ();\r
+        Error (NULL, 0, 0, argv[Index + 1], "only one -m MapFileName may be specified");\r
+        return STATUS_ERROR;\r
+      }\r
+      break;\r
+\r
     default:\r
       PrintUsage ();\r
       Error (NULL, 0, 0, argv[Index], "unrecognized argument");\r
@@ -192,6 +212,18 @@ Returns:
       break;\r
     }\r
   }\r
+\r
+  //\r
+  // Create the Map file if we need it\r
+  //\r
+  if (strlen (MapFileName) != 0) {\r
+    MapFile = fopen (MapFileName, "w");\r
+    if (MapFile == NULL) {\r
+      Error (NULL, 0, 0, MapFileName, "failed to open map file");\r
+      goto Finish;\r
+    }\r
+  } \r
+\r
   //\r
   // Open the file containing the FV\r
   //\r
@@ -246,7 +278,7 @@ Returns:
     // Rebase this file\r
     //\r
     CurrentFileBaseAddress  = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage);\r
-    Status                  = FfsRebase (CurrentFile, CurrentFileBaseAddress);\r
+    Status                  = FfsRebase (CurrentFile, CurrentFileBaseAddress, MapFile);\r
 \r
     if (EFI_ERROR (Status)) {\r
       switch (Status) {\r
@@ -274,6 +306,7 @@ Returns:
 \r
       goto Finish;\r
     }\r
+\r
     //\r
     // Get the next file\r
     //\r
@@ -313,6 +346,10 @@ Finish:
     fclose (OutputFile);\r
   }\r
 \r
+  if (MapFile != NULL) {\r
+    fclose (MapFile);\r
+  }\r
+\r
   if (FvImage != NULL) {\r
     free (FvImage);\r
   }\r
@@ -449,20 +486,22 @@ Returns:
 --*/\r
 {\r
   printf (\r
-    "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",\r
+    "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-M MapFile]\n",\r
     UTILITY_NAME\r
     );\r
   printf ("  Where:\n");\r
   printf ("    InputFileName is the name of the EFI FV file to rebase.\n");\r
   printf ("    OutputFileName is the desired output file name.\n");\r
   printf ("    BaseAddress is the FV base address to rebase agains.\n");\r
+  printf ("    MapFileName is an optional map file of the relocations\n");\r
   printf ("  Argument pair may be in any order.\n\n");\r
 }\r
 \r
 EFI_STATUS\r
 FfsRebase (\r
   IN OUT EFI_FFS_FILE_HEADER    *FfsFile,\r
-  IN EFI_PHYSICAL_ADDRESS       BaseAddress\r
+  IN EFI_PHYSICAL_ADDRESS       BaseAddress,\r
+  IN FILE                       *MapFile      OPTIONAL\r
   )\r
 /*++\r
 \r
@@ -475,6 +514,7 @@ Arguments:
 \r
   FfsFile           A pointer to Ffs file image.\r
   BaseAddress       The base address to use for rebasing the file image.\r
+  MapFile           Optional file to dump relocation information into\r
 \r
 Returns:\r
 \r
@@ -515,6 +555,7 @@ Returns:
   if (FfsFile == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+  \r
   //\r
   // Convert the GUID to a string so we can at least report which file\r
   // if we find an error.\r
@@ -525,6 +566,7 @@ Returns:
   } else {\r
     TailSize = 0;\r
   }\r
+  \r
   //\r
   // Do some cursory checks on the FFS file contents\r
   //\r
@@ -533,6 +575,9 @@ Returns:
     Error (NULL, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString);\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
+  memset (&ImageContext, 0, sizeof (ImageContext));\r
+\r
   //\r
   // Check if XIP file type. If not XIP, don't rebase.\r
   //\r
@@ -543,6 +588,7 @@ Returns:
       ) {\r
     return EFI_SUCCESS;\r
   }\r
+\r
   //\r
   // Rebase each PE32 section\r
   //\r
@@ -578,12 +624,12 @@ Returns:
     // Allocate a buffer for the image to be loaded into.\r
     //\r
     Pe32ImageSize       = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);\r
-    MemoryImagePointer  = (UINTN) (malloc (Pe32ImageSize + 0x1000));\r
+    MemoryImagePointer  = (UINTN) (malloc (Pe32ImageSize + 0x1000 + ImageContext.SectionAlignment));\r
     if (MemoryImagePointer == 0) {\r
       Error (NULL, 0, 0, "memory allocation failure", NULL);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);\r
+    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000 + ImageContext.SectionAlignment);\r
     MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);\r
     \r
 \r
@@ -629,14 +675,14 @@ Returns:
     //\r
     PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
     if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
     } else {\r
       Error (\r
         NULL,\r
@@ -659,6 +705,24 @@ Returns:
     }\r
 \r
     memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);\r
+    \r
+    //\r
+    // Get EntryPoint in Flash Region.\r
+    //\r
+    EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;\r
+\r
+    //\r
+    // If a map file was selected output mapping information for any file that\r
+    // was rebased.\r
+    //\r
+    if (MapFile != NULL) {\r
+      fprintf (MapFile, "PE32 File: %s Base:%08lx", FileGuidString, BaseAddress);\r
+      fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);\r
+      if (ImageContext.PdbPointer != NULL) {\r
+        fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);\r
+      }\r
+      fprintf (MapFile, "\n");\r
+    }\r
 \r
     free ((VOID *) MemoryImagePointer);\r
 \r
@@ -752,6 +816,8 @@ Returns:
     //\r
     PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));\r
     PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
+    PeHdr->OptionalHeader.AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint;\r
+    PeHdr->OptionalHeader.BaseOfCode  = TEImageHeader->BaseOfCode;\r
     PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
     PeHdr->OptionalHeader.Subsystem   = TEImageHeader->Subsystem;\r
     PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
@@ -810,13 +876,13 @@ Returns:
     //\r
     // Allocate a buffer for the image to be loaded into.\r
     //\r
-    MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));\r
+    MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000 + ImageContext.SectionAlignment));\r
     if (MemoryImagePointer == 0) {\r
       Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);\r
       free (TEBuffer);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);\r
+    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000 + ImageContext.SectionAlignment);\r
     MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);\r
     \r
 \r
@@ -849,11 +915,11 @@ Returns:
     //\r
     PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
     if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
     } else {\r
       Error (\r
         NULL,\r
@@ -883,6 +949,25 @@ Returns:
       GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
       sizeof (EFI_TE_IMAGE_HEADER)\r
       );\r
+    \r
+    //\r
+    // Get EntryPoint in Flash Region.\r
+    //\r
+    EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;\r
+\r
+    //\r
+    // If a map file was selected output mapping information for any file that\r
+    // was rebased.\r
+    //\r
+    if (MapFile != NULL) {\r
+      fprintf (MapFile, "TE   File: %s Base:%08lx", FileGuidString, BaseAddress);\r
+      fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);\r
+      if (ImageContext.PdbPointer != NULL) {\r
+        fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);\r
+      }\r
+      fprintf (MapFile, "\n");\r
+    }\r
+\r
     free ((VOID *) MemoryImagePointer);\r
     free (TEBuffer);\r
     if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
@@ -926,7 +1011,7 @@ Returns:
       return EFI_NOT_FOUND;\r
     }\r
   }\r
-\r
+  \r
   return EFI_SUCCESS;\r
 }\r
 \r