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);