X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FC%2FGenFv%2FGenFvInternalLib.c;h=2b80e7919ba250c3ce1d4de6a5f13ad790787855;hb=9425b34925d0cf1b96aaf2c316d3299df9780252;hp=123e3550dd97d027685ba33d3d6a2649b98509a4;hpb=adb6ac256338329883e4d8fafaa8c753dba707c9;p=mirror_edk2.git
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 123e3550dd..2b80e7919b 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -1,7 +1,7 @@
/** @file
This file contains the internal functions required to generate a Firmware Volume.
-Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
Portions Copyright (c) 2016 HP Development Company, L.P.
This program and the accompanying materials
@@ -44,6 +44,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
BOOLEAN mArm = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
+BOOLEAN VtfFileFlag = FALSE;
EFI_GUID mEfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;
EFI_GUID mFileGuidArray [MAX_NUMBER_OF_FILES_IN_FV];
@@ -374,7 +375,7 @@ Returns:
}
}
- for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {
+ for (Index = 0; Number + Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {
//
// Read the FFS file list
//
@@ -464,57 +465,97 @@ Returns:
case 0:
//
// 1 byte alignment
+ //if bit 1 have set, 128K byte alignmnet
//
- *Alignment = 0;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 17;
+ } else {
+ *Alignment = 0;
+ }
break;
case 1:
//
// 16 byte alignment
+ //if bit 1 have set, 256K byte alignment
//
- *Alignment = 4;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 18;
+ } else {
+ *Alignment = 4;
+ }
break;
case 2:
//
// 128 byte alignment
+ //if bit 1 have set, 512K byte alignment
//
- *Alignment = 7;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 19;
+ } else {
+ *Alignment = 7;
+ }
break;
case 3:
//
// 512 byte alignment
+ //if bit 1 have set, 1M byte alignment
//
- *Alignment = 9;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 20;
+ } else {
+ *Alignment = 9;
+ }
break;
case 4:
//
// 1K byte alignment
+ //if bit 1 have set, 2M byte alignment
//
- *Alignment = 10;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 21;
+ } else {
+ *Alignment = 10;
+ }
break;
case 5:
//
// 4K byte alignment
+ //if bit 1 have set, 4M byte alignment
//
- *Alignment = 12;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 22;
+ } else {
+ *Alignment = 12;
+ }
break;
case 6:
//
// 32K byte alignment
+ //if bit 1 have set , 8M byte alignment
//
- *Alignment = 15;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 23;
+ } else {
+ *Alignment = 15;
+ }
break;
case 7:
//
// 64K byte alignment
+ //if bit 1 have set, 16M alignment
//
- *Alignment = 16;
+ if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
+ *Alignment = 24;
+ } else {
+ *Alignment = 16;
+ }
break;
default:
@@ -560,7 +601,9 @@ Returns:
UINTN PadFileSize;
UINT32 NextFfsHeaderSize;
UINT32 CurFfsHeaderSize;
+ UINT32 Index;
+ Index = 0;
CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
//
// Verify input parameters.
@@ -665,6 +708,19 @@ Returns:
//
// Copy Fv Extension Header and Set Fv Extension header offset
//
+ if (ExtHeader->ExtHeaderSize > sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER)) {
+ for (Index = sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER); Index < ExtHeader->ExtHeaderSize;) {
+ if (((EFI_FIRMWARE_VOLUME_EXT_ENTRY *)((UINT8 *)ExtHeader + Index))-> ExtEntryType == EFI_FV_EXT_TYPE_USED_SIZE_TYPE) {
+ if (VtfFileFlag) {
+ ((EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)((UINT8 *)ExtHeader + Index))->UsedSize = mFvTotalSize;
+ } else {
+ ((EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)((UINT8 *)ExtHeader + Index))->UsedSize = mFvTakenSize;
+ }
+ break;
+ }
+ Index += ((EFI_FIRMWARE_VOLUME_EXT_ENTRY *)((UINT8 *)ExtHeader + Index))-> ExtEntrySize;
+ }
+ }
memcpy ((UINT8 *)PadFile + CurFfsHeaderSize, ExtHeader, ExtHeader->ExtHeaderSize);
((EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage)->ExtHeaderOffset = (UINT16) ((UINTN) ((UINT8 *)PadFile + CurFfsHeaderSize) - (UINTN) FvImage->FileImage);
//
@@ -751,7 +807,7 @@ Returns:
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
EFI_TE_IMAGE_HEADER *TEImageHeader;
EFI_IMAGE_SECTION_HEADER *SectionHeader;
- unsigned long long TempLongAddress;
+ long long TempLongAddress;
UINT32 TextVirtualAddress;
UINT32 DataVirtualAddress;
EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress;
@@ -1060,7 +1116,7 @@ Returns:
// Clear the alignment bits: these have become meaningless now that we have
// adjusted the padding section.
//
- FfsFile->Attributes &= ~FFS_ATTRIB_DATA_ALIGNMENT;
+ FfsFile->Attributes &= ~(FFS_ATTRIB_DATA_ALIGNMENT | FFS_ATTRIB_DATA_ALIGNMENT2);
//
// Recalculate the FFS header checksum. Instead of setting Header and State
@@ -1161,6 +1217,7 @@ Returns:
//
FileBuffer = malloc (FileSize);
if (FileBuffer == NULL) {
+ fclose (NewFile);
Error (NULL, 0, 4001, "Resouce", "memory cannot be allocated!");
return EFI_OUT_OF_RESOURCES;
}
@@ -1220,6 +1277,7 @@ Returns:
if (CompareGuid ((EFI_GUID *) FileBuffer, &mFileGuidArray [Index1]) == 0) {
Error (NULL, 0, 2000, "Invalid parameter", "the %dth file and %uth file have the same file GUID.", (unsigned) Index1 + 1, (unsigned) Index + 1);
PrintGuid ((EFI_GUID *) FileBuffer);
+ free (FileBuffer);
return EFI_INVALID_PARAMETER;
}
}
@@ -2418,17 +2476,19 @@ Returns:
UINT8 *FvImage;
UINTN FvImageSize;
FILE *FvFile;
- CHAR8 FvMapName [MAX_LONG_FILE_PATH];
+ CHAR8 *FvMapName;
FILE *FvMapFile;
EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
FILE *FvExtHeaderFile;
UINTN FileSize;
- CHAR8 FvReportName[MAX_LONG_FILE_PATH];
+ CHAR8 *FvReportName;
FILE *FvReportFile;
FvBufferHeader = NULL;
FvFile = NULL;
+ FvMapName = NULL;
FvMapFile = NULL;
+ FvReportName = NULL;
FvReportFile = NULL;
if (InfFileImage != NULL) {
@@ -2494,6 +2554,10 @@ Returns:
// Open the FV Extension Header file
//
FvExtHeaderFile = fopen (LongFilePath (mFvDataInfo.FvExtHeaderFile), "rb");
+ if (FvExtHeaderFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mFvDataInfo.FvExtHeaderFile);
+ return EFI_ABORTED;
+ }
//
// Get the file size
@@ -2562,8 +2626,34 @@ Returns:
// FvMap file to log the function address of all modules in one Fvimage
//
if (MapFileName != NULL) {
+ if (strlen (MapFileName) > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "MapFileName %s is too long!", MapFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ FvMapName = malloc (strlen (MapFileName) + 1);
+ if (FvMapName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
strcpy (FvMapName, MapFileName);
} else {
+ if (strlen (FvFileName) + strlen (".map") > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "FvFileName %s is too long!", FvFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ FvMapName = malloc (strlen (FvFileName) + strlen (".map") + 1);
+ if (FvMapName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
strcpy (FvMapName, FvFileName);
strcat (FvMapName, ".map");
}
@@ -2572,6 +2662,19 @@ Returns:
//
// FvReport file to log the FV information in one Fvimage
//
+ if (strlen (FvFileName) + strlen (".txt") > MAX_LONG_FILE_PATH - 1) {
+ Error (NULL, 0, 1003, "Invalid option value", "FvFileName %s is too long!", FvFileName);
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ FvReportName = malloc (strlen (FvFileName) + strlen (".txt") + 1);
+ if (FvReportName == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
strcpy (FvReportName, FvFileName);
strcat (FvReportName, ".txt");
@@ -2581,7 +2684,7 @@ Returns:
//
Status = CalculateFvSize (&mFvDataInfo);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Finish;
}
VerboseMsg ("the generated FV image size is %u bytes", (unsigned) mFvDataInfo.Size);
@@ -2595,7 +2698,8 @@ Returns:
//
FvBufferHeader = malloc (FvImageSize + sizeof (UINT64));
if (FvBufferHeader == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
}
FvImage = (UINT8 *) (((UINTN) FvBufferHeader + 7) & ~7);
@@ -2687,7 +2791,8 @@ Returns:
FvMapFile = fopen (LongFilePath (FvMapName), "w");
if (FvMapFile == NULL) {
Error (NULL, 0, 0001, "Error opening file", FvMapName);
- return EFI_ABORTED;
+ Status = EFI_ABORTED;
+ goto Finish;
}
//
@@ -2696,7 +2801,8 @@ Returns:
FvReportFile = fopen (LongFilePath (FvReportName), "w");
if (FvReportFile == NULL) {
Error (NULL, 0, 0001, "Error opening file", FvReportName);
- return EFI_ABORTED;
+ Status = EFI_ABORTED;
+ goto Finish;
}
//
// record FV size information into FvMap file.
@@ -2770,13 +2876,13 @@ Returns:
//
// Update reset vector (SALE_ENTRY for IPF)
// Now for IA32 and IA64 platform, the fv which has bsf file must have the
- // EndAddress of 0xFFFFFFFF (unless the section was rebased).
- // Thus, only this type fv needs to update the reset vector.
- // If the PEI Core is found, the VTF file will probably get
- // corrupted by updating the entry point.
+ // EndAddress of 0xFFFFFFFF (unless the section was rebased).
+ // Thus, only this type fv needs to update the reset vector.
+ // If the PEI Core is found, the VTF file will probably get
+ // corrupted by updating the entry point.
//
- if (mFvDataInfo.ForceRebase == 1 ||
- (mFvDataInfo.BaseAddress + mFvDataInfo.Size) == FV_IMAGES_TOP_ADDRESS) {
+ if (mFvDataInfo.ForceRebase == 1 ||
+ (mFvDataInfo.BaseAddress + mFvDataInfo.Size) == FV_IMAGES_TOP_ADDRESS) {
Status = UpdateResetVector (&FvImageMemoryFile, &mFvDataInfo, VtfFileImage);
if (EFI_ERROR(Status)) {
Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");
@@ -2848,6 +2954,14 @@ Finish:
if (FvExtHeader != NULL) {
free (FvExtHeader);
}
+
+ if (FvMapName != NULL) {
+ free (FvMapName);
+ }
+
+ if (FvReportName != NULL) {
+ free (FvReportName);
+ }
if (FvFile != NULL) {
fflush (FvFile);
@@ -2961,12 +3075,10 @@ Returns:
UINT32 FfsAlignment;
UINT32 FfsHeaderSize;
EFI_FFS_FILE_HEADER FfsHeader;
- BOOLEAN VtfFileFlag;
UINTN VtfFileSize;
FvExtendHeaderSize = 0;
VtfFileSize = 0;
- VtfFileFlag = FALSE;
fpin = NULL;
Index = 0;
@@ -3449,6 +3561,7 @@ Returns:
PeFileSize = _filelength (fileno (PeFile));
PeFileBuffer = (UINT8 *) malloc (PeFileSize);
if (PeFileBuffer == NULL) {
+ fclose (PeFile);
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
return EFI_OUT_OF_RESOURCES;
}
@@ -3704,6 +3817,7 @@ Returns:
PeFileSize = _filelength (fileno (PeFile));
PeFileBuffer = (UINT8 *) malloc (PeFileSize);
if (PeFileBuffer == NULL) {
+ fclose (PeFile);
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
return EFI_OUT_OF_RESOURCES;
}
@@ -4206,6 +4320,7 @@ Returns:
fwrite (CapBuffer, 1, CapSize, fpout);
fclose (fpout);
+ free (CapBuffer);
VerboseMsg ("The size of the generated capsule image is %u bytes", (unsigned) CapSize);