summaryrefslogtreecommitdiff
path: root/Tools/CCode/Source/PeiRebase
diff options
context:
space:
mode:
authorbxing <bxing@6f19259b-4bc3-4df7-8a09-765794883524>2006-12-30 09:17:16 +0000
committerbxing <bxing@6f19259b-4bc3-4df7-8a09-765794883524>2006-12-30 09:17:16 +0000
commit8733430b83565480540d1d890986cbf22c54db0d (patch)
treea53fa90f7b3ed378eb58d46971572c792814599a /Tools/CCode/Source/PeiRebase
parent242c77a08512363429e22a2e1cceb77274a7ef44 (diff)
downloadedk2-8733430b83565480540d1d890986cbf22c54db0d.zip
edk2-8733430b83565480540d1d890986cbf22c54db0d.tar.gz
edk2-8733430b83565480540d1d890986cbf22c54db0d.tar.bz2
1. Added a new tool GenFvMap, which is able to generate FV map files upon LOG files generated by PeiRebase.
2. Updated PeiRebase to generate LOG files while processing FV images. The original MAP feature and its corresponding option '-M' are dropped, however, they are superceded by the FV map file. 3. The FV map file are not generated yet. My next check-in will update FPD files to generate FV map files. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2157 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Tools/CCode/Source/PeiRebase')
-rw-r--r--Tools/CCode/Source/PeiRebase/PeiRebaseExe.c612
-rw-r--r--Tools/CCode/Source/PeiRebase/PeiRebaseExe.h17
2 files changed, 359 insertions, 270 deletions
diff --git a/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c b/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c
index 2d28a83..11192c4 100644
--- a/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c
+++ b/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c
@@ -1,8 +1,8 @@
/*++
Copyright (c) 1999-2006 Intel Corporation. All rights reserved
-This program and the accompanying materials are licensed and made available
-under the terms and conditions of the BSD License which accompanies this
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
@@ -59,23 +59,21 @@ Arguments:
argc - Number of command line arguments
argv[]:
- BaseAddress The base address to use for rebasing the FV. The correct
+ BaseAddress The base address to use for rebasing the FV. The correct
format is a hex number preceded by 0x.
InputFileName The name of the input FV file.
OutputFileName The name of the output FV file.
- MapFileName The name of the map file of relocation info.
Arguments come in pair in any order.
- -I InputFileName
+ -I InputFileName
-O OutputFileName
- -B BaseAddress
- -M MapFileName
+ -B BaseAddress
Returns:
0 No error conditions detected.
1 One or more of the input parameters is invalid.
- 2 A resource required by the utility was unavailable.
+ 2 A resource required by the utility was unavailable.
Most commonly this will be memory allocation or file creation.
3 PeiRebase.dll could not be loaded.
4 Error executing the PEI rebase.
@@ -84,14 +82,13 @@ Returns:
{
UINT8 Index;
CHAR8 InputFileName[_MAX_PATH];
- CHAR8 OutputFileName[_MAX_PATH];
- CHAR8 MapFileName[_MAX_PATH];
- EFI_PHYSICAL_ADDRESS BaseAddress;
- BOOLEAN BaseAddressSet;
+ CHAR8 *OutputFileName;
+ EFI_PHYSICAL_ADDRESS XipBase, BsBase, RtBase;
+ UINT32 BaseTypes;
EFI_STATUS Status;
FILE *InputFile;
FILE *OutputFile;
- FILE *MapFile;
+ FILE *LogFile;
UINT64 FvOffset;
UINT32 FileCount;
int BytesRead;
@@ -99,11 +96,8 @@ Returns:
UINT32 FvSize;
EFI_FFS_FILE_HEADER *CurrentFile;
BOOLEAN ErasePolarity;
- EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress;
- CHAR8 InfFileName[_MAX_PATH];
- CHAR8 *InfFileImage;
- UINTN InfFileSize;
MEMORY_FILE InfMemoryFile;
+ CHAR8 StringBuffer[0x100];
ErasePolarity = FALSE;
//
@@ -121,21 +115,17 @@ Returns:
//
// Initialize variables
//
- InputFileName[0] = 0;
- OutputFileName[0] = 0;
- MapFileName[0] = 0;
- BaseAddress = 0;
- BaseAddressSet = FALSE;
+ InputFileName[0] = '\0';
+ OutputFileName = NULL;
+ XipBase = BsBase = RtBase = 0;
+ BaseTypes = 0;
FvOffset = 0;
FileCount = 0;
ErasePolarity = FALSE;
InputFile = NULL;
OutputFile = NULL;
- MapFile = NULL;
+ LogFile = NULL;
FvImage = NULL;
- InfFileImage = NULL;
- InfFileSize = 0;
- strcpy (InfFileName, "");
//
// Parse the command line arguments
@@ -156,7 +146,7 @@ Returns:
PrintUsage ();
Error (NULL, 0, 0, argv[Index], "unrecognized option");
return STATUS_ERROR;
- }
+ }
//
// Determine argument to read
//
@@ -174,8 +164,8 @@ Returns:
case 'O':
case 'o':
- if (strlen (OutputFileName) == 0) {
- strcpy (OutputFileName, argv[Index + 1]);
+ if (OutputFileName == NULL) {
+ OutputFileName = argv[Index + 1];
} else {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");
@@ -183,79 +173,86 @@ Returns:
}
break;
+ case 'F':
+ case 'f':
+ //
+ // Load INF file into memory & initialize MEMORY_FILE structure
+ //
+ Status = GetFileImage (argv[Index + 1], &InfMemoryFile.FileImage, (UINT32*)&InfMemoryFile.Eof);
+ InfMemoryFile.Eof = InfMemoryFile.FileImage + (UINT32)(UINTN)InfMemoryFile.Eof;
+ InfMemoryFile.CurrentFilePointer = InfMemoryFile.FileImage;
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 0, argv[Index + 1], "Error opening FvInfFile");
+ return STATUS_ERROR;
+ }
+
+ //
+ // Read BaseAddress from fv.inf file
+ //
+ FindToken (&InfMemoryFile, "[options]", "EFI_BASE_ADDRESS", 0, StringBuffer);
+
+ //
+ // Free INF file image
+ //
+ free (InfMemoryFile.FileImage);
+
+ //
+ // Point argv[Index + 1] to StringBuffer so that it could be processed as "-b"
+ //
+ argv[Index + 1] = StringBuffer;
+
case 'B':
case 'b':
- if (!BaseAddressSet) {
- Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress);
- if (EFI_ERROR (Status)) {
- PrintUsage ();
- Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address");
- return STATUS_ERROR;
- }
+ if (BaseTypes & 1) {
+ PrintUsage ();
+ Error (NULL, 0, 0, argv[Index + 1], "XipBaseAddress may be specified only once by either -b or -f");
+ return STATUS_ERROR;
+ }
- BaseAddressSet = TRUE;
- } else {
+ Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &XipBase);
+ if (EFI_ERROR (Status)) {
PrintUsage ();
- Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once");
+ Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for XIP base address");
return STATUS_ERROR;
}
+
+ BaseTypes |= 1;
break;
- case 'F':
- case 'f':
- if (!BaseAddressSet) {
- strcpy (InfFileName, argv[Index + 1]);
- //
- // Read the INF file image
- //
- Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);
- if (EFI_ERROR (Status)) {
- PrintUsage ();
- Error (NULL, 0, 0, argv[Index + 1], "-f FvInfFile can't be opened.");
- return STATUS_ERROR;
- }
- //
- // Initialize file structures
- //
- InfMemoryFile.FileImage = InfFileImage;
- InfMemoryFile.CurrentFilePointer = InfFileImage;
- InfMemoryFile.Eof = InfFileImage + InfFileSize;
- //
- // Read BaseAddress from fv.inf file.
- //
- FindToken (&InfMemoryFile, "[options]", "EFI_BASE_ADDRESS", 0, InfFileName);
- //
- // free Inf File Image
- //
- free (InfFileImage);
-
- //
- // Convert string to UINT64 base address.
- //
- Status = AsciiStringToUint64 (InfFileName, FALSE, &BaseAddress);
- if (EFI_ERROR (Status)) {
- PrintUsage ();
- Error (NULL, 0, 0, argv[Index + 1], "can't find the base address in the specified fv.inf file.");
- return STATUS_ERROR;
- }
+ case 'D':
+ case 'd':
+ if (BaseTypes & 2) {
+ PrintUsage ();
+ Error (NULL, 0, 0, argv[Index + 1], "-d BsBaseAddress may be specified only once");
+ return STATUS_ERROR;
+ }
- BaseAddressSet = TRUE;
- } else {
+ Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BsBase);
+ if (EFI_ERROR (Status)) {
PrintUsage ();
- Error (NULL, 0, 0, argv[Index + 1], "BaseAddress has been got once from fv.inf or the specified base address.");
+ Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for BS_DRIVER base address");
return STATUS_ERROR;
}
+
+ BaseTypes |= 2;
break;
- case 'M':
- case 'm':
- if (strlen (MapFileName) == 0) {
- strcpy (MapFileName, argv[Index + 1]);
- } else {
+ case 'R':
+ case 'r':
+ if (BaseTypes & 4) {
+ PrintUsage ();
+ Error (NULL, 0, 0, argv[Index + 1], "-r RtBaseAddress may be specified only once");
+ return STATUS_ERROR;
+ }
+
+ Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &RtBase);
+ if (EFI_ERROR (Status)) {
PrintUsage ();
- Error (NULL, 0, 0, argv[Index + 1], "only one -m MapFileName may be specified");
+ Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for RT_DRIVER base address");
return STATUS_ERROR;
}
+
+ BaseTypes |= 4;
break;
default:
@@ -265,18 +262,6 @@ Returns:
break;
}
}
-
- //
- // Create the Map file if we need it
- //
- if (strlen (MapFileName) != 0) {
- MapFile = fopen (MapFileName, "w");
- if (MapFile == NULL) {
- Error (NULL, 0, 0, MapFileName, "failed to open map file");
- goto Finish;
- }
- }
-
//
// Open the file containing the FV
//
@@ -285,6 +270,16 @@ Returns:
Error (NULL, 0, 0, InputFileName, "could not open input file for reading");
return STATUS_ERROR;
}
+
+ //
+ // Open the log file
+ //
+ strcat (InputFileName, ".log");
+ LogFile = fopen (InputFileName, "a");
+ if (LogFile == NULL) {
+ Error (NULL, 0, 0, InputFileName, "could not append to log file");
+ }
+
//
// Determine size of FV
//
@@ -330,8 +325,14 @@ Returns:
//
// Rebase this file
//
- CurrentFileBaseAddress = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage);
- Status = FfsRebase (CurrentFile, CurrentFileBaseAddress, MapFile);
+ FfsRebase (
+ CurrentFile,
+ BaseTypes,
+ XipBase + (UINTN)CurrentFile - (UINTN)FvImage,
+ &BsBase,
+ &RtBase,
+ LogFile
+ );
if (EFI_ERROR (Status)) {
switch (Status) {
@@ -359,7 +360,6 @@ Returns:
goto Finish;
}
-
//
// Get the next file
//
@@ -399,8 +399,8 @@ Finish:
fclose (OutputFile);
}
- if (MapFile != NULL) {
- fclose (MapFile);
+ if (LogFile != NULL) {
+ fclose (LogFile);
}
if (FvImage != NULL) {
@@ -420,7 +420,7 @@ ReadHeader (
Routine Description:
- This function determines the size of the FV and the erase polarity. The
+ This function determines the size of the FV and the erase polarity. The
erase polarity is the FALSE value for file state.
Arguments:
@@ -428,9 +428,9 @@ Arguments:
InputFile The file that contains the FV image.
FvSize The size of the FV.
ErasePolarity The FV erase polarity.
-
+
Returns:
-
+
EFI_SUCCESS Function completed successfully.
EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
EFI_ABORTED The function encountered an error.
@@ -539,38 +539,36 @@ Returns:
--*/
{
printf (
- "Usage: %s -I InputFileName -O OutputFileName [-B BaseAddress] -F FvInfFileName -M MapFile\n",
+ "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",
UTILITY_NAME
);
printf (" Where:\n");
- printf (" InputFileName is the name of the EFI FV file to rebase.\n");
+ printf (" InputFileName is the name of the EFI FV file to rebase.\n");
printf (" OutputFileName is the desired output file name.\n");
- printf (" BaseAddress is the FV base address to rebase agains.\n");
- printf (" FvInfFileName is the fv.inf to be used to generate this fv image.\n");
- printf (" BaseAddress can also be got from the fv.inf file.\n");
- printf (" Choose only one method to input BaseAddress.\n");
- printf (" MapFileName is an optional map file of the relocations\n");
- printf (" Argument pair may be in any order.\n\n");
+ printf (" BaseAddress is the FV base address to rebase agains.\n");
+ printf (" Argument pair may be in any order.\n\n");
}
EFI_STATUS
FfsRebase (
- IN OUT EFI_FFS_FILE_HEADER *FfsFile,
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN FILE *MapFile OPTIONAL
+ IN OUT EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINT32 Flags,
+ IN OUT EFI_PHYSICAL_ADDRESS XipBase,
+ IN OUT EFI_PHYSICAL_ADDRESS *BsBase,
+ IN OUT EFI_PHYSICAL_ADDRESS *RtBase,
+ OUT FILE *LogFile
)
/*++
Routine Description:
- This function determines if a file is XIP and should be rebased. It will
+ This function determines if a file is XIP and should be rebased. It will
rebase any PE32 sections found in the file using the base address.
-
+
Arguments:
FfsFile A pointer to Ffs file image.
BaseAddress The base address to use for rebasing the file image.
- MapFile Optional file to dump relocation information into
Returns:
@@ -590,20 +588,21 @@ Returns:
UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS EntryPoint;
UINT32 Pe32ImageSize;
- UINT32 NewPe32BaseAddress;
+ EFI_PHYSICAL_ADDRESS NewPe32BaseAddress;
UINTN Index;
EFI_FILE_SECTION_POINTER CurrentPe32Section;
EFI_FFS_FILE_STATE SavedState;
- EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_IMAGE_NT_HEADERS32 *PeHdr;
+ EFI_IMAGE_NT_HEADERS64 *PePlusHdr;
UINT32 *PeHdrSizeOfImage;
UINT32 *PeHdrChecksum;
- UINT32 FoundCount;
EFI_TE_IMAGE_HEADER *TEImageHeader;
UINT8 *TEBuffer;
EFI_IMAGE_DOS_HEADER *DosHeader;
UINT8 FileGuidString[80];
UINT32 TailSize;
EFI_FFS_FILE_TAIL TailValue;
+ EFI_PHYSICAL_ADDRESS *BaseToUpdate;
//
// Verify input parameters
@@ -611,7 +610,6 @@ Returns:
if (FfsFile == NULL) {
return EFI_INVALID_PARAMETER;
}
-
//
// Convert the GUID to a string so we can at least report which file
// if we find an error.
@@ -622,7 +620,6 @@ Returns:
} else {
TailSize = 0;
}
-
//
// Do some cursory checks on the FFS file contents
//
@@ -632,36 +629,31 @@ Returns:
return EFI_INVALID_PARAMETER;
}
- memset (&ImageContext, 0, sizeof (ImageContext));
-
//
- // Check if XIP file type. If not XIP, don't rebase.
+ // We only process files potentially containing PE32 sections.
//
- if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
- FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
- FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
- FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
- ) {
- return EFI_SUCCESS;
+ switch (FfsFile->Type) {
+ case EFI_FV_FILETYPE_SECURITY_CORE:
+ case EFI_FV_FILETYPE_PEI_CORE:
+ case EFI_FV_FILETYPE_PEIM:
+ case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
+ case EFI_FV_FILETYPE_DRIVER:
+ case EFI_FV_FILETYPE_DXE_CORE:
+ break;
+ default:
+ return EFI_SUCCESS;
}
//
// Rebase each PE32 section
//
Status = EFI_SUCCESS;
- FoundCount = 0;
for (Index = 1;; Index++) {
Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) {
break;
}
- FoundCount++;
-
- //
- // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section
- //
- NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile);
//
// Initialize context
@@ -669,25 +661,102 @@ Returns:
memset (&ImageContext, 0, sizeof (ImageContext));
ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
-
Status = PeCoffLoaderGetImageInfo (&ImageContext);
-
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);
return Status;
}
+
+ //
+ // Calculate the PE32 base address, based on file type
+ //
+ switch (FfsFile->Type) {
+ case EFI_FV_FILETYPE_SECURITY_CORE:
+ case EFI_FV_FILETYPE_PEI_CORE:
+ case EFI_FV_FILETYPE_PEIM:
+ case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
+ if ((Flags & 1) == 0) {
+ //
+ // We aren't relocating XIP code, so skip it.
+ //
+ return EFI_SUCCESS;
+ }
+
+ NewPe32BaseAddress =
+ XipBase +
+ (UINTN)CurrentPe32Section.Pe32Section +
+ sizeof (EFI_COMMON_SECTION_HEADER) -
+ (UINTN)FfsFile;
+ BaseToUpdate = &XipBase;
+ break;
+
+ case EFI_FV_FILETYPE_DRIVER:
+ PeHdr = (EFI_IMAGE_NT_HEADERS32*)(
+ (UINTN)CurrentPe32Section.Pe32Section +
+ sizeof (EFI_COMMON_SECTION_HEADER) +
+ ImageContext.PeCoffHeaderOffset
+ );
+ switch (PeHdr->OptionalHeader.Subsystem) {
+ case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ if ((Flags & 4) == 0) {
+ //
+ // RT drivers aren't supposed to be relocated
+ //
+ continue;
+ }
+
+ NewPe32BaseAddress = *RtBase;
+ BaseToUpdate = RtBase;
+ break;
+
+ default:
+ //
+ // We treat all other subsystems the same as BS_DRIVER
+ //
+ if ((Flags & 2) == 0) {
+ //
+ // Skip all BS_DRIVER's
+ //
+ continue;
+ }
+
+ NewPe32BaseAddress = *BsBase;
+ BaseToUpdate = BsBase;
+ break;
+ }
+ break;
+
+ case EFI_FV_FILETYPE_DXE_CORE:
+ if ((Flags & 2) == 0) {
+ //
+ // Skip DXE core
+ //
+ return EFI_SUCCESS;
+ }
+
+ NewPe32BaseAddress = *BsBase;
+ BaseToUpdate = BsBase;
+ break;
+
+ default:
+ //
+ // Not supported file type
+ //
+ return EFI_SUCCESS;
+ }
+
//
// Allocate a buffer for the image to be loaded into.
//
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);
- MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x10000));
+ MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
if (MemoryImagePointer == 0) {
Error (NULL, 0, 0, "memory allocation failure", NULL);
return EFI_OUT_OF_RESOURCES;
}
- memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x10000);
- MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);
-
+ memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
+ MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
+
ImageContext.ImageAddress = MemoryImagePointerAligned;
@@ -697,24 +766,6 @@ Returns:
free ((VOID *) MemoryImagePointer);
return Status;
}
-
- //
- // Check if section-alignment and file-alignment match or not
- //
- if (!(ImageContext.IsTeImage)) {
- PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress +
- ImageContext.PeCoffHeaderOffset);
- if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {
- Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);
- free ((VOID *) MemoryImagePointer);
- return EFI_ABORTED;
- }
- }
- else {
- //
- // BUGBUG: TE Image Header lack section-alignment and file-alignment info
- //
- }
ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = PeCoffLoaderRelocateImage (&ImageContext);
@@ -742,21 +793,34 @@ Returns:
free ((VOID *) MemoryImagePointer);
return EFI_ABORTED;
}
+
+ //
+ // Update BASE address
+ //
+ fprintf (
+ LogFile,
+ "%s %016I64X\n",
+ FileGuidString,
+ ImageContext.DestinationAddress
+ );
+ *BaseToUpdate += EFI_SIZE_TO_PAGES (ImageContext.ImageSize) * EFI_PAGE_SIZE;
+
//
// Since we may have updated the Codeview RVA, we need to insure the PE
// header indicates the image is large enough to contain the Codeview data
// so it will be loaded properly later if the PEIM is reloaded into memory...
//
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
+ PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
- PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);
- PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);
+ PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);
+ PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
- PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
- PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
+ PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
+ PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
- PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
- PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
+ PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
+ PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
} else {
Error (
NULL,
@@ -779,24 +843,6 @@ Returns:
}
memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);
-
- //
- // Get EntryPoint in Flash Region.
- //
- EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;
-
- //
- // If a map file was selected output mapping information for any file that
- // was rebased.
- //
- if (MapFile != NULL) {
- fprintf (MapFile, "PE32 File: %s Base:%08lx", FileGuidString, BaseAddress);
- fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);
- if (ImageContext.PdbPointer != NULL) {
- fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);
- }
- fprintf (MapFile, "\n");
- }
free ((VOID *) MemoryImagePointer);
@@ -832,6 +878,20 @@ Returns:
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
}
}
+
+ if ((Flags & 1) == 0 || (
+ FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
+ FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
+
+ FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
+ FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
+ )) {
+ //
+ // Only XIP code may have a TE section
+ //
+ return EFI_SUCCESS;
+ }
+
//
// Now process TE sections
//
@@ -841,15 +901,13 @@ Returns:
break;
}
- FoundCount++;
-
//
// Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
// by GenTEImage
//
TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));
- NewPe32BaseAddress = ((UINT32) BaseAddress) +
+ NewPe32BaseAddress = ((UINT32) XipBase) +
(
(UINTN) CurrentPe32Section.Pe32Section +
sizeof (EFI_COMMON_SECTION_HEADER) +
@@ -880,6 +938,7 @@ Returns:
DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;
*(UINT32 *) (TEBuffer + 0x3C) = 0x40;
PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);
+ PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;
PeHdr->FileHeader.Machine = TEImageHeader->Machine;
PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;
@@ -889,39 +948,89 @@ Returns:
// the 0x40 bytes for our DOS header.
//
PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));
- PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
- PeHdr->OptionalHeader.AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint;
- PeHdr->OptionalHeader.BaseOfCode = TEImageHeader->BaseOfCode;
- PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
- PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
- PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
- PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
- sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
-
- //
- // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
- //
- if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
- (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
- ) {
- PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
+ if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA32) {
+ PeHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {
+ PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_X64) {
+ PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else {
+ Error (
+ NULL,
+ 0,
+ 0,
+ "unknown machine type in TE image",
+ "machine type=0x%X, file=%s",
+ (UINT32) TEImageHeader->Machine,
+ FileGuidString
+ );
+ free (TEBuffer);
+ return EFI_ABORTED;
}
- if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
- (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
- ) {
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
- if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
- PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
+ if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
+ PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
+ PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
+ PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
+ sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
+
+ //
+ // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
+ //
+ if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
+ (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
+ ) {
+ PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
+ PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
+ PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
+ }
+
+ if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
+ (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
+ ) {
+ PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
+ PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
+ }
+ }
+ //
+ // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
+ //
+ PeHdr->OptionalHeader.SectionAlignment = 0x10;
+ } else {
+ PePlusHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
+ PePlusHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
+ PePlusHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
+ PePlusHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
+ sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
+
+ //
+ // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
+ //
+ if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
+ (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
+ ) {
+ PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
+ PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
+ PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
+
+ if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
+ (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
+ ) {
+ PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ if (PePlusHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
+ PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
+ }
+ }
+ //
+ // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
+ //
+ PePlusHdr->OptionalHeader.SectionAlignment = 0x10;
}
- //
- // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
- //
- PeHdr->OptionalHeader.SectionAlignment = 0x10;
//
// Copy the rest of the image to its original offset
@@ -950,15 +1059,15 @@ Returns:
//
// Allocate a buffer for the image to be loaded into.
//
- MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x10000));
+ MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
if (MemoryImagePointer == 0) {
Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);
free (TEBuffer);
return EFI_OUT_OF_RESOURCES;
}
- memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x10000);
- MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);
-
+ memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
+ MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
+
ImageContext.ImageAddress = MemoryImagePointerAligned;
Status = PeCoffLoaderLoadImage (&ImageContext);
@@ -968,11 +1077,6 @@ Returns:
free ((VOID *) MemoryImagePointer);
return Status;
}
-
- //
- // Check if section-alignment and file-alignment match or not
- // BUGBUG: TE Image Header lack section-alignment and file-alignment info
- //
ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = PeCoffLoaderRelocateImage (&ImageContext);
@@ -993,12 +1097,16 @@ Returns:
// so it will be loaded properly later if the PEIM is reloaded into memory...
//
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
+ PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
- PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);
- PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);
+ PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);
+ PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
- PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
- PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
+ PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
+ PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
+ } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
+ PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
+ PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
} else {
Error (
NULL,
@@ -1028,25 +1136,6 @@ Returns:
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
sizeof (EFI_TE_IMAGE_HEADER)
);
-
- //
- // Get EntryPoint in Flash Region.
- //
- EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;
-
- //
- // If a map file was selected output mapping information for any file that
- // was rebased.
- //
- if (MapFile != NULL) {
- fprintf (MapFile, "TE File: %s Base:%08lx", FileGuidString, BaseAddress);
- fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);
- if (ImageContext.PdbPointer != NULL) {
- fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);
- }
- fprintf (MapFile, "\n");
- }
-
free ((VOID *) MemoryImagePointer);
free (TEBuffer);
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
@@ -1079,18 +1168,15 @@ Returns:
TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
}
+
+ fprintf (
+ LogFile,
+ "%s %016I64X\n",
+ FileGuidString,
+ ImageContext.DestinationAddress
+ );
}
- //
- // If we found no files, then emit an error if no compressed sections either
- //
- if (FoundCount == 0) {
- Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString);
- return EFI_NOT_FOUND;
- }
- }
-
+
return EFI_SUCCESS;
}
diff --git a/Tools/CCode/Source/PeiRebase/PeiRebaseExe.h b/Tools/CCode/Source/PeiRebase/PeiRebaseExe.h
index b05baef..253387e 100644
--- a/Tools/CCode/Source/PeiRebase/PeiRebaseExe.h
+++ b/Tools/CCode/Source/PeiRebase/PeiRebaseExe.h
@@ -1,8 +1,8 @@
/*++
Copyright (c) 1999-2006 Intel Corporation. All rights reserved
-This program and the accompanying materials are licensed and made available
-under the terms and conditions of the BSD License which accompanies this
+This program and the accompanying materials are licensed and made available
+under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
@@ -11,7 +11,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
-
+
PeiRebaseExe.h
Abstract:
@@ -43,7 +43,7 @@ Abstract:
//
// The maximum number of arguments accepted from the command line.
//
-#define MAX_ARGS 9
+#define MAX_ARGS 7
//
// The file copy buffer size
@@ -130,9 +130,12 @@ Returns:
EFI_STATUS
FfsRebase (
- IN OUT EFI_FFS_FILE_HEADER *FfsFile,
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN FILE *MapFile OPTIONAL
+ IN OUT EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINT32 Flags,
+ IN OUT EFI_PHYSICAL_ADDRESS XipBase,
+ IN OUT EFI_PHYSICAL_ADDRESS *BsBase,
+ IN OUT EFI_PHYSICAL_ADDRESS *RtBase,
+ OUT FILE *LogFile
)
/*++