/*++\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
#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
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
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
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
ErasePolarity = FALSE;\r
InputFile = NULL;\r
OutputFile = NULL;\r
+ MapFile = NULL;\r
FvImage = NULL;\r
+\r
//\r
// Parse the command line arguments\r
//\r
}\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
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
// 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
\r
goto Finish;\r
}\r
+\r
//\r
// Get the next file\r
//\r
fclose (OutputFile);\r
}\r
\r
+ if (MapFile != NULL) {\r
+ fclose (MapFile);\r
+ }\r
+\r
if (FvImage != NULL) {\r
free (FvImage);\r
}\r
--*/\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
\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
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
} else {\r
TailSize = 0;\r
}\r
+ \r
//\r
// Do some cursory checks on the FFS file contents\r
//\r
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
) {\r
return EFI_SUCCESS;\r
}\r
+\r
//\r
// Rebase each PE32 section\r
//\r
// 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
//\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
}\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
//\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
//\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
//\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
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
return EFI_NOT_FOUND;\r
}\r
}\r
-\r
+ \r
return EFI_SUCCESS;\r
}\r
\r