/** @file\r
\r
-Copyright (c) 2004 - 2009, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
+Copyright (c) 2004 - 2010, Intel Corporation. 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
which accompanies this distribution. The full text of the license may be found at \r
http://opensource.org/licenses/bsd-license.php \r
FV_INFO mFvDataInfo;\r
CAP_INFO mCapDataInfo;\r
\r
+EFI_PHYSICAL_ADDRESS mFvBaseAddress[0x10];\r
+UINT32 mFvBaseAddressNumber = 0;\r
+\r
EFI_STATUS\r
ParseFvInf (\r
IN MEMORY_FILE *InfFile,\r
WriteMapFile (\r
IN OUT FILE *FvMapFile,\r
IN CHAR8 *FileName,\r
- IN EFI_GUID *FileGuidPtr, \r
+ IN EFI_FFS_FILE_HEADER *FfsFile, \r
IN EFI_PHYSICAL_ADDRESS ImageBaseAddress,\r
IN PE_COFF_LOADER_IMAGE_CONTEXT *pImageContext\r
)\r
\r
FvMapFile A pointer to FvMap File\r
FileName Ffs File PathName\r
- FileGuidPtr Guid Value of Ffs file\r
+ FfsFile A pointer to Ffs file image.\r
ImageBaseAddress PeImage Base Address.\r
pImageContext Image Context Information.\r
\r
EFI_TE_IMAGE_HEADER *TEImageHeader;\r
EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
unsigned long long TempLongAddress;\r
+ UINT32 TextVirtualAddress;\r
+ UINT32 DataVirtualAddress;\r
+ EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress;\r
+\r
//\r
// Init local variable\r
//\r
//\r
// Print FileGuid to string buffer. \r
//\r
- PrintGuidToBuffer (FileGuidPtr, (UINT8 *)FileGuidName, MAX_LINE_LEN, TRUE);\r
+ PrintGuidToBuffer (&FfsFile->Name, (UINT8 *)FileGuidName, MAX_LINE_LEN, TRUE);\r
\r
//\r
// Construct Map file Name \r
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
Index = TEImageHeader->NumberOfSections;\r
}\r
- \r
+\r
//\r
// module information output\r
//\r
if (ImageBaseAddress == 0) {\r
fprintf (FvMapFile, "%s (dummy) (", KeyWord);\r
- fprintf (FvMapFile, "BaseAddress=%08llx, ", (unsigned long long) ImageBaseAddress);\r
+ fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress);\r
} else {\r
- fprintf (FvMapFile, "%s (", KeyWord);\r
- fprintf (FvMapFile, "BaseAddress=%08llx, ", (unsigned long long) (ImageBaseAddress + Offset));\r
+ fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord);\r
+ fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset));\r
+ }\r
+\r
+ if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && pImageContext->Machine == EFI_IMAGE_MACHINE_IA64) {\r
+ //\r
+ // Process IPF PLABEL to get the real address after the image has been rebased. \r
+ // PLABEL structure is got by AddressOfEntryPoint offset to ImageBuffer stored in pImageContext->Handle.\r
+ //\r
+ fprintf (FvMapFile, "EntryPoint=0x%010llx", (unsigned long long) (*(UINT64 *)((UINTN) pImageContext->Handle + (UINTN) AddressOfEntryPoint)));\r
+ } else {\r
+ fprintf (FvMapFile, "EntryPoint=0x%010llx", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));\r
}\r
- fprintf (FvMapFile, "EntryPoint=%08llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));\r
- fprintf (FvMapFile, "GUID=%s", FileGuidName);\r
fprintf (FvMapFile, ")\n"); \r
\r
+ fprintf (FvMapFile, "(GUID=%s", FileGuidName);\r
+ TextVirtualAddress = 0;\r
+ DataVirtualAddress = 0;\r
for (; Index > 0; Index --, SectionHeader ++) {\r
- if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {\r
- fprintf (FvMapFile, ".textbaseaddress=%08llx ", (unsigned long long) (ImageBaseAddress + SectionHeader->VirtualAddress));\r
+ if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {\r
+ TextVirtualAddress = SectionHeader->VirtualAddress;\r
} else if (stricmp ((CHAR8 *)SectionHeader->Name, ".data") == 0) {\r
- fprintf (FvMapFile, ".databaseaddress=%08llx ", (unsigned long long) (ImageBaseAddress + SectionHeader->VirtualAddress));\r
+ DataVirtualAddress = SectionHeader->VirtualAddress;\r
+ } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".sdata") == 0) {\r
+ DataVirtualAddress = SectionHeader->VirtualAddress;\r
}\r
}\r
- fprintf (FvMapFile, "\n\n"); \r
+ fprintf (FvMapFile, " .textbaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + TextVirtualAddress));\r
+ fprintf (FvMapFile, " .databaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + DataVirtualAddress));\r
+ fprintf (FvMapFile, ")\n\n");\r
\r
//\r
// Open PeMapFile\r
//\r
// Output Functions information into Fv Map file\r
//\r
+ LinkTimeBaseAddress = 0;\r
while (fgets (Line, MAX_LINE_LEN, PeMapFile) != NULL) {\r
//\r
// Skip blank line\r
//\r
FunctionType = 2;\r
fgets (Line, MAX_LINE_LEN, PeMapFile);\r
+ } else if (stricmp (KeyWord, "Preferred") ==0) {\r
+ sscanf (Line + strlen (" Preferred load address is"), "%llx", &TempLongAddress);\r
+ LinkTimeBaseAddress = (UINT64) TempLongAddress;\r
}\r
continue;\r
}\r
sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);\r
FunctionAddress = (UINT64) TempLongAddress;\r
if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {\r
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));\r
- fprintf (FvMapFile, "(%08llx) F ", (unsigned long long) (FunctionAddress - Offset));\r
- fprintf (FvMapFile, "%s\n", FunctionName);\r
- } else {\r
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));\r
- fprintf (FvMapFile, "(%08llx) ", (unsigned long long) (FunctionAddress - Offset));\r
+ fprintf (FvMapFile, " 0x%010llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));\r
fprintf (FvMapFile, "%s\n", FunctionName);\r
}\r
} else if (FunctionType == 2) {\r
sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);\r
FunctionAddress = (UINT64) TempLongAddress;\r
if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {\r
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));\r
- fprintf (FvMapFile, "(%08llx) FS ", (unsigned long long) (FunctionAddress - Offset));\r
- fprintf (FvMapFile, "%s\n", FunctionName);\r
- } else {\r
- fprintf (FvMapFile, " %016llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress));\r
- fprintf (FvMapFile, "(%08llx) ", (unsigned long long) (FunctionAddress - Offset));\r
+ fprintf (FvMapFile, " 0x%010llx ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));\r
fprintf (FvMapFile, "%s\n", FunctionName);\r
}\r
}\r
IN FV_INFO *FvInfo,\r
IN UINTN Index,\r
IN OUT EFI_FFS_FILE_HEADER **VtfFileImage,\r
- IN FILE *FvMapFile \r
+ IN FILE *FvMapFile,\r
+ IN FILE *FvReportFile\r
)\r
/*++\r
\r
VtfFileImage A pointer to the VTF file within the FvImage. If this is equal\r
to the end of the FvImage then no VTF previously found.\r
FvMapFile Pointer to FvMap File\r
+ FvReportFile Pointer to FvReport File\r
\r
Returns:\r
\r
UINT32 CurrentFileAlignment;\r
EFI_STATUS Status;\r
UINTN Index1;\r
+ UINT8 FileGuidString[PRINTED_GUID_BUFFER_SIZE];\r
\r
Index1 = 0;\r
//\r
// copy VTF File\r
//\r
memcpy (*VtfFileImage, FileBuffer, FileSize);\r
+ \r
+ PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE); \r
+ fprintf (FvReportFile, "0x%08X %s\n", (unsigned)(UINTN) (((UINT8 *)*VtfFileImage) - (UINTN)FvImage->FileImage), FileGuidString);\r
+\r
free (FileBuffer);\r
DebugMsg (NULL, 0, 9, "Add VTF FFS file in FV image", NULL);\r
return EFI_SUCCESS;\r
// Copy the file\r
//\r
memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);\r
+ PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE); \r
+ fprintf (FvReportFile, "0x%08X %s\n", (unsigned) (FvImage->CurrentFilePointer - FvImage->FileImage), FileGuidString);\r
FvImage->CurrentFilePointer += FileSize;\r
} else {\r
Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add file %s.", FvInfo->FvFiles[Index]);\r
}\r
\r
// Add opcode for an uncondional branch with no link. AKA B SecEntryPoint\r
- ResetVector[0] |= 0xEA000000;\r
+ ResetVector[0] |= 0xEB000000;\r
\r
\r
// Address of PEI Core, if we have one\r
EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;\r
FILE *FvExtHeaderFile;\r
UINTN FileSize;\r
+ CHAR8 FvReportName[_MAX_PATH];\r
+ FILE *FvReportFile;\r
\r
FvBufferHeader = NULL;\r
FvFile = NULL;\r
FvMapFile = NULL;\r
+ FvReportFile = NULL;\r
\r
if (InfFileImage != NULL) {\r
//\r
}\r
VerboseMsg ("FV Map file name is %s", FvMapName);\r
\r
+ //\r
+ // FvReport file to log the FV information in one Fvimage\r
+ //\r
+ strcpy (FvReportName, FvFileName);\r
+ strcat (FvReportName, ".txt");\r
+\r
//\r
// Calculate the FV size and Update Fv Size based on the actual FFS files.\r
// And Update mFvDataInfo data.\r
return EFI_ABORTED;\r
}\r
\r
+ //\r
+ // Open FvReport file\r
+ //\r
+ FvReportFile = fopen(FvReportName, "w");\r
+ if (FvReportFile == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening file", FvReportName);\r
+ return EFI_ABORTED;\r
+ }\r
//\r
// record FV size information into FvMap file.\r
//\r
fprintf (FvMapFile, " = 0x%x\n\n", (unsigned) (mFvTotalSize - mFvTakenSize));\r
}\r
\r
+ //\r
+ // record FV size information to FvReportFile.\r
+ //\r
+ fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);\r
+ fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);\r
+\r
//\r
// Add PI FV extension header\r
//\r
//\r
// Add the file\r
//\r
- Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile);\r
+ Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile, FvReportFile);\r
\r
//\r
// Exit if error detected while adding the file\r
}\r
\r
if (FvFile != NULL) {\r
+ fflush (FvFile);\r
fclose (FvFile);\r
}\r
\r
if (FvMapFile != NULL) {\r
+ fflush (FvMapFile);\r
fclose (FvMapFile);\r
}\r
\r
+ if (FvReportFile != NULL) {\r
+ fflush (FvReportFile);\r
+ fclose (FvReportFile);\r
+ }\r
return Status;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
+EFI_STATUS\r
+GetChildFvFromFfs (\r
+ IN FV_INFO *FvInfo, \r
+ IN EFI_FFS_FILE_HEADER *FfsFile,\r
+ IN UINTN XipOffset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function gets all child FvImages in the input FfsFile, and records\r
+ their base address to the parent image.\r
+\r
+Arguments:\r
+ FvInfo A pointer to FV_INFO struture.\r
+ FfsFile A pointer to Ffs file image that may contain FvImage.\r
+ XipOffset The offset address to the parent FvImage base.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Base address of child Fv image is recorded.\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_FILE_SECTION_POINTER SubFvSection;\r
+ EFI_FIRMWARE_VOLUME_HEADER *SubFvImageHeader;\r
+ EFI_PHYSICAL_ADDRESS SubFvBaseAddress;\r
+\r
+ for (Index = 1;; Index++) {\r
+ //\r
+ // Find FV section \r
+ //\r
+ Status = GetSectionByType (FfsFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, Index, &SubFvSection);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + sizeof (EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
+ //\r
+ // Rebase on Flash\r
+ //\r
+ SubFvBaseAddress = FvInfo->BaseAddress + (UINTN) SubFvImageHeader - (UINTN) FfsFile + XipOffset;\r
+ mFvBaseAddress[mFvBaseAddressNumber ++ ] = SubFvBaseAddress;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
EFI_STATUS\r
FfsRebase ( \r
IN OUT FV_INFO *FvInfo, \r
EFI_FFS_FILE_STATE SavedState;\r
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
EFI_TE_IMAGE_HEADER *TEImageHeader;\r
- UINT8 Flags;\r
UINT8 *MemoryImagePointer;\r
EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
CHAR8 PeFileName [_MAX_PATH];\r
PeFileBuffer = NULL;\r
\r
//\r
- // Check XipAddress, BootAddress and RuntimeAddress\r
+ // Don't need to relocate image when BaseAddress is not set.\r
//\r
- Flags = 0;\r
- XipBase = 0;\r
- if (FvInfo->BaseAddress != 0) {\r
- Flags |= REBASE_XIP_FILE;\r
- XipBase = FvInfo->BaseAddress + XipOffset;\r
- }\r
- if (FvInfo->BootBaseAddress != 0) {\r
- Flags |= REBASE_BOOTTIME_FILE;\r
- }\r
- if (FvInfo->RuntimeBaseAddress != 0) {\r
- Flags |= REBASE_RUNTIME_FILE;\r
+ if (FvInfo->BaseAddress == 0) {\r
+ return EFI_SUCCESS;\r
}\r
-\r
- //\r
- // Don't Rebase this FFS.\r
- // Only copy the original map file into the FvMap file \r
- // for the image that is not required to be relocated.\r
- //\r
+ XipBase = FvInfo->BaseAddress + XipOffset;\r
\r
//\r
// We only process files potentially containing PE32 sections.\r
case EFI_FV_FILETYPE_DRIVER:\r
case EFI_FV_FILETYPE_DXE_CORE:\r
break;\r
+ case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
+ //\r
+ // Rebase the inside FvImage.\r
+ //\r
+ GetChildFvFromFfs (FvInfo, FfsFile, XipOffset);\r
+\r
+ //\r
+ // Search PE/TE section in FV sectin.\r
+ //\r
+ break;\r
default:\r
return EFI_SUCCESS;\r
}\r
case EFI_FV_FILETYPE_PEI_CORE:\r
case EFI_FV_FILETYPE_PEIM:\r
case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
- if ((Flags & REBASE_XIP_FILE) == 0) {\r
- //\r
- // We aren't relocating XIP code, so skip it.\r
- //\r
- goto WritePeMap;\r
- }\r
- \r
//\r
// Check if section-alignment and file-alignment match or not\r
//\r
\r
case EFI_FV_FILETYPE_DRIVER:\r
case EFI_FV_FILETYPE_DXE_CORE:\r
- switch (ImgHdr->Pe32.OptionalHeader.Subsystem) {\r
- case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
- if ((Flags & REBASE_XIP_FILE) == REBASE_XIP_FILE) {\r
- //\r
- // Check if section-alignment and file-alignment match or not\r
- //\r
- if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {\r
- //\r
- // Xip module has the same section alignment and file alignment.\r
- //\r
- Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);\r
- return EFI_ABORTED;\r
- }\r
- NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;\r
- BaseToUpdate = &XipBase; \r
- } else if ((Flags & REBASE_RUNTIME_FILE) == REBASE_RUNTIME_FILE) {\r
- //\r
- // make sure image base address at the section alignment\r
- //\r
- FvInfo->RuntimeBaseAddress = (FvInfo->RuntimeBaseAddress - ImageContext.ImageSize) & (~(ImageContext.SectionAlignment - 1));\r
- FvInfo->RuntimeBaseAddress = FvInfo->RuntimeBaseAddress & (~(EFI_PAGE_SIZE - 1));\r
- NewPe32BaseAddress = FvInfo->RuntimeBaseAddress;\r
- BaseToUpdate = &(FvInfo->RuntimeBaseAddress);\r
- } else {\r
- //\r
- // RT drivers aren't supposed to be relocated\r
- //\r
- goto WritePeMap;\r
- }\r
- break;\r
-\r
- default:\r
- //\r
- // We treat all other subsystems the same as BS_DRIVER\r
- //\r
- if ((Flags & REBASE_XIP_FILE) == REBASE_XIP_FILE) {\r
- //\r
- // Check if section-alignment and file-alignment match or not\r
- //\r
- if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {\r
- //\r
- // Xip module has the same section alignment and file alignment.\r
- //\r
- Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);\r
- return EFI_ABORTED;\r
- }\r
- NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;\r
- BaseToUpdate = &XipBase; \r
- } else if ((Flags & REBASE_BOOTTIME_FILE) == REBASE_BOOTTIME_FILE) {\r
- //\r
- // make sure image base address at the Section and Page alignment\r
- //\r
- FvInfo->BootBaseAddress = (FvInfo->BootBaseAddress - ImageContext.ImageSize) & (~(ImageContext.SectionAlignment - 1));\r
- FvInfo->BootBaseAddress = FvInfo->BootBaseAddress & (~(EFI_PAGE_SIZE - 1));\r
- NewPe32BaseAddress = FvInfo->BootBaseAddress;\r
- BaseToUpdate = &(FvInfo->BootBaseAddress);\r
- } else {\r
- //\r
- // Skip all BS_DRIVER's\r
- //\r
- goto WritePeMap;\r
- }\r
- break;\r
+ //\r
+ // Check if section-alignment and file-alignment match or not\r
+ //\r
+ if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {\r
+ //\r
+ // Xip module has the same section alignment and file alignment.\r
+ //\r
+ Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);\r
+ return EFI_ABORTED;\r
}\r
+ NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;\r
+ BaseToUpdate = &XipBase; \r
break;\r
\r
default:\r
}\r
\r
//\r
- // Relocation exist and rebase\r
+ // Relocation doesn't exist\r
//\r
- if (!ImageContext.RelocationsStripped) { \r
- //\r
- // Load and Relocate Image Data\r
- //\r
- MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
- if (MemoryImagePointer == NULL) {\r
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
- ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
- \r
- Status = PeCoffLoaderLoadImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
- }\r
- \r
- ImageContext.DestinationAddress = NewPe32BaseAddress;\r
- Status = PeCoffLoaderRelocateImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
- }\r
+ if (ImageContext.RelocationsStripped) {\r
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);\r
+ continue;\r
+ }\r
\r
- //\r
- // Copy Relocated data to raw image file.\r
- //\r
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
- (UINTN) ImgHdr +\r
- sizeof (UINT32) + \r
- sizeof (EFI_IMAGE_FILE_HEADER) + \r
- ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
- );\r
- \r
- for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
- CopyMem (\r
- (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData, \r
- (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
- SectionHeader->SizeOfRawData\r
- );\r
- }\r
- \r
+ //\r
+ // Relocation exist and rebase\r
+ //\r
+ //\r
+ // Load and Relocate Image Data\r
+ //\r
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ if (MemoryImagePointer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
+ \r
+ Status = PeCoffLoaderLoadImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
free ((VOID *) MemoryImagePointer);\r
- MemoryImagePointer = NULL;\r
- if (PeFileBuffer != NULL) {\r
- free (PeFileBuffer);\r
- PeFileBuffer = NULL;\r
- }\r
+ return Status;\r
+ }\r
+ \r
+ ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+ Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
+ free ((VOID *) MemoryImagePointer);\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Copy Relocated data to raw image file.\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+ (UINTN) ImgHdr +\r
+ sizeof (UINT32) + \r
+ sizeof (EFI_IMAGE_FILE_HEADER) + \r
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
+ );\r
+ \r
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ CopyMem (\r
+ (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData, \r
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
+ SectionHeader->SizeOfRawData\r
+ );\r
+ }\r
+\r
+ free ((VOID *) MemoryImagePointer);\r
+ MemoryImagePointer = NULL;\r
+ if (PeFileBuffer != NULL) {\r
+ free (PeFileBuffer);\r
+ PeFileBuffer = NULL;\r
}\r
\r
//\r
// Update Image Base Address\r
//\r
if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
} else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
- ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
} else {\r
Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
ImgHdr->Pe32.OptionalHeader.Magic,\r
return EFI_ABORTED;\r
}\r
\r
- //\r
- // Update BASE address by add one page size.\r
- //\r
- *BaseToUpdate -= EFI_PAGE_SIZE;\r
-\r
//\r
// Now update file checksum\r
//\r
//\r
// Get this module function address from ModulePeMapFile and add them into FvMap file\r
//\r
-WritePeMap:\r
+\r
//\r
// Default use FileName as map file path\r
//\r
PdbPointer = FileName;\r
}\r
\r
- WriteMapFile (FvMapFile, PdbPointer, (EFI_GUID *) FfsFile, NewPe32BaseAddress, &OrigImageContext);\r
+ WriteMapFile (FvMapFile, PdbPointer, FfsFile, NewPe32BaseAddress, &OrigImageContext);\r
}\r
\r
if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&\r
FfsFile->Type != EFI_FV_FILETYPE_PEIM &&\r
- FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\r
+ FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&\r
+ FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
) {\r
//\r
// Only Peim code may have a TE section\r
// Get File PdbPointer\r
//\r
PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);\r
- \r
- if ((Flags & REBASE_XIP_FILE) == 0) {\r
- //\r
- // For none XIP PEIM module, their map info also are collected.\r
- //\r
- goto WriteTeMap;\r
- }\r
\r
//\r
// Set new rebased address.\r
//\r
// if reloc is stripped, try to get the original efi image to get reloc info.\r
//\r
- if (ImageContext.RelocationsStripped == TRUE) {\r
+ if (ImageContext.RelocationsStripped) {\r
//\r
// Construct the original efi file name \r
//\r
ImageContext.RelocationsStripped = FALSE;\r
}\r
}\r
+ //\r
+ // Relocation doesn't exist\r
+ //\r
+ if (ImageContext.RelocationsStripped) {\r
+ Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);\r
+ continue;\r
+ }\r
\r
//\r
// Relocation exist and rebase\r
//\r
- if (!ImageContext.RelocationsStripped) {\r
- //\r
- // Load and Relocate Image Data\r
- //\r
- MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
- if (MemoryImagePointer == NULL) {\r
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
- ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
- \r
- Status = PeCoffLoaderLoadImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
- }\r
- //\r
- // Reloacate TeImage\r
- // \r
- ImageContext.DestinationAddress = NewPe32BaseAddress;\r
- Status = PeCoffLoaderRelocateImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
- }\r
- \r
- //\r
- // Copy the relocated image into raw image file.\r
- //\r
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
- for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {\r
- if (!ImageContext.IsTeImage) {\r
- CopyMem (\r
- (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
- (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
- SectionHeader->SizeOfRawData\r
- );\r
- } else {\r
- CopyMem (\r
- (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
- (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), \r
- SectionHeader->SizeOfRawData\r
- );\r
- }\r
- }\r
- \r
- //\r
- // Free the allocated memory resource\r
- //\r
+ //\r
+ // Load and Relocate Image Data\r
+ //\r
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ if (MemoryImagePointer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
+\r
+ Status = PeCoffLoaderLoadImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
+ free ((VOID *) MemoryImagePointer);\r
+ return Status;\r
+ }\r
+ //\r
+ // Reloacate TeImage\r
+ // \r
+ ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+ Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);\r
free ((VOID *) MemoryImagePointer);\r
- MemoryImagePointer = NULL;\r
- if (PeFileBuffer != NULL) {\r
- free (PeFileBuffer);\r
- PeFileBuffer = NULL;\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Copy the relocated image into raw image file.\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
+ for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {\r
+ if (!ImageContext.IsTeImage) {\r
+ CopyMem (\r
+ (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
+ SectionHeader->SizeOfRawData\r
+ );\r
+ } else {\r
+ CopyMem (\r
+ (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
+ (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), \r
+ SectionHeader->SizeOfRawData\r
+ );\r
}\r
}\r
\r
+ //\r
+ // Free the allocated memory resource\r
+ //\r
+ free ((VOID *) MemoryImagePointer);\r
+ MemoryImagePointer = NULL;\r
+ if (PeFileBuffer != NULL) {\r
+ free (PeFileBuffer);\r
+ PeFileBuffer = NULL;\r
+ }\r
+ \r
//\r
// Update Image Base Address\r
//\r
//\r
// Get this module function address from ModulePeMapFile and add them into FvMap file\r
//\r
-WriteTeMap:\r
+\r
//\r
// Default use FileName as map file path\r
//\r
WriteMapFile (\r
FvMapFile, \r
PdbPointer, \r
- (EFI_GUID *) FfsFile,\r
+ FfsFile,\r
NewPe32BaseAddress, \r
&OrigImageContext\r
);\r