[edk2-devel] [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2

GregX Yeh gregx.yeh at intel.com
Tue Nov 3 05:47:11 UTC 2020


Fixed replace file failure when FFS in multi level FV and FV level over 2.

Signed-off-by: GregX Yeh <gregx.yeh at intel.com>
Cc: Bob Feng <bob.c.feng at intel.com>
Cc: Liming Gao <gaoliming at byosoft.com.cn>
---
 BaseTools/Source/C/FMMT/FirmwareModuleManagement.c |   2 +-
 BaseTools/Source/C/FMMT/FirmwareModuleManagement.h |   3 +-
 BaseTools/Source/C/FMMT/FmmtLib.c                  | 171 ++++++++++++++-------
 3 files changed, 118 insertions(+), 58 deletions(-)

diff --git a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c
index 38056153fb..dfad02838b 100644
--- a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c
+++ b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.c
@@ -615,7 +615,7 @@ static UINT32 FindFile(FV_INFORMATION *FvInFd, UINT8 FvLevel, CHAR8 *File, UINT3
     return 0;
   }
   LibAscii2Unicode(File, UIName);
-  for (Index = 0; Index <= FvInFd->FfsNumbers; Index++) {
+  for (Index = 0; Index < FvInFd->FfsNumbers; Index++) {
     //
     // Compare the New File Name with UI Name of FFS
     // NOTE: The UI Name is Unicode, but the New File Name is Ascii.
diff --git a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h
index 9d09c9160a..da9eb1a4b9 100644
--- a/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h
+++ b/BaseTools/Source/C/FMMT/FirmwareModuleManagement.h
@@ -2,7 +2,7 @@
 
  Structures and functions declaration.
 
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -284,6 +284,7 @@ typedef struct _FFS_INFOMATION{
   UINT8                      *Depex;
   UINT32                     DepexLen;
   BOOLEAN                    FfsFoundFlag;
+  UINT8                      FvLevel;
   struct _FFS_INFOMATION     *Next;
 } FFS_INFORMATION;
 
diff --git a/BaseTools/Source/C/FMMT/FmmtLib.c b/BaseTools/Source/C/FMMT/FmmtLib.c
index b945e9b63d..9bccd634bb 100644
--- a/BaseTools/Source/C/FMMT/FmmtLib.c
+++ b/BaseTools/Source/C/FMMT/FmmtLib.c
@@ -523,7 +523,7 @@ LibReadFvHeader (
            FvExtHeader->FvName.Data4[6],
            FvExtHeader->FvName.Data4[7]);
     LibExtractFvUiName(FvExtHeader, &FvUiName);
-    if (FvUiName != NULL && FvLevel == 1) {
+    if (FvUiName != NULL && (FvLevel - 1) != 0) {
       printf("%sFV UI Name:            %s\n\n", BlankSpace, FvUiName);
     }
     free(FvUiName);
@@ -709,10 +709,10 @@ LibGenFfsFile (
   free(FfsFileName);
   FfsFileName = NULL;
 
-  CurrentFv->FfsNumbers  = *FfsCount;
-
   *FfsCount += 1;
 
+  CurrentFv->FfsNumbers  = *FfsCount;
+
   if (ErasePolarity) {
     CurrentFile->State = (UINT8)~(CurrentFile->State);
   }
@@ -789,7 +789,8 @@ LibParseSection (
   UINT8                  *FvCount,
   BOOLEAN                ViewFlag,
   BOOLEAN                ErasePolarity,
-  BOOLEAN                *IsFfsGenerated
+  BOOLEAN                *IsFfsGenerated,
+  UINT32                 *FfsIndex
   )
 {
   UINT32              ParsedLength;
@@ -1147,19 +1148,21 @@ LibParseSection (
         return EFI_SECTION_ERROR;
       }
 
-      Status = LibParseSection (  UncompressedBuffer,
-                                  UncompressedLength,
-                                  CurrentFv,
-                                  FvName,
-                                  CurrentFile,
-                                  Level,
-                                  &LocalEncapData,
-                                  FfsLevel,
-                                  FfsCount,
-                                  FvCount,
-                                  ViewFlag,
-                                  ErasePolarity,
-                                  IsFfsGenerated);
+      Status = LibParseSection (UncompressedBuffer,
+                                UncompressedLength,
+                                CurrentFv,
+                                FvName,
+                                CurrentFile,
+                                Level,
+                                &LocalEncapData,
+                                FfsLevel,
+                                FfsCount,
+                                FvCount,
+                                ViewFlag,
+                                ErasePolarity,
+                                IsFfsGenerated,
+                                FfsIndex
+                                );
 
       if (CompressionType == EFI_STANDARD_COMPRESSION) {
         //
@@ -1216,7 +1219,8 @@ LibParseSection (
                 FvCount,
                 ViewFlag,
                 ErasePolarity,
-                IsFfsGenerated
+                IsFfsGenerated,
+                FfsIndex
                 );
         if (EFI_ERROR(Status)) {
           Error(NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
@@ -1471,7 +1475,8 @@ LibParseSection (
                   FvCount,
                   ViewFlag,
                   ErasePolarity,
-                  IsFfsGenerated
+                  IsFfsGenerated,
+                  FfsIndex
                   );
         if (EFI_ERROR (Status)) {
           Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
@@ -1491,7 +1496,8 @@ LibParseSection (
             FvCount,
             ViewFlag,
             ErasePolarity,
-            IsFfsGenerated
+            IsFfsGenerated,
+            FfsIndex
             );
           if (ExtractionTool != NULL) {
             free (ExtractionTool);
@@ -1527,6 +1533,7 @@ LibParseSection (
         if (!*IsFfsGenerated) {
           LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
           *IsFfsGenerated = TRUE;
+          *FfsIndex = *FfsCount;
         }
       }
 
@@ -1538,6 +1545,7 @@ LibParseSection (
         if (!*IsFfsGenerated) {
           LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
           *IsFfsGenerated = TRUE;
+          *FfsIndex = *FfsCount;
         }
       }
 
@@ -1549,6 +1557,7 @@ LibParseSection (
         if (!*IsFfsGenerated) {
           LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
           *IsFfsGenerated = TRUE;
+          *FfsIndex = *FfsCount;
         }
       }
 
@@ -1560,6 +1569,7 @@ LibParseSection (
         if (!*IsFfsGenerated) {
           LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
           *IsFfsGenerated = TRUE;
+          *FfsIndex = *FfsCount;
         }
       }
       break;
@@ -1571,6 +1581,7 @@ LibParseSection (
         if (!*IsFfsGenerated) {
           LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
           *IsFfsGenerated = TRUE;
+          *FfsIndex = *FfsCount;
         }
       }
       break;
@@ -1582,6 +1593,7 @@ LibParseSection (
         if (!*IsFfsGenerated) {
           LibGenFfsFile(CurrentFile, CurrentFv, FvName, Level, FfsCount, ErasePolarity);
           *IsFfsGenerated = TRUE;
+          *FfsIndex = *FfsCount;
         }
       }
       break;
@@ -1665,11 +1677,11 @@ LibParseSection (
       // If Ffs file has been generated, then the FfsCount should decrease 1.
       //
       if (*IsFfsGenerated) {
-        memcpy (CurrentFv->FfsAttuibutes[*FfsCount -1].UiName, UIName, UINameSize);
-        CurrentFv->FfsAttuibutes[*FfsCount -1].UiNameSize = UINameSize;
+        memcpy (CurrentFv->FfsAttuibutes[*FfsIndex - 1].UiName, UIName, UINameSize);
+        CurrentFv->FfsAttuibutes[*FfsIndex - 1].UiNameSize = UINameSize;
       } else {
-        memcpy (CurrentFv->FfsAttuibutes[*FfsCount].UiName, UIName, UINameSize);
-        CurrentFv->FfsAttuibutes[*FfsCount].UiNameSize = UINameSize;
+        memcpy (CurrentFv->FfsAttuibutes[*FfsIndex].UiName, UIName, UINameSize);
+        CurrentFv->FfsAttuibutes[*FfsIndex].UiNameSize = UINameSize;
       }
 
       HasDepexSection = FALSE;
@@ -1682,7 +1694,9 @@ LibParseSection (
     }
 
     ParsedLength += SectionLength;
-    FirstInFlag  = FALSE;
+    if (Type != EFI_SECTION_PEI_DEPEX && Type != EFI_SECTION_DXE_DEPEX) {
+      FirstInFlag  = FALSE;
+    }
     //
     // We make then next section begin on a 4-byte boundary
     //
@@ -1872,12 +1886,14 @@ LibGetFileInfo (
   BOOLEAN             IsGeneratedFfs;
   UINT32              FfsFileHeaderSize;
   CHAR8               *BlankChar;
+  UINT32              FfsIndex;
 
   Status = EFI_SUCCESS;
 
   LocalEncapData  = NULL;
   EncapDataNeedUpdateFlag = TRUE;
   IsGeneratedFfs   = FALSE;
+  FfsIndex        = 0xFFFFFFFF;
   BlankChar        = NULL;
 
   FfsFileHeaderSize = GetFfsHeaderLength  ((EFI_FFS_FILE_HEADER *) CurrentFile);
@@ -2083,24 +2099,25 @@ LibGetFileInfo (
     } else if( CurrentFile->Type == EFI_FV_FILETYPE_FFS_PAD){
       //EFI_FV_FILETYPE_FFS_PAD
     } else {
-    //
-    // All other files have sections
-    //
-    Status = LibParseSection (
-      (UINT8 *) ((UINTN) CurrentFile + FfsFileHeaderSize),
-      FileLength - FfsFileHeaderSize,
-      CurrentFv,
-      FvName,
-      CurrentFile,
-      Level,
-      &LocalEncapData,
-      Level,
-      FfsCount,
-      FvCount,
-      ViewFlag,
-      ErasePolarity,
-      &IsGeneratedFfs
-      );
+      //
+      // All other files have sections
+      //
+      Status = LibParseSection (
+                 (UINT8 *) ((UINTN) CurrentFile + FfsFileHeaderSize),
+                 FileLength - FfsFileHeaderSize,
+                 CurrentFv,
+                 FvName,
+                 CurrentFile,
+                 Level,
+                 &LocalEncapData,
+                 Level,
+                 FfsCount,
+                 FvCount,
+                 ViewFlag,
+                 ErasePolarity,
+                 &IsGeneratedFfs,
+                 &FfsIndex
+                 );
     }
     if (EFI_ERROR (Status)) {
       printf ("ERROR: Parsing the FFS file.\n");
@@ -2144,6 +2161,7 @@ LibGetFvInfo (
   EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHdrPtr;
   EFI_FIRMWARE_VOLUME_HEADER *FvHdr;
   UINT8                      PreFvId;
+  UINT8                       GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
 
   NumberOfFiles  = 0;
   Key            = 0;
@@ -2344,9 +2362,10 @@ LibGetFvInfo (
 
     CurrentFv->FfsAttuibutes[*FfsCount].FvLevel = CurrentFv->FvLevel;
     CurrentFv->FfsAttuibutes[*FfsCount].FvId    = PreFvId;
-     if (CurrentFv->FvLevel > CurrentFv->MulFvLevel) {
+    if (CurrentFv->FvLevel > CurrentFv->MulFvLevel) {
       CurrentFv->MulFvLevel = CurrentFv->FvLevel;
-   }
+    }
+    PrintGuidToBuffer (&(CurrentFile->Name), GuidBuffer, PRINTED_GUID_BUFFER_SIZE, FALSE);
     //
     // Display info about this file
     //
@@ -4198,10 +4217,13 @@ LibEncapNewFvFile(
   UINT32                      header;
   UINT8                       AlignN;
   UINT8                       AlignV[1] = {0xFF};
+  UINT32                      EntryFvId;
+
   AlignN                      = 0;
   Id                          = 0;
   InputFileSize               = 0;
   TmpFileSize                 = 0;
+  AlignmentFileSize           = 0;
   EncapFvIndex                = 0;
   Index                       = 0;
   OuterIndex                  = 0;
@@ -4224,7 +4246,7 @@ LibEncapNewFvFile(
   IsLargeFile                 = FALSE;
   OutputFileSize              = 0;
   LargeFileSize               = 0x1000000;
-
+  EntryFvId                   = 0;
 
   OutputFileNameList = (FFS_INFORMATION *)malloc(sizeof(FFS_INFORMATION));
   if (OutputFileNameList == NULL) {
@@ -4240,6 +4262,7 @@ LibEncapNewFvFile(
   OutputFileNameList->Depex = NULL;
   OutputFileNameList->DepexLen = 0;
   OutputFileNameList->FfsFoundFlag = FALSE;
+  OutputFileNameList->FvLevel = 0;
 
   ChildFileNameList = (FFS_INFORMATION *)malloc(sizeof(FFS_INFORMATION));
   if (ChildFileNameList == NULL) {
@@ -4258,12 +4281,16 @@ LibEncapNewFvFile(
   //
   // Encapsulate from the lowest FFS file level.
   //
-    LocalEncapData = CurrentEncapData;
-    if (LocalEncapData == NULL) {
-        LocalEncapData = FvInFd->EncapData;
-    }
-    Level = LocalEncapData->Level;
-    Type = LocalEncapData->Type;
+  LocalEncapData = CurrentEncapData;
+  if (LocalEncapData == NULL) {
+    LocalEncapData = FvInFd->EncapData;
+    EntryFvId = 0xFFFFFFFF;
+  } else {
+    EntryFvId = LocalEncapData->FvId;
+  }
+
+  Level = LocalEncapData->Level;
+  Type  = LocalEncapData->Type;
 
   if (CurrentEncapData == NULL) {
     LocalEncapData = FvInFd->EncapData;
@@ -4278,6 +4305,7 @@ LibEncapNewFvFile(
                 ChildFileNameList->ParentLevel = LocalEncapDataTemp->Level -1;
                 if (FvInFd->ChildFvFFS == NULL) {
                     FvInFd->ChildFvFFS = ChildFileNameList;
+                    NewFileNameList = FvInFd->ChildFvFFS;
                 } else {
                     NewFileNameList = FvInFd->ChildFvFFS;
                     while (NewFileNameList->Next != NULL) {
@@ -4325,6 +4353,12 @@ LibEncapNewFvFile(
         Type        = LocalEncapData->Type;
       }
       LocalEncapData = LocalEncapData->NextNode;
+      if (LocalEncapData == NULL) {
+        if (Type == FMMT_ENCAP_TREE_FV) {
+          ParentLevel = Level;
+          ParentType  = Type;
+        }
+      }
     }
   } else {
     LocalEncapData = CurrentEncapData;
@@ -4349,6 +4383,28 @@ LibEncapNewFvFile(
             LocalEncapDataTemp = LocalEncapDataTemp->RightNode;
         }
       }
+
+      if (LocalEncapData->FvId > EntryFvId && LocalEncapData->Type == FMMT_ENCAP_TREE_FFS) {
+        LocalEncapDataTemp = LocalEncapData->RightNode;
+
+        while (LocalEncapDataTemp != NULL) {
+          LocalEncapDataNext = LocalEncapDataTemp->NextNode;
+          if (LocalEncapDataNext != NULL && LocalEncapDataNext->NextNode != NULL) {
+            LibEncapNewFvFile(FvInFd, TemDir, LocalEncapDataTemp, LocalEncapDataTemp->Level - 1, &ChildFileNameList);
+            if (FvInFd->ChildFvFFS == NULL) {
+              FvInFd->ChildFvFFS = ChildFileNameList;
+            } else {
+              NewFileNameList = FvInFd->ChildFvFFS;
+              while (NewFileNameList->Next != NULL) {
+                NewFileNameList = NewFileNameList->Next;
+              }
+              NewFileNameList->Next = ChildFileNameList;
+            }
+          }
+          LocalEncapDataTemp = LocalEncapDataTemp->RightNode;
+        }
+      }
+
       if (LocalEncapData->Level > Level) {
         if (LocalEncapData->Type == FMMT_ENCAP_TREE_FFS) {
           ParentLevel = Level;
@@ -4485,12 +4541,12 @@ LibEncapNewFvFile(
         //
         FfsFoundFlag = FALSE;
         IsRootFv = FALSE;
-        for (Index=0; Index <= FvInFd->FfsNumbers; Index++) {
+        for (Index=0; Index < FvInFd->FfsNumbers; Index++) {
             if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == FALSE){
                 break;
             }
             if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == TRUE){
-                if (Index == EncapFvIndex) {
+                if (Index == EncapFvStart) {
                     if (FirstInFlag) {
                             Status = LibAddFfsFileToFvInf (OutputFileNameList->FFSName, InfFile, TRUE);
                             FirstInFlag = FALSE;
@@ -4601,7 +4657,7 @@ LibEncapNewFvFile(
             }
           }
        // The Fv may has multiple level (> 2), when it is in the FvLevel == 2, we set the IsLastLevelFfs Flag
-       if (Index <=FvInFd->FfsNumbers && FvInFd->FfsAttuibutes[Index].FvLevel <= FvInFd->MulFvLevel) {
+       if (Index < FvInFd->FfsNumbers && FvInFd->FfsAttuibutes[Index].FvLevel <= FvInFd->MulFvLevel) {
            if (FvInFd->FfsAttuibutes[Index].FvLevel == 2) {
                IsLastLevelFfs = FALSE;
            }
@@ -4777,6 +4833,7 @@ LibEncapNewFvFile(
          for (Id = FvInFd->FfsNumbers; Id <= FvInFd->FfsNumbers; Id--) {
              if ((memcmp(&FvInFd->FfsAttuibutes[Id].GuidName, &(LocalEncapData->FvExtHeader->FvName), sizeof(EFI_GUID)) == 0)){
                  if (access(FvInFd->FfsAttuibutes[Id].FfsName, 0) != -1) {
+                     OutputFileNameList->FvLevel = FvInFd->FfsAttuibutes[Id].FvLevel;
                      Status = LibFmmtDeleteFile(FvInFd->FfsAttuibutes[Id].FfsName);
                      if (EFI_ERROR(Status)) {
                          Error("FMMT", 0, 0004, "error while encapsulate FD Image", "Delete the specified file failed!");
@@ -5079,7 +5136,9 @@ LibEncapNewFvFile(
     } else {
         if (OutputFileNameList != NULL && OutputFileNameList->FFSName != NULL && OutputFileNameList->IsFFS == TRUE) {
           *OutputFile = OutputFileNameList;
-          return EFI_SUCCESS;
+          if (OutputFileNameList->FvLevel < 2) {
+            return EFI_SUCCESS;
+          }
         }
         LocalEncapData = CurrentEncapData;
     }
-- 
2.16.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#66913): https://edk2.groups.io/g/devel/message/66913
Mute This Topic: https://groups.io/mt/78000880/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list