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

Bob Feng bob.c.feng at intel.com
Tue Nov 3 09:09:35 UTC 2020


Hi Greg,

Could you provide more details about problems that this patch fix? It would be great if you can share the test case.

FMMT tool is in the edk2-staging repo, so the patch title for FMMT should add [edk2-staging] tag.

Thanks,
Bob

-----Original Message-----
From: Yeh, GregX <gregx.yeh at intel.com> 
Sent: Tuesday, November 3, 2020 1:47 PM
To: devel at edk2.groups.io
Cc: Feng, Bob C <bob.c.feng at intel.com>; Liming Gao <gaoliming at byosoft.com.cn>
Subject: [PATCH] BaseTools/FMMT: Replace file failure when FV level over 2

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 (#66920): https://edk2.groups.io/g/devel/message/66920
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