]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFv/GenFvInternalLib.c
BaseTools: PI 1.6 to support FV extended header contain FV used size
[mirror_edk2.git] / BaseTools / Source / C / GenFv / GenFvInternalLib.c
index fab7c940e0de89f422e4986f97dbf187c18da2c2..2b80e7919ba250c3ce1d4de6a5f13ad790787855 100644 (file)
@@ -1,7 +1,7 @@
 /** @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 - 2017, 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
@@ -44,6 +44,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \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
@@ -374,7 +375,7 @@ Returns:
     }\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
@@ -464,57 +465,97 @@ Returns:
   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
@@ -560,7 +601,9 @@ Returns:
   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
@@ -665,6 +708,19 @@ Returns:
     //\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
@@ -751,7 +807,7 @@ Returns:
   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
@@ -1060,7 +1116,7 @@ Returns:
   // 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
@@ -1161,6 +1217,7 @@ Returns:
   //\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
@@ -1220,6 +1277,7 @@ Returns:
     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
@@ -2418,17 +2476,19 @@ Returns:
   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
@@ -2494,6 +2554,10 @@ Returns:
     // 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
@@ -2562,8 +2626,34 @@ Returns:
   // 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
@@ -2572,6 +2662,19 @@ Returns:
   //\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
@@ -2581,7 +2684,7 @@ Returns:
   //\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
@@ -2595,7 +2698,8 @@ Returns:
   //\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
@@ -2687,7 +2791,8 @@ Returns:
   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
@@ -2696,7 +2801,8 @@ Returns:
   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
@@ -2848,6 +2954,14 @@ Finish:
   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
@@ -2961,12 +3075,10 @@ Returns:
   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
@@ -3449,6 +3561,7 @@ Returns:
           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
@@ -3704,6 +3817,7 @@ Returns:
         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
@@ -4206,6 +4320,7 @@ Returns:
 \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