/** @file\r
This file contains the internal functions required to generate a Firmware Volume.\r
\r
-Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>\r
This program and the accompanying materials \r
\r
#include <Guid/FfsSectionAlignmentPadding.h>\r
\r
+#include "WinNtInclude.h"\r
#include "GenFvInternalLib.h"\r
#include "FvLib.h"\r
#include "PeCoffLib.h"\r
-#include "WinNtInclude.h"\r
\r
#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION 0xEB000000\r
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000\r
\r
BOOLEAN mArm = FALSE;\r
STATIC UINT32 MaxFfsAlignment = 0;\r
+BOOLEAN VtfFileFlag = FALSE;\r
\r
EFI_GUID mEfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;\r
EFI_GUID mFileGuidArray [MAX_NUMBER_OF_FILES_IN_FV];\r
}\r
}\r
\r
- for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {\r
+ for (Index = 0; Number + Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {\r
//\r
// Read the FFS file list\r
//\r
case 0:\r
//\r
// 1 byte alignment\r
+ //if bit 1 have set, 128K byte alignmnet\r
//\r
- *Alignment = 0;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 17;\r
+ } else {\r
+ *Alignment = 0;\r
+ }\r
break;\r
\r
case 1:\r
//\r
// 16 byte alignment\r
+ //if bit 1 have set, 256K byte alignment\r
//\r
- *Alignment = 4;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 18;\r
+ } else {\r
+ *Alignment = 4;\r
+ }\r
break;\r
\r
case 2:\r
//\r
// 128 byte alignment\r
+ //if bit 1 have set, 512K byte alignment\r
//\r
- *Alignment = 7;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 19;\r
+ } else {\r
+ *Alignment = 7;\r
+ }\r
break;\r
\r
case 3:\r
//\r
// 512 byte alignment\r
+ //if bit 1 have set, 1M byte alignment\r
//\r
- *Alignment = 9;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 20;\r
+ } else {\r
+ *Alignment = 9;\r
+ }\r
break;\r
\r
case 4:\r
//\r
// 1K byte alignment\r
+ //if bit 1 have set, 2M byte alignment\r
//\r
- *Alignment = 10;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 21;\r
+ } else {\r
+ *Alignment = 10;\r
+ }\r
break;\r
\r
case 5:\r
//\r
// 4K byte alignment\r
+ //if bit 1 have set, 4M byte alignment\r
//\r
- *Alignment = 12;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 22;\r
+ } else {\r
+ *Alignment = 12;\r
+ }\r
break;\r
\r
case 6:\r
//\r
// 32K byte alignment\r
+ //if bit 1 have set , 8M byte alignment\r
//\r
- *Alignment = 15;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 23;\r
+ } else {\r
+ *Alignment = 15;\r
+ }\r
break;\r
\r
case 7:\r
//\r
// 64K byte alignment\r
+ //if bit 1 have set, 16M alignment\r
//\r
- *Alignment = 16;\r
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {\r
+ *Alignment = 24;\r
+ } else {\r
+ *Alignment = 16;\r
+ }\r
break;\r
\r
default:\r
UINTN PadFileSize;\r
UINT32 NextFfsHeaderSize;\r
UINT32 CurFfsHeaderSize;\r
+ UINT32 Index;\r
\r
+ Index = 0;\r
CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);\r
//\r
// Verify input parameters.\r
//\r
// Copy Fv Extension Header and Set Fv Extension header offset\r
//\r
+ if (ExtHeader->ExtHeaderSize > sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER)) {\r
+ for (Index = sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER); Index < ExtHeader->ExtHeaderSize;) {\r
+ if (((EFI_FIRMWARE_VOLUME_EXT_ENTRY *)((UINT8 *)ExtHeader + Index))-> ExtEntryType == EFI_FV_EXT_TYPE_USED_SIZE_TYPE) {\r
+ if (VtfFileFlag) {\r
+ ((EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)((UINT8 *)ExtHeader + Index))->UsedSize = mFvTotalSize;\r
+ } else {\r
+ ((EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)((UINT8 *)ExtHeader + Index))->UsedSize = mFvTakenSize;\r
+ }\r
+ break;\r
+ }\r
+ Index += ((EFI_FIRMWARE_VOLUME_EXT_ENTRY *)((UINT8 *)ExtHeader + Index))-> ExtEntrySize;\r
+ }\r
+ }\r
memcpy ((UINT8 *)PadFile + CurFfsHeaderSize, ExtHeader, ExtHeader->ExtHeaderSize);\r
((EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage)->ExtHeaderOffset = (UINT16) ((UINTN) ((UINT8 *)PadFile + CurFfsHeaderSize) - (UINTN) FvImage->FileImage);\r
//\r
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
EFI_TE_IMAGE_HEADER *TEImageHeader;\r
EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
- unsigned long long TempLongAddress;\r
+ long long TempLongAddress;\r
UINT32 TextVirtualAddress;\r
UINT32 DataVirtualAddress;\r
EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress;\r
//\r
// Construct Map file Name \r
//\r
- strcpy (PeMapFileName, FileName);\r
+ if (strlen (FileName) >= MAX_LONG_FILE_PATH) {\r
+ return EFI_ABORTED;\r
+ }\r
+ strncpy (PeMapFileName, FileName, MAX_LONG_FILE_PATH - 1);\r
+ PeMapFileName[MAX_LONG_FILE_PATH - 1] = 0;\r
\r
//\r
// Change '\\' to '/', unified path format.\r
Cptr --;\r
}\r
*Cptr2 = '\0';\r
- strcpy (KeyWord, Cptr + 1);\r
+ if (strlen (Cptr + 1) >= MAX_LINE_LEN) {\r
+ return EFI_ABORTED;\r
+ }\r
+ strncpy (KeyWord, Cptr + 1, MAX_LINE_LEN - 1);\r
+ KeyWord[MAX_LINE_LEN - 1] = 0;\r
*Cptr2 = '.';\r
\r
//\r
// Clear the alignment bits: these have become meaningless now that we have\r
// adjusted the padding section.\r
//\r
- FfsFile->Attributes &= ~FFS_ATTRIB_DATA_ALIGNMENT;\r
+ FfsFile->Attributes &= ~(FFS_ATTRIB_DATA_ALIGNMENT | FFS_ATTRIB_DATA_ALIGNMENT2);\r
\r
//\r
// Recalculate the FFS header checksum. Instead of setting Header and State\r
//\r
FileBuffer = malloc (FileSize);\r
if (FileBuffer == NULL) {\r
+ fclose (NewFile);\r
Error (NULL, 0, 4001, "Resouce", "memory cannot be allocated!");\r
return EFI_OUT_OF_RESOURCES;\r
}\r
if (CompareGuid ((EFI_GUID *) FileBuffer, &mFileGuidArray [Index1]) == 0) {\r
Error (NULL, 0, 2000, "Invalid parameter", "the %dth file and %uth file have the same file GUID.", (unsigned) Index1 + 1, (unsigned) Index + 1);\r
PrintGuid ((EFI_GUID *) FileBuffer);\r
+ free (FileBuffer);\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r
UINT8 *FvImage;\r
UINTN FvImageSize;\r
FILE *FvFile;\r
- CHAR8 FvMapName [MAX_LONG_FILE_PATH];\r
+ CHAR8 *FvMapName;\r
FILE *FvMapFile;\r
EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;\r
FILE *FvExtHeaderFile;\r
UINTN FileSize;\r
- CHAR8 FvReportName[MAX_LONG_FILE_PATH];\r
+ CHAR8 *FvReportName;\r
FILE *FvReportFile;\r
\r
FvBufferHeader = NULL;\r
FvFile = NULL;\r
+ FvMapName = NULL;\r
FvMapFile = NULL;\r
+ FvReportName = NULL;\r
FvReportFile = NULL;\r
\r
if (InfFileImage != NULL) {\r
// Open the FV Extension Header file\r
//\r
FvExtHeaderFile = fopen (LongFilePath (mFvDataInfo.FvExtHeaderFile), "rb");\r
+ if (FvExtHeaderFile == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening file", mFvDataInfo.FvExtHeaderFile);\r
+ return EFI_ABORTED;\r
+ }\r
\r
//\r
// Get the file size\r
// FvMap file to log the function address of all modules in one Fvimage\r
//\r
if (MapFileName != NULL) {\r
+ if (strlen (MapFileName) > MAX_LONG_FILE_PATH - 1) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "MapFileName %s is too long!", MapFileName);\r
+ Status = EFI_ABORTED;\r
+ goto Finish;\r
+ }\r
+\r
+ FvMapName = malloc (strlen (MapFileName) + 1);\r
+ if (FvMapName == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Finish;\r
+ }\r
+\r
strcpy (FvMapName, MapFileName);\r
} else {\r
+ if (strlen (FvFileName) + strlen (".map") > MAX_LONG_FILE_PATH - 1) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "FvFileName %s is too long!", FvFileName);\r
+ Status = EFI_ABORTED;\r
+ goto Finish;\r
+ }\r
+\r
+ FvMapName = malloc (strlen (FvFileName) + strlen (".map") + 1);\r
+ if (FvMapName == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Finish;\r
+ }\r
+\r
strcpy (FvMapName, FvFileName);\r
strcat (FvMapName, ".map");\r
}\r
//\r
// FvReport file to log the FV information in one Fvimage\r
//\r
+ if (strlen (FvFileName) + strlen (".txt") > MAX_LONG_FILE_PATH - 1) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "FvFileName %s is too long!", FvFileName);\r
+ Status = EFI_ABORTED;\r
+ goto Finish;\r
+ }\r
+\r
+ FvReportName = malloc (strlen (FvFileName) + strlen (".txt") + 1);\r
+ if (FvReportName == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Finish;\r
+ }\r
+\r
strcpy (FvReportName, FvFileName);\r
strcat (FvReportName, ".txt");\r
\r
//\r
Status = CalculateFvSize (&mFvDataInfo);\r
if (EFI_ERROR (Status)) {\r
- return Status; \r
+ goto Finish;\r
}\r
VerboseMsg ("the generated FV image size is %u bytes", (unsigned) mFvDataInfo.Size);\r
\r
//\r
FvBufferHeader = malloc (FvImageSize + sizeof (UINT64));\r
if (FvBufferHeader == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Finish;\r
}\r
FvImage = (UINT8 *) (((UINTN) FvBufferHeader + 7) & ~7);\r
\r
FvMapFile = fopen (LongFilePath (FvMapName), "w");\r
if (FvMapFile == NULL) {\r
Error (NULL, 0, 0001, "Error opening file", FvMapName);\r
- return EFI_ABORTED;\r
+ Status = EFI_ABORTED;\r
+ goto Finish;\r
}\r
\r
//\r
FvReportFile = fopen (LongFilePath (FvReportName), "w");\r
if (FvReportFile == NULL) {\r
Error (NULL, 0, 0001, "Error opening file", FvReportName);\r
- return EFI_ABORTED;\r
+ Status = EFI_ABORTED;\r
+ goto Finish;\r
}\r
//\r
// record FV size information into FvMap file.\r
if (FvExtHeader != NULL) {\r
free (FvExtHeader);\r
}\r
+\r
+ if (FvMapName != NULL) {\r
+ free (FvMapName);\r
+ }\r
+\r
+ if (FvReportName != NULL) {\r
+ free (FvReportName);\r
+ }\r
\r
if (FvFile != NULL) {\r
fflush (FvFile);\r
UINT32 FfsAlignment;\r
UINT32 FfsHeaderSize;\r
EFI_FFS_FILE_HEADER FfsHeader;\r
- BOOLEAN VtfFileFlag;\r
UINTN VtfFileSize;\r
\r
FvExtendHeaderSize = 0;\r
VtfFileSize = 0;\r
- VtfFileFlag = FALSE;\r
fpin = NULL;\r
Index = 0;\r
\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
+ Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);\r
return EFI_ABORTED;\r
}\r
//\r
//\r
// Construct the original efi file Name \r
//\r
- strcpy (PeFileName, FileName);\r
+ if (strlen (FileName) >= MAX_LONG_FILE_PATH) {\r
+ Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);\r
+ return EFI_ABORTED;\r
+ }\r
+ strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1);\r
+ PeFileName[MAX_LONG_FILE_PATH - 1] = 0;\r
Cptr = PeFileName + strlen (PeFileName);\r
while (*Cptr != '.') {\r
Cptr --;\r
PeFileSize = _filelength (fileno (PeFile));\r
PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
if (PeFileBuffer == NULL) {\r
+ fclose (PeFile);\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
return EFI_OUT_OF_RESOURCES;\r
}\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
+ Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);\r
return EFI_ABORTED;\r
}\r
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;\r
//\r
// Construct the original efi file name \r
//\r
- strcpy (PeFileName, FileName);\r
+ if (strlen (FileName) >= MAX_LONG_FILE_PATH) {\r
+ Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);\r
+ return EFI_ABORTED;\r
+ }\r
+ strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1);\r
+ PeFileName[MAX_LONG_FILE_PATH - 1] = 0;\r
Cptr = PeFileName + strlen (PeFileName);\r
while (*Cptr != '.') {\r
Cptr --;\r
PeFileSize = _filelength (fileno (PeFile));\r
PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
if (PeFileBuffer == NULL) {\r
+ fclose (PeFile);\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
fwrite (CapBuffer, 1, CapSize, fpout);\r
fclose (fpout);\r
+ free (CapBuffer);\r
\r
VerboseMsg ("The size of the generated capsule image is %u bytes", (unsigned) CapSize);\r
\r