summaryrefslogtreecommitdiff
path: root/BaseTools/Source/C/GenFv/GenFvInternalLib.c
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-28 23:39:39 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-28 23:39:39 +0000
commit52302d4dee589a5df43a464420c9fe68ba83937d (patch)
tree2393f61b9e8975134e3cdfa0352d4c51a3b2ac8d /BaseTools/Source/C/GenFv/GenFvInternalLib.c
parentfe35c036354c4b6bf18c4699a45156f3965fae2a (diff)
downloadedk2-platforms-52302d4dee589a5df43a464420c9fe68ba83937d.tar.xz
Sync EDKII BaseTools to BaseTools project r1903.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10123 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source/C/GenFv/GenFvInternalLib.c')
-rw-r--r--BaseTools/Source/C/GenFv/GenFvInternalLib.c506
1 files changed, 268 insertions, 238 deletions
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index d17a2ff1a8..00d008573a 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2009, Intel Corporation
+Copyright (c) 2004 - 2010, 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 distribution. The full text of the license may be found at
@@ -159,6 +159,9 @@ UINT8 m64kRecoveryStartupApDataArray[SIZEOF_ST
FV_INFO mFvDataInfo;
CAP_INFO mCapDataInfo;
+EFI_PHYSICAL_ADDRESS mFvBaseAddress[0x10];
+UINT32 mFvBaseAddressNumber = 0;
+
EFI_STATUS
ParseFvInf (
IN MEMORY_FILE *InfFile,
@@ -716,6 +719,11 @@ Returns:
EFI_TE_IMAGE_HEADER *TEImageHeader;
EFI_IMAGE_SECTION_HEADER *SectionHeader;
unsigned long long TempLongAddress;
+ UINT32 TextVirtualAddress;
+ UINT32 DataVirtualAddress;
+ EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress;
+
+
//
// Init local variable
//
@@ -789,29 +797,35 @@ Returns:
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);
Index = TEImageHeader->NumberOfSections;
}
-
+
//
// module information output
//
if (ImageBaseAddress == 0) {
fprintf (FvMapFile, "%s (dummy) (", KeyWord);
- fprintf (FvMapFile, "BaseAddress=%08llx, ", (unsigned long long) ImageBaseAddress);
+ fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress);
} else {
- fprintf (FvMapFile, "%s (", KeyWord);
- fprintf (FvMapFile, "BaseAddress=%08llx, ", (unsigned long long) (ImageBaseAddress + Offset));
+ fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord);
+ fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset));
}
- fprintf (FvMapFile, "EntryPoint=%08llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));
- fprintf (FvMapFile, "GUID=%s", FileGuidName);
+ fprintf (FvMapFile, "EntryPoint=0x%010llx", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));
fprintf (FvMapFile, ")\n");
+ fprintf (FvMapFile, "(GUID=%s", FileGuidName);
+ TextVirtualAddress = 0;
+ DataVirtualAddress = 0;
for (; Index > 0; Index --, SectionHeader ++) {
- if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {
- fprintf (FvMapFile, ".textbaseaddress=%08llx ", (unsigned long long) (ImageBaseAddress + SectionHeader->VirtualAddress));
+ if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {
+ TextVirtualAddress = SectionHeader->VirtualAddress;
} else if (stricmp ((CHAR8 *)SectionHeader->Name, ".data") == 0) {
- fprintf (FvMapFile, ".databaseaddress=%08llx ", (unsigned long long) (ImageBaseAddress + SectionHeader->VirtualAddress));
+ DataVirtualAddress = SectionHeader->VirtualAddress;
+ } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".sdata") == 0) {
+ DataVirtualAddress = SectionHeader->VirtualAddress;
}
}
- fprintf (FvMapFile, "\n\n");
+ fprintf (FvMapFile, " .textbaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + TextVirtualAddress));
+ fprintf (FvMapFile, " .databaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + DataVirtualAddress));
+ fprintf (FvMapFile, ")\n\n");
//
// Open PeMapFile
@@ -826,6 +840,7 @@ Returns:
//
// Output Functions information into Fv Map file
//
+ LinkTimeBaseAddress = 0;
while (fgets (Line, MAX_LINE_LEN, PeMapFile) != NULL) {
//
// Skip blank line
@@ -851,6 +866,9 @@ Returns:
//
FunctionType = 2;
fgets (Line, MAX_LINE_LEN, PeMapFile);
+ } else if (stricmp (KeyWord, "Preferred") ==0) {
+ sscanf (Line + strlen (" Preferred load address is"), "%llx", &TempLongAddress);
+ LinkTimeBaseAddress = (UINT64) TempLongAddress;
}
continue;
}
@@ -861,24 +879,14 @@ Returns:
sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);
FunctionAddress = (UINT64) TempLongAddress;
if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));
- fprintf (FvMapFile, "(%08llx) F ", (unsigned long long) (FunctionAddress - Offset));
- fprintf (FvMapFile, "%s\n", FunctionName);
- } else {
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));
- fprintf (FvMapFile, "(%08llx) ", (unsigned long long) (FunctionAddress - Offset));
+ fprintf (FvMapFile, " 0x%010llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
fprintf (FvMapFile, "%s\n", FunctionName);
}
} else if (FunctionType == 2) {
sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);
FunctionAddress = (UINT64) TempLongAddress;
if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));
- fprintf (FvMapFile, "(%08llx) FS ", (unsigned long long) (FunctionAddress - Offset));
- fprintf (FvMapFile, "%s\n", FunctionName);
- } else {
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));
- fprintf (FvMapFile, "(%08llx) ", (unsigned long long) (FunctionAddress - Offset));
+ fprintf (FvMapFile, " 0x%010llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
fprintf (FvMapFile, "%s\n", FunctionName);
}
}
@@ -898,7 +906,8 @@ AddFile (
IN FV_INFO *FvInfo,
IN UINTN Index,
IN OUT EFI_FFS_FILE_HEADER **VtfFileImage,
- IN FILE *FvMapFile
+ IN FILE *FvMapFile,
+ IN FILE *FvReportFile
)
/*++
@@ -916,6 +925,7 @@ Arguments:
VtfFileImage A pointer to the VTF file within the FvImage. If this is equal
to the end of the FvImage then no VTF previously found.
FvMapFile Pointer to FvMap File
+ FvReportFile Pointer to FvReport File
Returns:
@@ -933,6 +943,7 @@ Returns:
UINT32 CurrentFileAlignment;
EFI_STATUS Status;
UINTN Index1;
+ UINT8 FileGuidString[PRINTED_GUID_BUFFER_SIZE];
Index1 = 0;
//
@@ -1071,6 +1082,10 @@ Returns:
// copy VTF File
//
memcpy (*VtfFileImage, FileBuffer, FileSize);
+
+ PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE);
+ fprintf (FvReportFile, "0x%08X %s\n", (unsigned)(UINTN) (((UINT8 *)*VtfFileImage) - (UINTN)FvImage->FileImage), FileGuidString);
+
free (FileBuffer);
DebugMsg (NULL, 0, 9, "Add VTF FFS file in FV image", NULL);
return EFI_SUCCESS;
@@ -1106,6 +1121,8 @@ Returns:
// Copy the file
//
memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);
+ PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE);
+ fprintf (FvReportFile, "0x%08X %s\n", (unsigned) (FvImage->CurrentFilePointer - FvImage->FileImage), FileGuidString);
FvImage->CurrentFilePointer += FileSize;
} else {
Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add file %s.", FvInfo->FvFiles[Index]);
@@ -1967,10 +1984,13 @@ Returns:
EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
FILE *FvExtHeaderFile;
UINTN FileSize;
+ CHAR8 FvReportName[_MAX_PATH];
+ FILE *FvReportFile;
FvBufferHeader = NULL;
FvFile = NULL;
FvMapFile = NULL;
+ FvReportFile = NULL;
if (InfFileImage != NULL) {
//
@@ -2110,6 +2130,12 @@ Returns:
VerboseMsg ("FV Map file name is %s", FvMapName);
//
+ // FvReport file to log the FV information in one Fvimage
+ //
+ strcpy (FvReportName, FvFileName);
+ strcat (FvReportName, ".txt");
+
+ //
// Calculate the FV size and Update Fv Size based on the actual FFS files.
// And Update mFvDataInfo data.
//
@@ -2225,6 +2251,14 @@ Returns:
}
//
+ // Open FvReport file
+ //
+ FvReportFile = fopen(FvReportName, "w");
+ if (FvReportFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", FvReportName);
+ return EFI_ABORTED;
+ }
+ //
// record FV size information into FvMap file.
//
if (mFvTotalSize != 0) {
@@ -2241,6 +2275,12 @@ Returns:
}
//
+ // record FV size information to FvReportFile.
+ //
+ fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);
+ fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);
+
+ //
// Add PI FV extension header
//
if (FvExtHeader != NULL) {
@@ -2263,7 +2303,7 @@ Returns:
//
// Add the file
//
- Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile);
+ Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile, FvReportFile);
//
// Exit if error detected while adding the file
@@ -2358,13 +2398,19 @@ Finish:
}
if (FvFile != NULL) {
+ fflush (FvFile);
fclose (FvFile);
}
if (FvMapFile != NULL) {
+ fflush (FvMapFile);
fclose (FvMapFile);
}
+ if (FvReportFile != NULL) {
+ fflush (FvReportFile);
+ fclose (FvReportFile);
+ }
return Status;
}
@@ -2653,6 +2699,54 @@ Returns:
}
EFI_STATUS
+GetChildFvFromFfs (
+ IN FV_INFO *FvInfo,
+ IN EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINTN XipOffset
+ )
+/*++
+
+Routine Description:
+
+ This function gets all child FvImages in the input FfsFile, and records
+ their base address to the parent image.
+
+Arguments:
+ FvInfo A pointer to FV_INFO struture.
+ FfsFile A pointer to Ffs file image that may contain FvImage.
+ XipOffset The offset address to the parent FvImage base.
+
+Returns:
+
+ EFI_SUCCESS Base address of child Fv image is recorded.
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_FILE_SECTION_POINTER SubFvSection;
+ EFI_FIRMWARE_VOLUME_HEADER *SubFvImageHeader;
+ EFI_PHYSICAL_ADDRESS SubFvBaseAddress;
+
+ for (Index = 1;; Index++) {
+ //
+ // Find FV section
+ //
+ Status = GetSectionByType (FfsFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, Index, &SubFvSection);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + sizeof (EFI_FIRMWARE_VOLUME_IMAGE_SECTION));
+ //
+ // Rebase on Flash
+ //
+ SubFvBaseAddress = FvInfo->BaseAddress + (UINTN) SubFvImageHeader - (UINTN) FfsFile + XipOffset;
+ mFvBaseAddress[mFvBaseAddressNumber ++ ] = SubFvBaseAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
FfsRebase (
IN OUT FV_INFO *FvInfo,
IN CHAR8 *FileName,
@@ -2696,7 +2790,6 @@ Returns:
EFI_FFS_FILE_STATE SavedState;
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
EFI_TE_IMAGE_HEADER *TEImageHeader;
- UINT8 Flags;
UINT8 *MemoryImagePointer;
EFI_IMAGE_SECTION_HEADER *SectionHeader;
CHAR8 PeFileName [_MAX_PATH];
@@ -2717,26 +2810,12 @@ Returns:
PeFileBuffer = NULL;
//
- // Check XipAddress, BootAddress and RuntimeAddress
+ // Don't need to relocate image when BaseAddress is not set.
//
- Flags = 0;
- XipBase = 0;
- if (FvInfo->BaseAddress != 0) {
- Flags |= REBASE_XIP_FILE;
- XipBase = FvInfo->BaseAddress + XipOffset;
- }
- if (FvInfo->BootBaseAddress != 0) {
- Flags |= REBASE_BOOTTIME_FILE;
- }
- if (FvInfo->RuntimeBaseAddress != 0) {
- Flags |= REBASE_RUNTIME_FILE;
+ if (FvInfo->BaseAddress == 0) {
+ return EFI_SUCCESS;
}
-
- //
- // Don't Rebase this FFS.
- // Only copy the original map file into the FvMap file
- // for the image that is not required to be relocated.
- //
+ XipBase = FvInfo->BaseAddress + XipOffset;
//
// We only process files potentially containing PE32 sections.
@@ -2749,6 +2828,16 @@ Returns:
case EFI_FV_FILETYPE_DRIVER:
case EFI_FV_FILETYPE_DXE_CORE:
break;
+ case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
+ //
+ // Rebase the inside FvImage.
+ //
+ GetChildFvFromFfs (FvInfo, FfsFile, XipOffset);
+
+ //
+ // Search PE/TE section in FV sectin.
+ //
+ break;
default:
return EFI_SUCCESS;
}
@@ -2809,13 +2898,6 @@ Returns:
case EFI_FV_FILETYPE_PEI_CORE:
case EFI_FV_FILETYPE_PEIM:
case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
- if ((Flags & REBASE_XIP_FILE) == 0) {
- //
- // We aren't relocating XIP code, so skip it.
- //
- goto WritePeMap;
- }
-
//
// Check if section-alignment and file-alignment match or not
//
@@ -2889,70 +2971,18 @@ Returns:
case EFI_FV_FILETYPE_DRIVER:
case EFI_FV_FILETYPE_DXE_CORE:
- switch (ImgHdr->Pe32.OptionalHeader.Subsystem) {
- case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
- if ((Flags & REBASE_XIP_FILE) == REBASE_XIP_FILE) {
- //
- // Check if section-alignment and file-alignment match or not
- //
- if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
- //
- // Xip module has the same section alignment and file alignment.
- //
- Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);
- return EFI_ABORTED;
- }
- NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;
- BaseToUpdate = &XipBase;
- } else if ((Flags & REBASE_RUNTIME_FILE) == REBASE_RUNTIME_FILE) {
- //
- // make sure image base address at the section alignment
- //
- FvInfo->RuntimeBaseAddress = (FvInfo->RuntimeBaseAddress - ImageContext.ImageSize) & (~(ImageContext.SectionAlignment - 1));
- FvInfo->RuntimeBaseAddress = FvInfo->RuntimeBaseAddress & (~(EFI_PAGE_SIZE - 1));
- NewPe32BaseAddress = FvInfo->RuntimeBaseAddress;
- BaseToUpdate = &(FvInfo->RuntimeBaseAddress);
- } else {
- //
- // RT drivers aren't supposed to be relocated
- //
- goto WritePeMap;
- }
- break;
-
- default:
- //
- // We treat all other subsystems the same as BS_DRIVER
- //
- if ((Flags & REBASE_XIP_FILE) == REBASE_XIP_FILE) {
- //
- // Check if section-alignment and file-alignment match or not
- //
- if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
- //
- // Xip module has the same section alignment and file alignment.
- //
- Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);
- return EFI_ABORTED;
- }
- NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;
- BaseToUpdate = &XipBase;
- } else if ((Flags & REBASE_BOOTTIME_FILE) == REBASE_BOOTTIME_FILE) {
- //
- // make sure image base address at the Section and Page alignment
- //
- FvInfo->BootBaseAddress = (FvInfo->BootBaseAddress - ImageContext.ImageSize) & (~(ImageContext.SectionAlignment - 1));
- FvInfo->BootBaseAddress = FvInfo->BootBaseAddress & (~(EFI_PAGE_SIZE - 1));
- NewPe32BaseAddress = FvInfo->BootBaseAddress;
- BaseToUpdate = &(FvInfo->BootBaseAddress);
- } else {
- //
- // Skip all BS_DRIVER's
- //
- goto WritePeMap;
- }
- break;
+ //
+ // Check if section-alignment and file-alignment match or not
+ //
+ if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
+ //
+ // Xip module has the same section alignment and file alignment.
+ //
+ Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);
+ return EFI_ABORTED;
}
+ NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;
+ BaseToUpdate = &XipBase;
break;
default:
@@ -2963,68 +2993,74 @@ Returns:
}
//
- // Relocation exist and rebase
+ // Relocation doesn't exist
//
- if (!ImageContext.RelocationsStripped) {
- //
- // Load and Relocate Image Data
- //
- MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
- if (MemoryImagePointer == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
- return EFI_OUT_OF_RESOURCES;
- }
- memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
- ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));
-
- Status = PeCoffLoaderLoadImage (&ImageContext);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
- free ((VOID *) MemoryImagePointer);
- return Status;
- }
-
- ImageContext.DestinationAddress = NewPe32BaseAddress;
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
- free ((VOID *) MemoryImagePointer);
- return Status;
- }
+ if (ImageContext.RelocationsStripped) {
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
+ continue;
+ }
- //
- // Copy Relocated data to raw image file.
- //
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
- (UINTN) ImgHdr +
- sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
- );
-
- for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
- CopyMem (
- (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData,
- (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
- SectionHeader->SizeOfRawData
- );
- }
-
+ //
+ // Relocation exist and rebase
+ //
+ //
+ // Load and Relocate Image Data
+ //
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ if (MemoryImagePointer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));
+
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
free ((VOID *) MemoryImagePointer);
- MemoryImagePointer = NULL;
- if (PeFileBuffer != NULL) {
- free (PeFileBuffer);
- PeFileBuffer = NULL;
- }
+ return Status;
+ }
+
+ ImageContext.DestinationAddress = NewPe32BaseAddress;
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ //
+ // Copy Relocated data to raw image file.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ CopyMem (
+ (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
+ }
+
+ free ((VOID *) MemoryImagePointer);
+ MemoryImagePointer = NULL;
+ if (PeFileBuffer != NULL) {
+ free (PeFileBuffer);
+ PeFileBuffer = NULL;
}
//
// Update Image Base Address
//
if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
} else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
- ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
} else {
Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
ImgHdr->Pe32.OptionalHeader.Magic,
@@ -3034,11 +3070,6 @@ Returns:
}
//
- // Update BASE address by add one page size.
- //
- *BaseToUpdate -= EFI_PAGE_SIZE;
-
- //
// Now update file checksum
//
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
@@ -3055,7 +3086,7 @@ Returns:
//
// Get this module function address from ModulePeMapFile and add them into FvMap file
//
-WritePeMap:
+
//
// Default use FileName as map file path
//
@@ -3069,7 +3100,8 @@ WritePeMap:
if (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
+ FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&
+ FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
//
// Only Peim code may have a TE section
@@ -3122,13 +3154,6 @@ WritePeMap:
// Get File PdbPointer
//
PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);
-
- if ((Flags & REBASE_XIP_FILE) == 0) {
- //
- // For none XIP PEIM module, their map info also are collected.
- //
- goto WriteTeMap;
- }
//
// Set new rebased address.
@@ -3139,7 +3164,7 @@ WritePeMap:
//
// if reloc is stripped, try to get the original efi image to get reloc info.
//
- if (ImageContext.RelocationsStripped == TRUE) {
+ if (ImageContext.RelocationsStripped) {
//
// Construct the original efi file name
//
@@ -3194,71 +3219,76 @@ WritePeMap:
ImageContext.RelocationsStripped = FALSE;
}
}
+ //
+ // Relocation doesn't exist
+ //
+ if (ImageContext.RelocationsStripped) {
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
+ continue;
+ }
//
// Relocation exist and rebase
//
- if (!ImageContext.RelocationsStripped) {
- //
- // Load and Relocate Image Data
- //
- MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
- if (MemoryImagePointer == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
- return EFI_OUT_OF_RESOURCES;
- }
- memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
- ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));
-
- Status = PeCoffLoaderLoadImage (&ImageContext);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
- free ((VOID *) MemoryImagePointer);
- return Status;
- }
- //
- // Reloacate TeImage
- //
- ImageContext.DestinationAddress = NewPe32BaseAddress;
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);
- free ((VOID *) MemoryImagePointer);
- return Status;
- }
-
- //
- // Copy the relocated image into raw image file.
- //
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);
- for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {
- if (!ImageContext.IsTeImage) {
- CopyMem (
- (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
- (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
- SectionHeader->SizeOfRawData
- );
- } else {
- CopyMem (
- (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
- (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress),
- SectionHeader->SizeOfRawData
- );
- }
- }
-
- //
- // Free the allocated memory resource
- //
+ //
+ // Load and Relocate Image Data
+ //
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ if (MemoryImagePointer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));
+
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
free ((VOID *) MemoryImagePointer);
- MemoryImagePointer = NULL;
- if (PeFileBuffer != NULL) {
- free (PeFileBuffer);
- PeFileBuffer = NULL;
+ return Status;
+ }
+ //
+ // Reloacate TeImage
+ //
+ ImageContext.DestinationAddress = NewPe32BaseAddress;
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ //
+ // Copy the relocated image into raw image file.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);
+ for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {
+ if (!ImageContext.IsTeImage) {
+ CopyMem (
+ (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
+ } else {
+ CopyMem (
+ (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
}
}
//
+ // Free the allocated memory resource
+ //
+ free ((VOID *) MemoryImagePointer);
+ MemoryImagePointer = NULL;
+ if (PeFileBuffer != NULL) {
+ free (PeFileBuffer);
+ PeFileBuffer = NULL;
+ }
+
+ //
// Update Image Base Address
//
TEImageHeader->ImageBase = NewPe32BaseAddress;
@@ -3279,7 +3309,7 @@ WritePeMap:
//
// Get this module function address from ModulePeMapFile and add them into FvMap file
//
-WriteTeMap:
+
//
// Default use FileName as map file path
//