/** @file
This file contains the internal functions required to generate a Firmware Volume.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

//
// Include files
//

#ifdef __GNUC__
#include <sys/stat.h>
#endif
#include <string.h>
#ifndef __GNUC__
#include <io.h>
#endif
#include <assert.h>

#include <Guid/FfsSectionAlignmentPadding.h>

#include "GenFvInternalLib.h"
#include "FvLib.h"
#include "PeCoffLib.h"

#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION      0x14000000

/*
 * Arm instruction to jump to Fv entry instruction in Arm or Thumb mode.
 * From ARM Arch Ref Manual versions b/c/d, section A8.8.25 BL, BLX (immediate)
 * BLX (encoding A2) branches to offset in Thumb instruction set mode.
 * BL (encoding A1) branches to offset in Arm instruction set mode.
 */
#define ARM_JUMP_OFFSET_MAX        0xffffff
#define ARM_JUMP_TO_ARM(Offset)    (0xeb000000 | ((Offset - 8) >> 2))

#define _ARM_JUMP_TO_THUMB(Imm32)  (0xfa000000 | \
                                    (((Imm32) & (1 << 1)) << (24 - 1)) | \
                                    (((Imm32) >> 2) & 0x7fffff))
#define ARM_JUMP_TO_THUMB(Offset)  _ARM_JUMP_TO_THUMB((Offset) - 8)

/*
 * Arm instruction to return from exception (MOVS PC, LR)
 */
#define ARM_RETURN_FROM_EXCEPTION  0xE1B0F07E

BOOLEAN mArm = FALSE;
BOOLEAN mRiscV = FALSE;
BOOLEAN mLoongArch = 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];
EFI_GUID  mZeroGuid                           = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
EFI_GUID  mDefaultCapsuleGuid                 = {0x3B6686BD, 0x0D76, 0x4030, { 0xB7, 0x0E, 0xB5, 0x51, 0x9E, 0x2F, 0xC5, 0xA0 }};
EFI_GUID  mEfiFfsSectionAlignmentPaddingGuid  = EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID;

CHAR8      *mFvbAttributeName[] = {
  EFI_FVB2_READ_DISABLED_CAP_STRING,
  EFI_FVB2_READ_ENABLED_CAP_STRING,
  EFI_FVB2_READ_STATUS_STRING,
  EFI_FVB2_WRITE_DISABLED_CAP_STRING,
  EFI_FVB2_WRITE_ENABLED_CAP_STRING,
  EFI_FVB2_WRITE_STATUS_STRING,
  EFI_FVB2_LOCK_CAP_STRING,
  EFI_FVB2_LOCK_STATUS_STRING,
  NULL,
  EFI_FVB2_STICKY_WRITE_STRING,
  EFI_FVB2_MEMORY_MAPPED_STRING,
  EFI_FVB2_ERASE_POLARITY_STRING,
  EFI_FVB2_READ_LOCK_CAP_STRING,
  EFI_FVB2_READ_LOCK_STATUS_STRING,
  EFI_FVB2_WRITE_LOCK_CAP_STRING,
  EFI_FVB2_WRITE_LOCK_STATUS_STRING
};

CHAR8      *mFvbAlignmentName[] = {
  EFI_FVB2_ALIGNMENT_1_STRING,
  EFI_FVB2_ALIGNMENT_2_STRING,
  EFI_FVB2_ALIGNMENT_4_STRING,
  EFI_FVB2_ALIGNMENT_8_STRING,
  EFI_FVB2_ALIGNMENT_16_STRING,
  EFI_FVB2_ALIGNMENT_32_STRING,
  EFI_FVB2_ALIGNMENT_64_STRING,
  EFI_FVB2_ALIGNMENT_128_STRING,
  EFI_FVB2_ALIGNMENT_256_STRING,
  EFI_FVB2_ALIGNMENT_512_STRING,
  EFI_FVB2_ALIGNMENT_1K_STRING,
  EFI_FVB2_ALIGNMENT_2K_STRING,
  EFI_FVB2_ALIGNMENT_4K_STRING,
  EFI_FVB2_ALIGNMENT_8K_STRING,
  EFI_FVB2_ALIGNMENT_16K_STRING,
  EFI_FVB2_ALIGNMENT_32K_STRING,
  EFI_FVB2_ALIGNMENT_64K_STRING,
  EFI_FVB2_ALIGNMENT_128K_STRING,
  EFI_FVB2_ALIGNMENT_256K_STRING,
  EFI_FVB2_ALIGNMENT_512K_STRING,
  EFI_FVB2_ALIGNMENT_1M_STRING,
  EFI_FVB2_ALIGNMENT_2M_STRING,
  EFI_FVB2_ALIGNMENT_4M_STRING,
  EFI_FVB2_ALIGNMENT_8M_STRING,
  EFI_FVB2_ALIGNMENT_16M_STRING,
  EFI_FVB2_ALIGNMENT_32M_STRING,
  EFI_FVB2_ALIGNMENT_64M_STRING,
  EFI_FVB2_ALIGNMENT_128M_STRING,
  EFI_FVB2_ALIGNMENT_256M_STRING,
  EFI_FVB2_ALIGNMENT_512M_STRING,
  EFI_FVB2_ALIGNMENT_1G_STRING,
  EFI_FVB2_ALIGNMENT_2G_STRING
};

FV_INFO                     mFvDataInfo;
CAP_INFO                    mCapDataInfo;
BOOLEAN                     mIsLargeFfs = FALSE;

EFI_PHYSICAL_ADDRESS mFvBaseAddress[0x10];
UINT32               mFvBaseAddressNumber = 0;

EFI_STATUS
ParseFvInf (
  IN  MEMORY_FILE  *InfFile,
  OUT FV_INFO      *FvInfo
  )
/*++

Routine Description:

  This function parses a FV.INF file and copies info into a FV_INFO structure.

Arguments:

  InfFile         Memory file image.
  FvInfo          Information read from INF file.

Returns:

  EFI_SUCCESS       INF file information successfully retrieved.
  EFI_ABORTED       INF file has an invalid format.
  EFI_NOT_FOUND     A required string was not found in the INF file.
--*/
{
  CHAR8       Value[MAX_LONG_FILE_PATH];
  UINT64      Value64;
  UINTN       Index;
  UINTN       Number;
  EFI_STATUS  Status;
  EFI_GUID    GuidValue;

  //
  // Read the FV base address
  //
  if (!mFvDataInfo.BaseAddressSet) {
    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_BASE_ADDRESS_STRING, 0, Value);
    if (Status == EFI_SUCCESS) {
      //
      // Get the base address
      //
      Status = AsciiStringToUint64 (Value, FALSE, &Value64);
      if (EFI_ERROR (Status)) {
        Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_BASE_ADDRESS_STRING, Value);
        return EFI_ABORTED;
      }
      DebugMsg (NULL, 0, 9, "rebase address", "%s = %s", EFI_FV_BASE_ADDRESS_STRING, Value);

      FvInfo->BaseAddress = Value64;
      FvInfo->BaseAddressSet = TRUE;
    }
  }

  //
  // Read the FV File System Guid
  //
  if (!FvInfo->FvFileSystemGuidSet) {
    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILESYSTEMGUID_STRING, 0, Value);
    if (Status == EFI_SUCCESS) {
      //
      // Get the guid value
      //
      Status = StringToGuid (Value, &GuidValue);
      if (EFI_ERROR (Status)) {
        Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_FV_FILESYSTEMGUID_STRING, Value);
        return EFI_ABORTED;
      }
      memcpy (&FvInfo->FvFileSystemGuid, &GuidValue, sizeof (EFI_GUID));
      FvInfo->FvFileSystemGuidSet = TRUE;
    }
  }

  //
  // Read the FV Extension Header File Name
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FV_EXT_HEADER_FILE_NAME, 0, Value);
  if (Status == EFI_SUCCESS) {
    strcpy (FvInfo->FvExtHeaderFile, Value);
  }

  //
  // Read the FV file name
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILE_NAME_STRING, 0, Value);
  if (Status == EFI_SUCCESS) {
    //
    // copy the file name
    //
    strcpy (FvInfo->FvName, Value);
  }

  //
  // Read Fv Attribute
  //
  for (Index = 0; Index < sizeof (mFvbAttributeName)/sizeof (CHAR8 *); Index ++) {
    if ((mFvbAttributeName [Index] != NULL) && \
        (FindToken (InfFile, ATTRIBUTES_SECTION_STRING, mFvbAttributeName [Index], 0, Value) == EFI_SUCCESS)) {
      if ((strcmp (Value, TRUE_STRING) == 0) || (strcmp (Value, ONE_STRING) == 0)) {
        FvInfo->FvAttributes |= 1 << Index;
      } else if ((strcmp (Value, FALSE_STRING) != 0) && (strcmp (Value, ZERO_STRING) != 0)) {
        Error (NULL, 0, 2000, "Invalid parameter", "%s expected %s | %s", mFvbAttributeName [Index], TRUE_STRING, FALSE_STRING);
        return EFI_ABORTED;
      }
    }
  }

  //
  // Read Fv Alignment
  //
  for (Index = 0; Index < sizeof (mFvbAlignmentName)/sizeof (CHAR8 *); Index ++) {
    if (FindToken (InfFile, ATTRIBUTES_SECTION_STRING, mFvbAlignmentName [Index], 0, Value) == EFI_SUCCESS) {
      if (strcmp (Value, TRUE_STRING) == 0) {
        FvInfo->FvAttributes |= Index << 16;
        DebugMsg (NULL, 0, 9, "FV file alignment", "Align = %s", mFvbAlignmentName [Index]);
        break;
      }
    }
  }

  //
  // Read weak alignment flag
  //
  Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FV_WEAK_ALIGNMENT_STRING, 0, Value);
  if (Status == EFI_SUCCESS) {
    if ((strcmp (Value, TRUE_STRING) == 0) || (strcmp (Value, ONE_STRING) == 0)) {
      FvInfo->FvAttributes |= EFI_FVB2_WEAK_ALIGNMENT;
    } else if ((strcmp (Value, FALSE_STRING) != 0) && (strcmp (Value, ZERO_STRING) != 0)) {
      Error (NULL, 0, 2000, "Invalid parameter", "Weak alignment value expected one of TRUE, FALSE, 1 or 0.");
      return EFI_ABORTED;
    }
  }

  //
  // Read block maps
  //
  for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) {
    if (FvInfo->FvBlocks[Index].Length == 0) {
      //
      // Read block size
      //
      Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value);

      if (Status == EFI_SUCCESS) {
        //
        // Update the size of block
        //
        Status = AsciiStringToUint64 (Value, FALSE, &Value64);
        if (EFI_ERROR (Status)) {
          Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_BLOCK_SIZE_STRING, Value);
          return EFI_ABORTED;
        }

        FvInfo->FvBlocks[Index].Length = (UINT32) Value64;
        DebugMsg (NULL, 0, 9, "FV Block Size", "%s = %s", EFI_BLOCK_SIZE_STRING, Value);
      } else {
        //
        // If there is no blocks size, but there is the number of block, then we have a mismatched pair
        // and should return an error.
        //
        Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value);
        if (!EFI_ERROR (Status)) {
          Error (NULL, 0, 2000, "Invalid parameter", "both %s and %s must be specified.", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING);
          return EFI_ABORTED;
        } else {
          //
          // We are done
          //
          break;
        }
      }

      //
      // Read blocks number
      //
      Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value);

      if (Status == EFI_SUCCESS) {
        //
        // Update the number of blocks
        //
        Status = AsciiStringToUint64 (Value, FALSE, &Value64);
        if (EFI_ERROR (Status)) {
          Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_NUM_BLOCKS_STRING, Value);
          return EFI_ABORTED;
        }

        FvInfo->FvBlocks[Index].NumBlocks = (UINT32) Value64;
        DebugMsg (NULL, 0, 9, "FV Block Number", "%s = %s", EFI_NUM_BLOCKS_STRING, Value);
      }
    }
  }

  if (Index == 0) {
    Error (NULL, 0, 2001, "Missing required argument", "block size.");
    return EFI_ABORTED;
  }

  //
  // Read files
  //
  Number = 0;
  for (Number = 0; Number < MAX_NUMBER_OF_FILES_IN_FV; Number ++) {
    if (FvInfo->FvFiles[Number][0] == '\0') {
      break;
    }
  }

  for (Index = 0; Number + Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {
    //
    // Read the FFS file list
    //
    Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value);

    if (Status == EFI_SUCCESS) {
      //
      // Add the file
      //
      strcpy (FvInfo->FvFiles[Number + Index], Value);
      DebugMsg (NULL, 0, 9, "FV component file", "the %uth name is %s", (unsigned) Index, Value);
    } else {
      break;
    }
  }

  if ((Index + Number) == 0) {
    Warning (NULL, 0, 0, "FV components are not specified.", NULL);
  }

  return EFI_SUCCESS;
}

VOID
UpdateFfsFileState (
  IN EFI_FFS_FILE_HEADER          *FfsFile,
  IN EFI_FIRMWARE_VOLUME_HEADER   *FvHeader
  )
/*++

Routine Description:

  This function changes the FFS file attributes based on the erase polarity
  of the FV. Update the reserved bits of State to EFI_FVB2_ERASE_POLARITY.

Arguments:

  FfsFile   File header.
  FvHeader  FV header.

Returns:

  None

--*/
{
  if (FvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
    FfsFile->State = (UINT8)~(FfsFile->State);
    // FfsFile->State |= ~(UINT8) EFI_FILE_ALL_STATE_BITS;
  }
}

EFI_STATUS
ReadFfsAlignment (
  IN EFI_FFS_FILE_HEADER    *FfsFile,
  IN OUT UINT32             *Alignment
  )
/*++

Routine Description:

  This function determines the alignment of the FFS input file from the file
  attributes.

Arguments:

  FfsFile       FFS file to parse
  Alignment     The minimum required alignment offset of the FFS file

Returns:

  EFI_SUCCESS              The function completed successfully.
  EFI_INVALID_PARAMETER    One of the input parameters was invalid.
  EFI_ABORTED              An error occurred.

--*/
{
  //
  // Verify input parameters.
  //
  if (FfsFile == NULL || Alignment == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  switch ((FfsFile->Attributes >> 3) & 0x07) {

  case 0:
    //
    // 1 byte alignment
    //if bit 1 have set, 128K byte alignment
    //
    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
    //
    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
    //
    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
    //
    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
    //
    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
    //
    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
    //
    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
    //
    if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
      *Alignment = 24;
    } else {
      *Alignment = 16;
    }
    break;

  default:
    break;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
AddPadFile (
  IN OUT MEMORY_FILE  *FvImage,
  IN UINT32           DataAlignment,
  IN VOID             *FvEnd,
  IN EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHeader,
  IN UINT32           NextFfsSize
  )
/*++

Routine Description:

  This function adds a pad file to the FV image if it required to align the
  data of the next file.

Arguments:

  FvImage         The memory image of the FV to add it to.
                  The current offset must be valid.
  DataAlignment   The data alignment of the next FFS file.
  FvEnd           End of the empty data in FvImage.
  ExtHeader       PI FvExtHeader Optional

Returns:

  EFI_SUCCESS              The function completed successfully.
  EFI_INVALID_PARAMETER    One of the input parameters was invalid.
  EFI_OUT_OF_RESOURCES     Insufficient resources exist in the FV to complete
                           the pad file add.

--*/
{
  EFI_FFS_FILE_HEADER *PadFile;
  UINTN               PadFileSize;
  UINT32              NextFfsHeaderSize;
  UINT32              CurFfsHeaderSize;
  UINT32              Index;

  Index = 0;
  CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
  //
  // Verify input parameters.
  //
  if (FvImage == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Calculate the pad file size
  //

  //
  // Append extension header size
  //
  if (ExtHeader != NULL) {
    PadFileSize = ExtHeader->ExtHeaderSize;
    if (PadFileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
      CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
    }
    PadFileSize += CurFfsHeaderSize;
  } else {
    NextFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
    if (NextFfsSize >= MAX_FFS_SIZE) {
      NextFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
    }
    //
    // Check if a pad file is necessary
    //
    if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + NextFfsHeaderSize) % DataAlignment == 0) {
      return EFI_SUCCESS;
    }
    PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER) + NextFfsHeaderSize;
    //
    // Add whatever it takes to get to the next aligned address
    //
    while ((PadFileSize % DataAlignment) != 0) {
      PadFileSize++;
    }
    //
    // Subtract the next file header size
    //
    PadFileSize -= NextFfsHeaderSize;
    //
    // Subtract the starting offset to get size
    //
    PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage;
  }

  //
  // Verify that we have enough space for the file header
  //
  if (((UINTN) FvImage->CurrentFilePointer + PadFileSize) > (UINTN) FvEnd) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Write pad file header
  //
  PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;

  //
  // Write PadFile FFS header with PadType, don't need to set PAD file guid in its header.
  //
  PadFile->Type       = EFI_FV_FILETYPE_FFS_PAD;
  PadFile->Attributes = 0;

  //
  // Write pad file size (calculated size minus next file header size)
  //
  if (PadFileSize >= MAX_FFS_SIZE) {
    memset(PadFile->Size, 0, sizeof(UINT8) * 3);
    ((EFI_FFS_FILE_HEADER2 *)PadFile)->ExtendedSize = PadFileSize;
    PadFile->Attributes |= FFS_ATTRIB_LARGE_FILE;
  } else {
    PadFile->Size[0]  = (UINT8) (PadFileSize & 0xFF);
    PadFile->Size[1]  = (UINT8) ((PadFileSize >> 8) & 0xFF);
    PadFile->Size[2]  = (UINT8) ((PadFileSize >> 16) & 0xFF);
  }

  //
  // Fill in checksums and state, they must be 0 for checksumming.
  //
  PadFile->IntegrityCheck.Checksum.Header = 0;
  PadFile->IntegrityCheck.Checksum.File   = 0;
  PadFile->State                          = 0;
  PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, CurFfsHeaderSize);
  PadFile->IntegrityCheck.Checksum.File   = FFS_FIXED_CHECKSUM;

  PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
  UpdateFfsFileState (
    (EFI_FFS_FILE_HEADER *) PadFile,
    (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage
    );

  //
  // Update the current FV pointer
  //
  FvImage->CurrentFilePointer += PadFileSize;

  if (ExtHeader != NULL) {
    //
    // 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);
    //
    // Make next file start at QWord Boundary
    //
    while (((UINTN) FvImage->CurrentFilePointer & (EFI_FFS_FILE_HEADER_ALIGNMENT - 1)) != 0) {
      FvImage->CurrentFilePointer++;
    }
  }

  return EFI_SUCCESS;
}

BOOLEAN
IsVtfFile (
  IN EFI_FFS_FILE_HEADER    *FileBuffer
  )
/*++

Routine Description:

  This function checks the header to validate if it is a VTF file

Arguments:

  FileBuffer     Buffer in which content of a file has been read.

Returns:

  TRUE    If this is a VTF file
  FALSE   If this is not a VTF file

--*/
{
  if (!memcmp (&FileBuffer->Name, &mEfiFirmwareVolumeTopFileGuid, sizeof (EFI_GUID))) {
    return TRUE;
  } else {
    return FALSE;
  }
}

EFI_STATUS
WriteMapFile (
  IN OUT FILE                  *FvMapFile,
  IN     CHAR8                 *FileName,
  IN     EFI_FFS_FILE_HEADER   *FfsFile,
  IN     EFI_PHYSICAL_ADDRESS  ImageBaseAddress,
  IN     PE_COFF_LOADER_IMAGE_CONTEXT *pImageContext
  )
/*++

Routine Description:

  This function gets the basic debug information (entrypoint, baseaddress, .text, .data section base address)
  from PE/COFF image and abstracts Pe Map file information and add them into FvMap file for Debug.

Arguments:

  FvMapFile             A pointer to FvMap File
  FileName              Ffs File PathName
  FfsFile               A pointer to Ffs file image.
  ImageBaseAddress      PeImage Base Address.
  pImageContext         Image Context Information.

Returns:

  EFI_SUCCESS           Added required map information.

--*/
{
  CHAR8                               PeMapFileName [MAX_LONG_FILE_PATH];
  CHAR8                               *Cptr, *Cptr2;
  CHAR8                               FileGuidName [MAX_LINE_LEN];
  FILE                                *PeMapFile;
  CHAR8                               Line [MAX_LINE_LEN];
  CHAR8                               KeyWord [MAX_LINE_LEN];
  CHAR8                               KeyWord2 [MAX_LINE_LEN];
  CHAR8                               FunctionName [MAX_LINE_LEN];
  EFI_PHYSICAL_ADDRESS                FunctionAddress;
  UINT32                              FunctionType;
  CHAR8                               FunctionTypeName [MAX_LINE_LEN];
  UINT32                              Index;
  UINT32                              AddressOfEntryPoint;
  UINT32                              Offset;
  EFI_IMAGE_OPTIONAL_HEADER_UNION     *ImgHdr;
  EFI_TE_IMAGE_HEADER                 *TEImageHeader;
  EFI_IMAGE_SECTION_HEADER            *SectionHeader;
  long long                           TempLongAddress;
  UINT32                              TextVirtualAddress;
  UINT32                              DataVirtualAddress;
  EFI_PHYSICAL_ADDRESS                LinkTimeBaseAddress;
  BOOLEAN                             IsUseClang;

  //
  // Init local variable
  //
  FunctionType = 0;
  //
  // Print FileGuid to string buffer.
  //
  PrintGuidToBuffer (&FfsFile->Name, (UINT8 *)FileGuidName, MAX_LINE_LEN, TRUE);

  //
  // Construct Map file Name
  //
  if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
    return EFI_ABORTED;
  }
  strncpy (PeMapFileName, FileName, MAX_LONG_FILE_PATH - 1);
  PeMapFileName[MAX_LONG_FILE_PATH - 1] = 0;

  //
  // Change '\\' to '/', unified path format.
  //
  Cptr = PeMapFileName;
  while (*Cptr != '\0') {
    if (*Cptr == '\\') {
      *Cptr = FILE_SEP_CHAR;
    }
    Cptr ++;
  }

  //
  // Get Map file
  //
  Cptr = PeMapFileName + strlen (PeMapFileName);
  while ((*Cptr != '.') && (Cptr >= PeMapFileName)) {
    Cptr --;
  }
  if (Cptr < PeMapFileName) {
    return EFI_NOT_FOUND;
  } else {
    *(Cptr + 1) = 'm';
    *(Cptr + 2) = 'a';
    *(Cptr + 3) = 'p';
    *(Cptr + 4) = '\0';
  }

  //
  // Get module Name
  //
  Cptr2 = Cptr;
  while ((*Cptr != FILE_SEP_CHAR) && (Cptr >= PeMapFileName)) {
    Cptr --;
  }
  *Cptr2 = '\0';
  if (strlen (Cptr + 1) >= MAX_LINE_LEN) {
    return EFI_ABORTED;
  }
  strncpy (KeyWord, Cptr + 1, MAX_LINE_LEN - 1);
  KeyWord[MAX_LINE_LEN - 1] = 0;
  *Cptr2 = '.';

  //
  // AddressOfEntryPoint and Offset in Image
  //
  if (!pImageContext->IsTeImage) {
    ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset);
    AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
    Offset = 0;
    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
                       (UINT8 *) ImgHdr +
                       sizeof (UINT32) +
                       sizeof (EFI_IMAGE_FILE_HEADER) +
                       ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
                       );
    Index = ImgHdr->Pe32.FileHeader.NumberOfSections;
  } else {
    TEImageHeader = (EFI_TE_IMAGE_HEADER *) pImageContext->Handle;
    AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint;
    Offset = TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);
    Index = TEImageHeader->NumberOfSections;
  }

  //
  // module information output
  //
  if (ImageBaseAddress == 0) {
    fprintf (FvMapFile, "%s (dummy) (", KeyWord);
    fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress);
  } else {
    fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord);
    fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset));
  }

  fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));
  if (!pImageContext->IsTeImage) {
    fprintf (FvMapFile, "Type=PE");
  } else {
    fprintf (FvMapFile, "Type=TE");
  }
  fprintf (FvMapFile, ")\n");

  fprintf (FvMapFile, "(GUID=%s", FileGuidName);
  TextVirtualAddress = 0;
  DataVirtualAddress = 0;
  for (; Index > 0; Index --, SectionHeader ++) {
    if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) {
      TextVirtualAddress = SectionHeader->VirtualAddress;
    } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".data") == 0) {
      DataVirtualAddress = SectionHeader->VirtualAddress;
    } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".sdata") == 0) {
      DataVirtualAddress = SectionHeader->VirtualAddress;
    }
  }
  fprintf (FvMapFile, " .textbaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + TextVirtualAddress));
  fprintf (FvMapFile, " .databaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + DataVirtualAddress));
  fprintf (FvMapFile, ")\n\n");

  //
  // Open PeMapFile
  //
  PeMapFile = fopen (LongFilePath (PeMapFileName), "r");
  if (PeMapFile == NULL) {
    // fprintf (stdout, "can't open %s file to reading\n", PeMapFileName);
    return EFI_ABORTED;
  }
  VerboseMsg ("The map file is %s", PeMapFileName);

  //
  // Output Functions information into Fv Map file
  //
  LinkTimeBaseAddress = 0;
  IsUseClang = FALSE;
  while (fgets (Line, MAX_LINE_LEN, PeMapFile) != NULL) {
    //
    // Skip blank line
    //
    if (Line[0] == 0x0a) {
      FunctionType = 0;
      continue;
    }
    //
    // By Address and Static keyword
    //
    if (FunctionType == 0) {
      sscanf (Line, "%s", KeyWord);
      if (stricmp (KeyWord, "Address") == 0) {
        sscanf (Line, "%s %s", KeyWord, KeyWord2);
        if (stricmp (KeyWord2, "Size") == 0) {
          IsUseClang = TRUE;
          FunctionType = 1;
          continue;
        }
        //
        // function list
        //
        FunctionType = 1;
        fgets (Line, MAX_LINE_LEN, PeMapFile);
      } else if (stricmp (KeyWord, "Static") == 0) {
        //
        // static function list
        //
        FunctionType = 2;
        fgets (Line, MAX_LINE_LEN, PeMapFile);
      } else if (stricmp (KeyWord, "Preferred") ==0) {
        sscanf (Line + strlen (" Preferred load address is"), "%llx", &TempLongAddress);
        LinkTimeBaseAddress = (UINT64) TempLongAddress;
      }
      continue;
    }
    //
    // Printf Function Information
    //
    if (FunctionType == 1) {
      if (IsUseClang) {
        sscanf (Line, "%llx %s %s %s", &TempLongAddress, KeyWord, KeyWord2, FunctionTypeName);
        FunctionAddress = (UINT64) TempLongAddress;
        if (FunctionTypeName [0] != '/' && FunctionTypeName [0] != '.' && FunctionTypeName [1] != ':') {
          fprintf (FvMapFile, "  0x%010llx    ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
          fprintf (FvMapFile, "%s\n", FunctionTypeName);
        }
      } else {
        sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);
        FunctionAddress = (UINT64) TempLongAddress;
        if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {
          fprintf (FvMapFile, "  0x%010llx    ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
          fprintf (FvMapFile, "%s\n", FunctionName);
        }
      }
    } else if (FunctionType == 2) {
      sscanf (Line, "%s %s %llx %s", KeyWord, FunctionName, &TempLongAddress, FunctionTypeName);
      FunctionAddress = (UINT64) TempLongAddress;
      if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {
        fprintf (FvMapFile, "  0x%010llx    ", (unsigned long long) (ImageBaseAddress + FunctionAddress - LinkTimeBaseAddress));
        fprintf (FvMapFile, "%s\n", FunctionName);
      }
    }
  }
  //
  // Close PeMap file
  //
  fprintf (FvMapFile, "\n\n");
  fclose (PeMapFile);

  return EFI_SUCCESS;
}

STATIC
BOOLEAN
AdjustInternalFfsPadding (
  IN OUT  EFI_FFS_FILE_HEADER   *FfsFile,
  IN OUT  MEMORY_FILE           *FvImage,
  IN      UINTN                 Alignment,
  IN OUT  UINTN                 *FileSize
  )
/*++

Routine Description:

  This function looks for a dedicated alignment padding section in the FFS, and
  shrinks it to the size required to line up subsequent sections correctly.

Arguments:

  FfsFile               A pointer to Ffs file image.
  FvImage               The memory image of the FV to adjust it to.
  Alignment             Current file alignment
  FileSize              Reference to a variable holding the size of the FFS file

Returns:

  TRUE                  Padding section was found and updated successfully
  FALSE                 Otherwise

--*/
{
  EFI_FILE_SECTION_POINTER  PadSection;
  UINT8                     *Remainder;
  EFI_STATUS                Status;
  UINT32                    FfsHeaderLength;
  UINT32                    FfsFileLength;
  UINT32                    PadSize;
  UINTN                     Misalignment;
  EFI_FFS_INTEGRITY_CHECK   *IntegrityCheck;

  //
  // Figure out the misalignment: all FFS sections are aligned relative to the
  // start of the FFS payload, so use that as the base of the misalignment
  // computation.
  //
  FfsHeaderLength = GetFfsHeaderLength(FfsFile);
  Misalignment = (UINTN) FvImage->CurrentFilePointer -
                 (UINTN) FvImage->FileImage + FfsHeaderLength;
  Misalignment &= Alignment - 1;
  if (Misalignment == 0) {
    // Nothing to do, return success
    return TRUE;
  }

  //
  // We only apply this optimization to FFS files with the FIXED attribute set,
  // since the FFS will not be loadable at arbitrary offsets anymore after
  // we adjust the size of the padding section.
  //
  if ((FfsFile->Attributes & FFS_ATTRIB_FIXED) == 0) {
    return FALSE;
  }

  //
  // Look for a dedicated padding section that we can adjust to compensate
  // for the misalignment. If such a padding section exists, it precedes all
  // sections with alignment requirements, and so the adjustment will correct
  // all of them.
  //
  Status = GetSectionByType (FfsFile, EFI_SECTION_FREEFORM_SUBTYPE_GUID, 1,
             &PadSection);
  if (EFI_ERROR (Status) ||
      CompareGuid (&PadSection.FreeformSubtypeSection->SubTypeGuid,
        &mEfiFfsSectionAlignmentPaddingGuid) != 0) {
    return FALSE;
  }

  //
  // Find out if the size of the padding section is sufficient to compensate
  // for the misalignment.
  //
  PadSize = GetSectionFileLength (PadSection.CommonHeader);
  if (Misalignment > PadSize - sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION)) {
    return FALSE;
  }

  //
  // Move the remainder of the FFS file towards the front, and adjust the
  // file size output parameter.
  //
  Remainder = (UINT8 *) PadSection.CommonHeader + PadSize;
  memmove (Remainder - Misalignment, Remainder,
           *FileSize - (UINTN) (Remainder - (UINTN) FfsFile));
  *FileSize -= Misalignment;

  //
  // Update the padding section's length with the new values. Note that the
  // padding is always < 64 KB, so we can ignore EFI_COMMON_SECTION_HEADER2
  // ExtendedSize.
  //
  PadSize -= Misalignment;
  PadSection.CommonHeader->Size[0] = (UINT8) (PadSize & 0xff);
  PadSection.CommonHeader->Size[1] = (UINT8) ((PadSize & 0xff00) >> 8);
  PadSection.CommonHeader->Size[2] = (UINT8) ((PadSize & 0xff0000) >> 16);

  //
  // Update the FFS header with the new overall length
  //
  FfsFileLength = GetFfsFileLength (FfsFile) - Misalignment;
  if (FfsHeaderLength > sizeof(EFI_FFS_FILE_HEADER)) {
    ((EFI_FFS_FILE_HEADER2 *)FfsFile)->ExtendedSize = FfsFileLength;
  } else {
    FfsFile->Size[0] = (UINT8) (FfsFileLength & 0x000000FF);
    FfsFile->Size[1] = (UINT8) ((FfsFileLength & 0x0000FF00) >> 8);
    FfsFile->Size[2] = (UINT8) ((FfsFileLength & 0x00FF0000) >> 16);
  }

  //
  // Clear the alignment bits: these have become meaningless now that we have
  // adjusted the padding section.
  //
  FfsFile->Attributes &= ~(FFS_ATTRIB_DATA_ALIGNMENT | FFS_ATTRIB_DATA_ALIGNMENT2);

  //
  // Recalculate the FFS header checksum. Instead of setting Header and State
  // both to zero, set Header to (UINT8)(-State) so State preserves its original
  // value
  //
  IntegrityCheck = &FfsFile->IntegrityCheck;
  IntegrityCheck->Checksum.Header = (UINT8) (0x100 - FfsFile->State);
  IntegrityCheck->Checksum.File = 0;

  IntegrityCheck->Checksum.Header = CalculateChecksum8 (
                                      (UINT8 *) FfsFile, FfsHeaderLength);

  if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
    //
    // Ffs header checksum = zero, so only need to calculate ffs body.
    //
    IntegrityCheck->Checksum.File = CalculateChecksum8 (
                                      (UINT8 *) FfsFile + FfsHeaderLength,
                                      FfsFileLength - FfsHeaderLength);
  } else {
    IntegrityCheck->Checksum.File = FFS_FIXED_CHECKSUM;
  }

  return TRUE;
}

EFI_STATUS
AddFile (
  IN OUT MEMORY_FILE          *FvImage,
  IN FV_INFO                  *FvInfo,
  IN UINTN                    Index,
  IN OUT EFI_FFS_FILE_HEADER  **VtfFileImage,
  IN FILE                     *FvMapFile,
  IN FILE                     *FvReportFile
  )
/*++

Routine Description:

  This function adds a file to the FV image.  The file will pad to the
  appropriate alignment if required.

Arguments:

  FvImage       The memory image of the FV to add it to.  The current offset
                must be valid.
  FvInfo        Pointer to information about the FV.
  Index         The file in the FvInfo file list to add.
  VtfFileImage  A pointer to the VTF file within the FvImage.  If this is equal
                to the end of the FvImage then no VTF previously found.
  FvMapFile     Pointer to FvMap File
  FvReportFile  Pointer to FvReport File

Returns:

  EFI_SUCCESS              The function completed successfully.
  EFI_INVALID_PARAMETER    One of the input parameters was invalid.
  EFI_ABORTED              An error occurred.
  EFI_OUT_OF_RESOURCES     Insufficient resources exist to complete the add.

--*/
{
  FILE                  *NewFile;
  UINTN                 FileSize;
  UINT8                 *FileBuffer;
  UINTN                 NumBytesRead;
  UINT32                CurrentFileAlignment;
  EFI_STATUS            Status;
  UINTN                 Index1;
  UINT8                 FileGuidString[PRINTED_GUID_BUFFER_SIZE];

  Index1 = 0;
  //
  // Verify input parameters.
  //
  if (FvImage == NULL || FvInfo == NULL || FvInfo->FvFiles[Index][0] == 0 || VtfFileImage == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Read the file to add
  //
  NewFile = fopen (LongFilePath (FvInfo->FvFiles[Index]), "rb");

  if (NewFile == NULL) {
    Error (NULL, 0, 0001, "Error opening file", FvInfo->FvFiles[Index]);
    return EFI_ABORTED;
  }

  //
  // Get the file size
  //
  FileSize = _filelength (fileno (NewFile));

  //
  // Read the file into a buffer
  //
  FileBuffer = malloc (FileSize);
  if (FileBuffer == NULL) {
    fclose (NewFile);
    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
    return EFI_OUT_OF_RESOURCES;
  }

  NumBytesRead = fread (FileBuffer, sizeof (UINT8), FileSize, NewFile);

  //
  // Done with the file, from this point on we will just use the buffer read.
  //
  fclose (NewFile);

  //
  // Verify read successful
  //
  if (NumBytesRead != sizeof (UINT8) * FileSize) {
    free  (FileBuffer);
    Error (NULL, 0, 0004, "Error reading file", FvInfo->FvFiles[Index]);
    return EFI_ABORTED;
  }

  //
  // For None PI Ffs file, directly add them into FvImage.
  //
  if (!FvInfo->IsPiFvImage) {
    memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);
    if (FvInfo->SizeofFvFiles[Index] > FileSize) {
      FvImage->CurrentFilePointer += FvInfo->SizeofFvFiles[Index];
    } else {
      FvImage->CurrentFilePointer += FileSize;
    }
    goto Done;
  }

  //
  // Verify Ffs file
  //
  Status = VerifyFfsFile ((EFI_FFS_FILE_HEADER *)FileBuffer);
  if (EFI_ERROR (Status)) {
    free (FileBuffer);
    Error (NULL, 0, 3000, "Invalid", "%s is not a valid FFS file.", FvInfo->FvFiles[Index]);
    return EFI_INVALID_PARAMETER;
  }

  //
  // Verify space exists to add the file
  //
  if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) {
    free (FileBuffer);
    Error (NULL, 0, 4002, "Resource", "FV space is full, not enough room to add file %s.", FvInfo->FvFiles[Index]);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Verify the input file is the duplicated file in this Fv image
  //
  for (Index1 = 0; Index1 < Index; Index1 ++) {
    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;
    }
  }
  CopyMem (&mFileGuidArray [Index], FileBuffer, sizeof (EFI_GUID));

  //
  // Update the file state based on polarity of the FV.
  //
  UpdateFfsFileState (
    (EFI_FFS_FILE_HEADER *) FileBuffer,
    (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage
    );

  //
  // Check if alignment is required
  //
  ReadFfsAlignment ((EFI_FFS_FILE_HEADER *) FileBuffer, &CurrentFileAlignment);

  //
  // Find the largest alignment of all the FFS files in the FV
  //
  if (CurrentFileAlignment > MaxFfsAlignment) {
    MaxFfsAlignment = CurrentFileAlignment;
  }
  //
  // If we have a VTF file, add it at the top.
  //
  if (IsVtfFile ((EFI_FFS_FILE_HEADER *) FileBuffer)) {
    if ((UINTN) *VtfFileImage == (UINTN) FvImage->Eof) {
      //
      // No previous VTF, add this one.
      //
      *VtfFileImage = (EFI_FFS_FILE_HEADER *) (UINTN) ((UINTN) FvImage->FileImage + FvInfo->Size - FileSize);
      //
      // Sanity check. The file MUST align appropriately
      //
      if (((UINTN) *VtfFileImage + GetFfsHeaderLength((EFI_FFS_FILE_HEADER *)FileBuffer) - (UINTN) FvImage->FileImage) % (1 << CurrentFileAlignment)) {
        Error (NULL, 0, 3000, "Invalid", "VTF file cannot be aligned on a %u-byte boundary.", (unsigned) (1 << CurrentFileAlignment));
        free (FileBuffer);
        return EFI_ABORTED;
      }
      //
      // Rebase the PE or TE image in FileBuffer of FFS file for XIP
      // Rebase for the debug genfvmap tool
      //
      Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile);
      if (EFI_ERROR (Status)) {
        Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
        return Status;
      }
      //
      // copy VTF File
      //
      memcpy (*VtfFileImage, FileBuffer, FileSize);

      PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE);
      fprintf (FvReportFile, "0x%08X %s\n", (unsigned)(UINTN) (((UINT8 *)*VtfFileImage) - (UINTN)FvImage->FileImage), FileGuidString);

      free (FileBuffer);
      DebugMsg (NULL, 0, 9, "Add VTF FFS file in FV image", NULL);
      return EFI_SUCCESS;
    } else {
      //
      // Already found a VTF file.
      //
      Error (NULL, 0, 3000, "Invalid", "multiple VTF files are not permitted within a single FV.");
      free (FileBuffer);
      return EFI_ABORTED;
    }
  }

  //
  // Add pad file if necessary
  //
  if (!AdjustInternalFfsPadding ((EFI_FFS_FILE_HEADER *) FileBuffer, FvImage,
         1 << CurrentFileAlignment, &FileSize)) {
    Status = AddPadFile (FvImage, 1 << CurrentFileAlignment, *VtfFileImage, NULL, FileSize);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 4002, "Resource", "FV space is full, could not add pad file for data alignment property.");
      free (FileBuffer);
      return EFI_ABORTED;
    }
  }
  //
  // Add file
  //
  if ((UINTN) (FvImage->CurrentFilePointer + FileSize) <= (UINTN) (*VtfFileImage)) {
    //
    // Rebase the PE or TE image in FileBuffer of FFS file for XIP.
    // Rebase Bs and Rt drivers for the debug genfvmap tool.
    //
    Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile);
  if (EFI_ERROR (Status)) {
    Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
    return Status;
  }
    //
    // Copy the file
    //
    memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize);
    PrintGuidToBuffer ((EFI_GUID *) FileBuffer, FileGuidString, sizeof (FileGuidString), TRUE);
    fprintf (FvReportFile, "0x%08X %s\n", (unsigned) (FvImage->CurrentFilePointer - FvImage->FileImage), FileGuidString);
    FvImage->CurrentFilePointer += FileSize;
  } else {
    Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add file %s.", FvInfo->FvFiles[Index]);
    free (FileBuffer);
    return EFI_ABORTED;
  }
  //
  // Make next file start at QWord Boundary
  //
  while (((UINTN) FvImage->CurrentFilePointer & (EFI_FFS_FILE_HEADER_ALIGNMENT - 1)) != 0) {
    FvImage->CurrentFilePointer++;
  }

Done:
  //
  // Free allocated memory.
  //
  free (FileBuffer);

  return EFI_SUCCESS;
}

EFI_STATUS
PadFvImage (
  IN MEMORY_FILE          *FvImage,
  IN EFI_FFS_FILE_HEADER  *VtfFileImage
  )
/*++

Routine Description:

  This function places a pad file between the last file in the FV and the VTF
  file if the VTF file exists.

Arguments:

  FvImage       Memory file for the FV memory image
  VtfFileImage  The address of the VTF file.  If this is the end of the FV
                image, no VTF exists and no pad file is needed.

Returns:

  EFI_SUCCESS             Completed successfully.
  EFI_INVALID_PARAMETER   One of the input parameters was NULL.

--*/
{
  EFI_FFS_FILE_HEADER *PadFile;
  UINTN               FileSize;
  UINT32              FfsHeaderSize;

  //
  // If there is no VTF or the VTF naturally follows the previous file without a
  // pad file, then there's nothing to do
  //
  if ((UINTN) VtfFileImage == (UINTN) FvImage->Eof || \
      ((UINTN) VtfFileImage == (UINTN) FvImage->CurrentFilePointer)) {
    return EFI_SUCCESS;
  }

  if ((UINTN) VtfFileImage < (UINTN) FvImage->CurrentFilePointer) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Pad file starts at beginning of free space
  //
  PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer;

  //
  // write PadFile FFS header with PadType, don't need to set PAD file guid in its header.
  //
  PadFile->Type       = EFI_FV_FILETYPE_FFS_PAD;
  PadFile->Attributes = 0;

  //
  // FileSize includes the EFI_FFS_FILE_HEADER
  //
  FileSize          = (UINTN) VtfFileImage - (UINTN) FvImage->CurrentFilePointer;
  if (FileSize >= MAX_FFS_SIZE) {
    PadFile->Attributes |= FFS_ATTRIB_LARGE_FILE;
    memset(PadFile->Size, 0, sizeof(UINT8) * 3);
    ((EFI_FFS_FILE_HEADER2 *)PadFile)->ExtendedSize = FileSize;
    FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER2);
    mIsLargeFfs = TRUE;
  } else {
    PadFile->Size[0]  = (UINT8) (FileSize & 0x000000FF);
    PadFile->Size[1]  = (UINT8) ((FileSize & 0x0000FF00) >> 8);
    PadFile->Size[2]  = (UINT8) ((FileSize & 0x00FF0000) >> 16);
    FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER);
  }

  //
  // Fill in checksums and state, must be zero during checksum calculation.
  //
  PadFile->IntegrityCheck.Checksum.Header = 0;
  PadFile->IntegrityCheck.Checksum.File   = 0;
  PadFile->State                          = 0;
  PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, FfsHeaderSize);
  PadFile->IntegrityCheck.Checksum.File   = FFS_FIXED_CHECKSUM;

  PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;

  UpdateFfsFileState (
    (EFI_FFS_FILE_HEADER *) PadFile,
    (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage
    );
  //
  // Update the current FV pointer
  //
  FvImage->CurrentFilePointer = FvImage->Eof;

  return EFI_SUCCESS;
}

EFI_STATUS
UpdateResetVector (
  IN MEMORY_FILE            *FvImage,
  IN FV_INFO                *FvInfo,
  IN EFI_FFS_FILE_HEADER    *VtfFile
  )
/*++

Routine Description:

  This parses the FV looking for the PEI core and then plugs the address into
  the SALE_ENTRY point of the BSF/VTF for IPF and does BUGBUG TBD action to
  complete an IA32 Bootstrap FV.

Arguments:

  FvImage       Memory file for the FV memory image
  FvInfo        Information read from INF file.
  VtfFile       Pointer to the VTF file in the FV image.

Returns:

  EFI_SUCCESS             Function Completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.
  EFI_NOT_FOUND           PEI Core file not found.

--*/
{
  EFI_FFS_FILE_HEADER       *PeiCoreFile;
  EFI_FFS_FILE_HEADER       *SecCoreFile;
  EFI_STATUS                Status;
  EFI_FILE_SECTION_POINTER  Pe32Section;
  UINT32                    EntryPoint;
  UINT32                    BaseOfCode;
  UINT16                    MachineType;
  EFI_PHYSICAL_ADDRESS      PeiCorePhysicalAddress;
  EFI_PHYSICAL_ADDRESS      SecCorePhysicalAddress;
  INT32                     Ia32SecEntryOffset;
  UINT32                    *Ia32ResetAddressPtr;
  EFI_FFS_FILE_STATE        SavedState;
  BOOLEAN                   Vtf0Detected;
  UINT32                    FfsHeaderSize;
  UINT32                    SecHeaderSize;

  //
  // Verify input parameters
  //
  if (FvImage == NULL || FvInfo == NULL || VtfFile == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Initialize FV library
  //
  InitializeFvLib (FvImage->FileImage, FvInfo->Size);

  //
  // Verify VTF file
  //
  Status = VerifyFfsFile (VtfFile);
  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }

  if (
      (((UINTN)FvImage->Eof - (UINTN)FvImage->FileImage) >=
        IA32_X64_VTF_SIGNATURE_OFFSET) &&
      (*(UINT32 *)(VOID*)((UINTN) FvImage->Eof -
                                  IA32_X64_VTF_SIGNATURE_OFFSET) ==
        IA32_X64_VTF0_SIGNATURE)
     ) {
    Vtf0Detected = TRUE;
  } else {
    Vtf0Detected = FALSE;
  }

  //
  // Find the Sec Core
  //
  Status = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &SecCoreFile);
  if (EFI_ERROR (Status) || SecCoreFile == NULL) {
    if (Vtf0Detected) {
      //
      // If the SEC core file is not found, but the VTF-0 signature
      // is found, we'll treat it as a VTF-0 'Volume Top File'.
      // This means no modifications are required to the VTF.
      //
      return EFI_SUCCESS;
    }

    Error (NULL, 0, 3000, "Invalid", "could not find the SEC core file in the FV.");
    return EFI_ABORTED;
  }
  //
  // Sec Core found, now find PE32 section
  //
  Status = GetSectionByType (SecCoreFile, EFI_SECTION_PE32, 1, &Pe32Section);
  if (Status == EFI_NOT_FOUND) {
    Status = GetSectionByType (SecCoreFile, EFI_SECTION_TE, 1, &Pe32Section);
  }

  if (EFI_ERROR (Status)) {
    Error (NULL, 0, 3000, "Invalid", "could not find a PE32 section in the SEC core file.");
    return EFI_ABORTED;
  }

  SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
  Status = GetPe32Info (
            (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
            &EntryPoint,
            &BaseOfCode,
            &MachineType
            );

  if (EFI_ERROR (Status)) {
    Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the SEC core.");
    return EFI_ABORTED;
  }

  if (
       Vtf0Detected &&
       (MachineType == IMAGE_FILE_MACHINE_I386 ||
        MachineType == IMAGE_FILE_MACHINE_X64)
     ) {
    //
    // If the SEC core code is IA32 or X64 and the VTF-0 signature
    // is found, we'll treat it as a VTF-0 'Volume Top File'.
    // This means no modifications are required to the VTF.
    //
    return EFI_SUCCESS;
  }

  //
  // Physical address is FV base + offset of PE32 + offset of the entry point
  //
  SecCorePhysicalAddress = FvInfo->BaseAddress;
  SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
  SecCorePhysicalAddress += EntryPoint;
  DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%llX", (unsigned long long) SecCorePhysicalAddress);

  //
  // Find the PEI Core
  //
  PeiCorePhysicalAddress = 0;
  Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile);
  if (!EFI_ERROR (Status) && (PeiCoreFile != NULL)) {
    //
    // PEI Core found, now find PE32 or TE section
    //
    Status = GetSectionByType (PeiCoreFile, EFI_SECTION_PE32, 1, &Pe32Section);
    if (Status == EFI_NOT_FOUND) {
      Status = GetSectionByType (PeiCoreFile, EFI_SECTION_TE, 1, &Pe32Section);
    }

    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "could not find either a PE32 or a TE section in PEI core file.");
      return EFI_ABORTED;
    }

    SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
    Status = GetPe32Info (
              (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
              &EntryPoint,
              &BaseOfCode,
              &MachineType
              );

    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the PEI core.");
      return EFI_ABORTED;
    }
    //
    // Physical address is FV base + offset of PE32 + offset of the entry point
    //
    PeiCorePhysicalAddress = FvInfo->BaseAddress;
    PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
    PeiCorePhysicalAddress += EntryPoint;
    DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);
  }

if (MachineType == IMAGE_FILE_MACHINE_I386 || MachineType == IMAGE_FILE_MACHINE_X64) {
    if (PeiCorePhysicalAddress != 0) {
      //
      // Get the location to update
      //
      Ia32ResetAddressPtr  = (UINT32 *) ((UINTN) FvImage->Eof - IA32_PEI_CORE_ENTRY_OFFSET);

      //
      // Write lower 32 bits of physical address for Pei Core entry
      //
      *Ia32ResetAddressPtr = (UINT32) PeiCorePhysicalAddress;
    }
    //
    // Write SecCore Entry point relative address into the jmp instruction in reset vector.
    //
    Ia32ResetAddressPtr  = (UINT32 *) ((UINTN) FvImage->Eof - IA32_SEC_CORE_ENTRY_OFFSET);

    Ia32SecEntryOffset   = (INT32) (SecCorePhysicalAddress - (FV_IMAGES_TOP_ADDRESS - IA32_SEC_CORE_ENTRY_OFFSET + 2));
    if (Ia32SecEntryOffset <= -65536) {
      Error (NULL, 0, 3000, "Invalid", "The SEC EXE file size is too large, it must be less than 64K.");
      return STATUS_ERROR;
    }

    *(UINT16 *) Ia32ResetAddressPtr = (UINT16) Ia32SecEntryOffset;

    //
    // Update the BFV base address
    //
    Ia32ResetAddressPtr   = (UINT32 *) ((UINTN) FvImage->Eof - 4);
    *Ia32ResetAddressPtr  = (UINT32) (FvInfo->BaseAddress);
    DebugMsg (NULL, 0, 9, "update BFV base address in the top FV image", "BFV base address = 0x%llX.", (unsigned long long) FvInfo->BaseAddress);
  } else if (MachineType == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) {
    //
    // Since the ARM reset vector is in the FV Header you really don't need a
    // Volume Top File, but if you have one for some reason don't crash...
    //
  } else if (MachineType == IMAGE_FILE_MACHINE_ARM64) {
    //
    // Since the AArch64 reset vector is in the FV Header you really don't need a
    // Volume Top File, but if you have one for some reason don't crash...
    //
  } else {
    Error (NULL, 0, 3000, "Invalid", "machine type=0x%X in PEI core.", MachineType);
    return EFI_ABORTED;
  }

  //
  // Now update file checksum
  //
  SavedState  = VtfFile->State;
  VtfFile->IntegrityCheck.Checksum.File = 0;
  VtfFile->State                        = 0;
  if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) {
    FfsHeaderSize = GetFfsHeaderLength(VtfFile);
    VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
                                              (UINT8 *) ((UINT8 *)VtfFile + FfsHeaderSize),
                                              GetFfsFileLength (VtfFile) - FfsHeaderSize
                                              );
  } else {
    VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
  }

  VtfFile->State = SavedState;

  return EFI_SUCCESS;
}

EFI_STATUS
FindCorePeSection(
  IN VOID                       *FvImageBuffer,
  IN UINT64                     FvSize,
  IN EFI_FV_FILETYPE            FileType,
  OUT EFI_FILE_SECTION_POINTER  *Pe32Section
  )
/*++

Routine Description:

  Recursively searches the FV for the FFS file of specified type (typically
  SEC or PEI core) and extracts the PE32 section for further processing.

Arguments:

  FvImageBuffer   Buffer containing FV data
  FvSize          Size of the FV
  FileType        Type of FFS file to search for
  Pe32Section     PE32 section pointer when FFS file is found.

Returns:

  EFI_SUCCESS             Function Completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.
  EFI_NOT_FOUND           Core file not found.

--*/
{
  EFI_STATUS                  Status;
  EFI_FIRMWARE_VOLUME_HEADER  *OrigFvHeader;
  UINT32                      OrigFvLength;
  EFI_FFS_FILE_HEADER         *CoreFfsFile;
  UINTN                       FvImageFileCount;
  EFI_FFS_FILE_HEADER         *FvImageFile;
  UINTN                       EncapFvSectionCount;
  EFI_FILE_SECTION_POINTER    EncapFvSection;
  EFI_FIRMWARE_VOLUME_HEADER  *EncapsulatedFvHeader;

  if (Pe32Section == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Initialize FV library, saving previous values
  //
  OrigFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NULL;
  GetFvHeader (&OrigFvHeader, &OrigFvLength);
  InitializeFvLib(FvImageBuffer, (UINT32)FvSize);

  //
  // First see if we can obtain the file directly in outer FV
  //
  Status = GetFileByType(FileType, 1, &CoreFfsFile);
  if (!EFI_ERROR(Status) && (CoreFfsFile != NULL) ) {

    //
    // Core found, now find PE32 or TE section
    //
    Status = GetSectionByType(CoreFfsFile, EFI_SECTION_PE32, 1, Pe32Section);
    if (EFI_ERROR(Status)) {
      Status = GetSectionByType(CoreFfsFile, EFI_SECTION_TE, 1, Pe32Section);
    }

    if (EFI_ERROR(Status)) {
      Error(NULL, 0, 3000, "Invalid", "could not find a PE32 section in the core file.");
      return EFI_ABORTED;
    }

    //
    // Core PE/TE section, found, return
    //
    Status = EFI_SUCCESS;
    goto EarlyExit;
  }

  //
  // File was not found, look for FV Image file
  //

  // iterate through all FV image files in outer FV
  for (FvImageFileCount = 1;; FvImageFileCount++) {

    Status = GetFileByType(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, FvImageFileCount, &FvImageFile);

    if (EFI_ERROR(Status) || (FvImageFile == NULL) ) {
      // exit FV image file loop, no more found
      break;
    }

    // Found an fv image file, look for an FV image section.  The PI spec does not
    // preclude multiple FV image sections so we loop accordingly.
    for (EncapFvSectionCount = 1;; EncapFvSectionCount++) {

      // Look for the next FV image section.  The section search code will
      // iterate into encapsulation sections.  For example, it will iterate
      // into an EFI_SECTION_GUID_DEFINED encapsulation section to find the
      // EFI_SECTION_FIRMWARE_VOLUME_IMAGE sections contained therein.
      Status = GetSectionByType(FvImageFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EncapFvSectionCount, &EncapFvSection);

      if (EFI_ERROR(Status)) {
        // exit section inner loop, no more found
        break;
      }

      EncapsulatedFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINT8 *)EncapFvSection.FVImageSection + GetSectionHeaderLength(EncapFvSection.FVImageSection));

      // recurse to search the encapsulated FV for this core file type
      Status = FindCorePeSection(EncapsulatedFvHeader, EncapsulatedFvHeader->FvLength, FileType, Pe32Section);

      if (!EFI_ERROR(Status)) {
        // we found the core in the capsulated image, success
        goto EarlyExit;
      }

    } // end encapsulated fv image section loop
  } // end fv image file loop

  // core was not found
  Status = EFI_NOT_FOUND;

EarlyExit:

  // restore FV lib values
  if(OrigFvHeader != NULL) {
    InitializeFvLib(OrigFvHeader, OrigFvLength);
  }

  return Status;
}

EFI_STATUS
GetCoreMachineType(
  IN  EFI_FILE_SECTION_POINTER     Pe32Section,
  OUT UINT16                      *CoreMachineType
  )
/*++

Routine Description:

  Returns the machine type of a P32 image, typically SEC or PEI core.

Arguments:

  Pe32Section       PE32 section data
  CoreMachineType   The extracted machine type

Returns:

  EFI_SUCCESS             Function Completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.

--*/
{
  EFI_STATUS                  Status;
  UINT32                      EntryPoint;
  UINT32                      BaseOfCode;

  if (CoreMachineType == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Status = GetPe32Info(
    (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
    &EntryPoint,
    &BaseOfCode,
    CoreMachineType
    );
  if (EFI_ERROR(Status)) {
    Error(NULL, 0, 3000, "Invalid", "could not get the PE32 machine type for the core.");
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
GetCoreEntryPointAddress(
  IN VOID                         *FvImageBuffer,
  IN FV_INFO                      *FvInfo,
  IN  EFI_FILE_SECTION_POINTER     Pe32Section,
  OUT EFI_PHYSICAL_ADDRESS        *CoreEntryAddress
)
/*++

Routine Description:

  Returns the physical address of the core (SEC or PEI) entry point.

Arguments:

  FvImageBuffer     Pointer to buffer containing FV data
  FvInfo            Info for the parent FV
  Pe32Section       PE32 section data
  CoreEntryAddress  The extracted core entry physical address

Returns:

  EFI_SUCCESS             Function Completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.

--*/
{
  EFI_STATUS                  Status;
  UINT32                      EntryPoint;
  UINT32                      BaseOfCode;
  UINT16                      MachineType;
  EFI_PHYSICAL_ADDRESS        EntryPhysicalAddress;

  if (CoreEntryAddress == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Status = GetPe32Info(
    (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
    &EntryPoint,
    &BaseOfCode,
    &MachineType
    );
  if (EFI_ERROR(Status)) {
    Error(NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the core.");
    return EFI_ABORTED;
  }

  //
  // Physical address is FV base + offset of PE32 + offset of the entry point
  //
  EntryPhysicalAddress = FvInfo->BaseAddress;
  EntryPhysicalAddress += (UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN)FvImageBuffer;
  EntryPhysicalAddress += EntryPoint;

  *CoreEntryAddress = EntryPhysicalAddress;

  return EFI_SUCCESS;
}

EFI_STATUS
UpdateArmResetVectorIfNeeded (
  IN MEMORY_FILE            *FvImage,
  IN FV_INFO                *FvInfo
  )
/*++

Routine Description:
  This parses the FV looking for SEC and patches that address into the
  beginning of the FV header.

  For ARM32 the reset vector is at 0x00000000 or 0xFFFF0000.
  For AArch64 the reset vector is at 0x00000000.

  This would commonly map to the first entry in the ROM.
  ARM32 Exceptions:
  Reset            +0
  Undefined        +4
  SWI              +8
  Prefetch Abort   +12
  Data Abort       +16
  IRQ              +20
  FIQ              +24

  We support two schemes on ARM.
  1) Beginning of the FV is the reset vector
  2) Reset vector is data bytes FDF file and that code branches to reset vector
    in the beginning of the FV (fixed size offset).

  Need to have the jump for the reset vector at location zero.
  We also need to store the address or PEI (if it exists).
  We stub out a return from interrupt in case the debugger
   is using SWI (not done for AArch64, not enough space in struct).
  The optional entry to the common exception handler is
   to support full featured exception handling from ROM and is currently
    not support by this tool.

Arguments:
  FvImage       Memory file for the FV memory image
  FvInfo        Information read from INF file.

Returns:

  EFI_SUCCESS             Function Completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.
  EFI_NOT_FOUND           PEI Core file not found.

--*/
{
  EFI_STATUS                  Status;
  EFI_FILE_SECTION_POINTER    SecPe32;
  EFI_FILE_SECTION_POINTER    PeiPe32;
  BOOLEAN                     UpdateVectorSec = FALSE;
  BOOLEAN                     UpdateVectorPei = FALSE;
  UINT16                      MachineType = 0;
  EFI_PHYSICAL_ADDRESS        SecCoreEntryAddress = 0;
  UINT16                      PeiMachineType = 0;
  EFI_PHYSICAL_ADDRESS        PeiCoreEntryAddress = 0;

  //
  // Verify input parameters
  //
  if (FvImage == NULL || FvInfo == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate an SEC Core instance and if found extract the machine type and entry point address
  //
  Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
  if (!EFI_ERROR(Status)) {

    Status = GetCoreMachineType(SecPe32, &MachineType);
    if (EFI_ERROR(Status)) {
      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");
      return EFI_ABORTED;
    }

    Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
    if (EFI_ERROR(Status)) {
      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
      return EFI_ABORTED;
    }

    VerboseMsg("UpdateArmResetVectorIfNeeded found SEC core entry at 0x%llx", (unsigned long long)SecCoreEntryAddress);
    UpdateVectorSec = TRUE;
  }

  //
  // Locate a PEI Core instance and if found extract the machine type and entry point address
  //
  Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_PEI_CORE, &PeiPe32);
  if (!EFI_ERROR(Status)) {

    Status = GetCoreMachineType(PeiPe32, &PeiMachineType);
    if (EFI_ERROR(Status)) {
      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for PEI Core.");
      return EFI_ABORTED;
    }

    Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, PeiPe32, &PeiCoreEntryAddress);
    if (EFI_ERROR(Status)) {
      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for PEI Core.");
      return EFI_ABORTED;
    }

    VerboseMsg("UpdateArmResetVectorIfNeeded found PEI core entry at 0x%llx", (unsigned long long)PeiCoreEntryAddress);

    // if we previously found an SEC Core make sure machine types match
    if (UpdateVectorSec && (MachineType != PeiMachineType)) {
      Error(NULL, 0, 3000, "Invalid", "SEC and PEI machine types do not match, can't update reset vector");
      return EFI_ABORTED;
    }
    else {
      MachineType = PeiMachineType;
    }

    UpdateVectorPei = TRUE;
  }

  if (!UpdateVectorSec && !UpdateVectorPei) {
    return EFI_SUCCESS;
  }

  if (MachineType == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) {
    // ARM: Array of 4 UINT32s:
    // 0 - is branch relative to SEC entry point
    // 1 - PEI Entry Point
    // 2 - movs pc,lr for a SWI handler
    // 3 - Place holder for Common Exception Handler
    UINT32                      ResetVector[4];

    memset(ResetVector, 0, sizeof (ResetVector));

    // if we found an SEC core entry point then generate a branch instruction
    // to it and populate a debugger SWI entry as well
    if (UpdateVectorSec) {
      UINT32                    EntryOffset;

      VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM SEC vector");

      EntryOffset = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress);

      if (EntryOffset > ARM_JUMP_OFFSET_MAX) {
          Error(NULL, 0, 3000, "Invalid", "SEC Entry point offset above 1MB of the start of the FV");
        return EFI_ABORTED;
      }

      if ((SecCoreEntryAddress & 1) != 0) {
        ResetVector[0] = ARM_JUMP_TO_THUMB(EntryOffset);
      } else {
        ResetVector[0] = ARM_JUMP_TO_ARM(EntryOffset);
      }

      // SWI handler movs   pc,lr. Just in case a debugger uses SWI
      ResetVector[2] = ARM_RETURN_FROM_EXCEPTION;

      // Place holder to support a common interrupt handler from ROM.
      // Currently not supported. For this to be used the reset vector would not be in this FV
      // and the exception vectors would be hard coded in the ROM and just through this address
      // to find a common handler in the a module in the FV.
      ResetVector[3] = 0;
    }

    // if a PEI core entry was found place its address in the vector area
    if (UpdateVectorPei) {

      VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM PEI address");

      // Address of PEI Core, if we have one
      ResetVector[1] = (UINT32)PeiCoreEntryAddress;
    }

    //
    // Copy to the beginning of the FV
    //
    memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));

  } else if (MachineType == IMAGE_FILE_MACHINE_ARM64) {
    // AArch64: Used as UINT64 ResetVector[2]
    // 0 - is branch relative to SEC entry point
    // 1 - PEI Entry Point
    UINT64                      ResetVector[2];

    memset(ResetVector, 0, sizeof (ResetVector));

    /* NOTE:
    ARMT above has an entry in ResetVector[2] for SWI. The way we are using the ResetVector
    array at the moment, for AArch64, does not allow us space for this as the header only
    allows for a fixed amount of bytes at the start. If we are sure that UEFI will live
    within the first 4GB of addressable RAM we could potentially adopt the same ResetVector
    layout as above. But for the moment we replace the four 32bit vectors with two 64bit
    vectors in the same area of the Image heasder. This allows UEFI to start from a 64bit
    base.
    */

    // if we found an SEC core entry point then generate a branch instruction to it
    if (UpdateVectorSec) {

      VerboseMsg("UpdateArmResetVectorIfNeeded updating AArch64 SEC vector");

      ResetVector[0] = (UINT64)(SecCoreEntryAddress - FvInfo->BaseAddress) >> 2;

      // B SecEntryPoint - signed_immed_26 part +/-128MB offset
      if (ResetVector[0] > 0x03FFFFFF) {
        Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 128MB of the start of the FV");
        return EFI_ABORTED;
      }
      // Add opcode for an unconditional branch with no link. i.e.: " B SecEntryPoint"
      ResetVector[0] |= ARM64_UNCONDITIONAL_JUMP_INSTRUCTION;
    }

    // if a PEI core entry was found place its address in the vector area
    if (UpdateVectorPei) {

      VerboseMsg("UpdateArmResetVectorIfNeeded updating AArch64 PEI address");

      // Address of PEI Core, if we have one
      ResetVector[1] = (UINT64)PeiCoreEntryAddress;
    }

    //
    // Copy to the beginning of the FV
    //
    memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));

  } else {
    Error(NULL, 0, 3000, "Invalid", "Unknown machine type");
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
UpdateRiscvResetVectorIfNeeded (
  MEMORY_FILE            *FvImage,
  FV_INFO                *FvInfo
  )
/*++

Routine Description:
  This parses the FV looking for SEC and patches that address into the
  beginning of the FV header.

  For RISC-V ISA, the reset vector is at 0xfff~ff00h or 200h

Arguments:
  FvImage       Memory file for the FV memory image/
  FvInfo        Information read from INF file.

Returns:

  EFI_SUCCESS             Function Completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.
  EFI_NOT_FOUND           PEI Core file not found.

--*/
{
  EFI_STATUS                Status;
  UINT16                    MachineType;
  EFI_FILE_SECTION_POINTER  SecPe32;
  EFI_PHYSICAL_ADDRESS      SecCoreEntryAddress;

  UINT32 bSecCore;
  UINT32 tmp;


  //
  // Verify input parameters
  //
  if (FvImage == NULL || FvInfo == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Initialize FV library
  //
  InitializeFvLib (FvImage->FileImage, FvInfo->Size);

  //
  // Find the Sec Core
  //
  Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
  if(EFI_ERROR(Status)) {
    printf("skip because Secutiry Core not found\n");
    return EFI_SUCCESS;
  }

  DebugMsg (NULL, 0, 9, "Update SEC core in FV Header", NULL);

  Status = GetCoreMachineType(SecPe32, &MachineType);
  if(EFI_ERROR(Status)) {
    Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC core.");
    return EFI_ABORTED;
  }

  if (MachineType != IMAGE_FILE_MACHINE_RISCV64) {
    Error(NULL, 0, 3000, "Invalid", "Could not update SEC core because Machine type is not RiscV.");
    return EFI_ABORTED;
  }

  Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
  if(EFI_ERROR(Status)) {
    Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
    return EFI_ABORTED;
  }

  VerboseMsg("SecCore entry point Address = 0x%llX", (unsigned long long) SecCoreEntryAddress);
  VerboseMsg("BaseAddress = 0x%llX", (unsigned long long) FvInfo->BaseAddress);
  bSecCore = (UINT32)(SecCoreEntryAddress - FvInfo->BaseAddress);
  VerboseMsg("offset = 0x%X", bSecCore);

  if(bSecCore > 0x0fffff) {
    Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 1MB of start of the FV");
    return EFI_ABORTED;
  }

  tmp = bSecCore;
  bSecCore = 0;
  //J-type
  bSecCore  = (tmp&0x100000)<<11; //imm[20]    at bit[31]
  bSecCore |= (tmp&0x0007FE)<<20; //imm[10:1]  at bit[30:21]
  bSecCore |= (tmp&0x000800)<<9;  //imm[11]    at bit[20]
  bSecCore |= (tmp&0x0FF000);     //imm[19:12] at bit[19:12]
  bSecCore |= 0x6F; //JAL opcode

  memcpy(FvImage->FileImage, &bSecCore, sizeof(bSecCore));

  return EFI_SUCCESS;
}

EFI_STATUS
UpdateLoongArchResetVectorIfNeeded (
  IN MEMORY_FILE            *FvImage,
  IN FV_INFO                *FvInfo
  )
/*++

Routine Description:
  This parses the FV looking for SEC and patches that address into the
  beginning of the FV header.

  For LoongArch ISA, the reset vector is at 0x1c000000.

  We relocate it to SecCoreEntry and copy the ResetVector code to the
  beginning of the FV.

Arguments:
  FvImage       Memory file for the FV memory image
  FvInfo        Information read from INF file.

Returns:

  EFI_SUCCESS             Function Completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.
  EFI_NOT_FOUND           PEI Core file not found.

--*/
{
  EFI_STATUS                  Status;
  EFI_FILE_SECTION_POINTER    SecPe32;
  BOOLEAN                     UpdateVectorSec = FALSE;
  UINT16                      MachineType = 0;
  EFI_PHYSICAL_ADDRESS        SecCoreEntryAddress = 0;

  //
  // Verify input parameters
  //
  if (FvImage == NULL || FvInfo == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate an SEC Core instance and if found extract the machine type and entry point address
  //
  Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
  if (!EFI_ERROR(Status)) {

    Status = GetCoreMachineType(SecPe32, &MachineType);
    if (EFI_ERROR(Status)) {
      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");
      return EFI_ABORTED;
    }

    Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
    if (EFI_ERROR(Status)) {
      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
      return EFI_ABORTED;
    }

    UpdateVectorSec = TRUE;
  }

  if (!UpdateVectorSec)
    return EFI_SUCCESS;

  if (MachineType == IMAGE_FILE_MACHINE_LOONGARCH64) {
    UINT32                      ResetVector[1];

    memset(ResetVector, 0, sizeof (ResetVector));

    /* if we found an SEC core entry point then generate a branch instruction */
    if (UpdateVectorSec) {
      VerboseMsg("UpdateLoongArchResetVectorIfNeeded updating LOONGARCH64 SEC vector");

      ResetVector[0] = ((SecCoreEntryAddress - FvInfo->BaseAddress) & 0x3FFFFFF) >> 2;
      ResetVector[0] = ((ResetVector[0] & 0x0FFFF) << 10) | ((ResetVector[0] >> 16) & 0x3FF);
      ResetVector[0] |= 0x50000000; /* b offset */
    }

    //
    // Copy to the beginning of the FV
    //
    memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));
  } else {
    Error(NULL, 0, 3000, "Invalid", "Unknown machine type");
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
GetPe32Info (
  IN UINT8                  *Pe32,
  OUT UINT32                *EntryPoint,
  OUT UINT32                *BaseOfCode,
  OUT UINT16                *MachineType
  )
/*++

Routine Description:

  Retrieves the PE32 entry point offset and machine type from PE image or TeImage.
  See EfiImage.h for machine types.  The entry point offset is from the beginning
  of the PE32 buffer passed in.

Arguments:

  Pe32          Beginning of the PE32.
  EntryPoint    Offset from the beginning of the PE32 to the image entry point.
  BaseOfCode    Base address of code.
  MachineType   Magic number for the machine type.

Returns:

  EFI_SUCCESS             Function completed successfully.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.
  EFI_UNSUPPORTED         The operation is unsupported.

--*/
{
  EFI_IMAGE_DOS_HEADER             *DosHeader;
  EFI_IMAGE_OPTIONAL_HEADER_UNION  *ImgHdr;
  EFI_TE_IMAGE_HEADER              *TeHeader;

  //
  // Verify input parameters
  //
  if (Pe32 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // First check whether it is one TE Image.
  //
  TeHeader = (EFI_TE_IMAGE_HEADER *) Pe32;
  if (TeHeader->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
    //
    // By TeImage Header to get output
    //
    *EntryPoint   = TeHeader->AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize;
    *BaseOfCode   = TeHeader->BaseOfCode + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize;
    *MachineType  = TeHeader->Machine;
  } else {

    //
    // Then check whether
    // First is the DOS header
    //
    DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32;

    //
    // Verify DOS header is expected
    //
    if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
      Error (NULL, 0, 3000, "Invalid", "Unknown magic number in the DOS header, 0x%04X.", DosHeader->e_magic);
      return EFI_UNSUPPORTED;
    }
    //
    // Immediately following is the NT header.
    //
    ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN) Pe32 + DosHeader->e_lfanew);

    //
    // Verify NT header is expected
    //
    if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
      Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature);
      return EFI_UNSUPPORTED;
    }
    //
    // Get output
    //
    *EntryPoint   = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
    *BaseOfCode   = ImgHdr->Pe32.OptionalHeader.BaseOfCode;
    *MachineType  = ImgHdr->Pe32.FileHeader.Machine;
  }

  //
  // Verify machine type is supported
  //
  if ((*MachineType != IMAGE_FILE_MACHINE_I386) &&  (*MachineType != IMAGE_FILE_MACHINE_X64) && (*MachineType != IMAGE_FILE_MACHINE_EBC) &&
      (*MachineType != IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) && (*MachineType != IMAGE_FILE_MACHINE_ARM64) &&
      (*MachineType != IMAGE_FILE_MACHINE_RISCV64) && (*MachineType != IMAGE_FILE_MACHINE_LOONGARCH64)) {
    Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
GenerateFvImage (
  IN CHAR8                *InfFileImage,
  IN UINTN                InfFileSize,
  IN CHAR8                *FvFileName,
  IN CHAR8                *MapFileName
  )
/*++

Routine Description:

  This is the main function which will be called from application.

Arguments:

  InfFileImage   Buffer containing the INF file contents.
  InfFileSize    Size of the contents of the InfFileImage buffer.
  FvFileName     Requested name for the FV file.
  MapFileName    Fv map file to log fv driver information.

Returns:

  EFI_SUCCESS             Function completed successfully.
  EFI_OUT_OF_RESOURCES    Could not allocate required resources.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.

--*/
{
  EFI_STATUS                      Status;
  MEMORY_FILE                     InfMemoryFile;
  MEMORY_FILE                     FvImageMemoryFile;
  UINTN                           Index;
  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;
  EFI_FFS_FILE_HEADER             *VtfFileImage;
  UINT8                           *FvBufferHeader; // to make sure fvimage header 8 type alignment.
  UINT8                           *FvImage;
  UINTN                           FvImageSize;
  FILE                            *FvFile;
  CHAR8                           *FvMapName;
  FILE                            *FvMapFile;
  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FvExtHeader;
  FILE                            *FvExtHeaderFile;
  UINTN                           FileSize;
  CHAR8                           *FvReportName;
  FILE                            *FvReportFile;

  FvBufferHeader = NULL;
  FvFile         = NULL;
  FvMapName      = NULL;
  FvMapFile      = NULL;
  FvReportName   = NULL;
  FvReportFile   = NULL;

  if (InfFileImage != NULL) {
    //
    // Initialize file structures
    //
    InfMemoryFile.FileImage           = InfFileImage;
    InfMemoryFile.CurrentFilePointer  = InfFileImage;
    InfMemoryFile.Eof                 = InfFileImage + InfFileSize;

    //
    // Parse the FV inf file for header information
    //
    Status = ParseFvInf (&InfMemoryFile, &mFvDataInfo);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 0003, "Error parsing file", "the input FV INF file.");
      return Status;
    }
  }

  //
  // Update the file name return values
  //
  if (FvFileName == NULL && mFvDataInfo.FvName[0] != '\0') {
    FvFileName = mFvDataInfo.FvName;
  }

  if (FvFileName == NULL) {
    Error (NULL, 0, 1001, "Missing option", "Output file name");
    return EFI_ABORTED;
  }

  if (mFvDataInfo.FvBlocks[0].Length == 0) {
    Error (NULL, 0, 1001, "Missing required argument", "Block Size");
    return EFI_ABORTED;
  }

  //
  // Debug message Fv File System Guid
  //
  if (mFvDataInfo.FvFileSystemGuidSet) {
    DebugMsg (NULL, 0, 9, "FV File System Guid", "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
                  (unsigned) mFvDataInfo.FvFileSystemGuid.Data1,
                  mFvDataInfo.FvFileSystemGuid.Data2,
                  mFvDataInfo.FvFileSystemGuid.Data3,
                  mFvDataInfo.FvFileSystemGuid.Data4[0],
                  mFvDataInfo.FvFileSystemGuid.Data4[1],
                  mFvDataInfo.FvFileSystemGuid.Data4[2],
                  mFvDataInfo.FvFileSystemGuid.Data4[3],
                  mFvDataInfo.FvFileSystemGuid.Data4[4],
                  mFvDataInfo.FvFileSystemGuid.Data4[5],
                  mFvDataInfo.FvFileSystemGuid.Data4[6],
                  mFvDataInfo.FvFileSystemGuid.Data4[7]);
  }

  //
  // Add PI FV extension header
  //
  FvExtHeader = NULL;
  FvExtHeaderFile = NULL;
  if (mFvDataInfo.FvExtHeaderFile[0] != 0) {
    //
    // 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
    //
    FileSize = _filelength (fileno (FvExtHeaderFile));

    //
    // Allocate a buffer for the FV Extension Header
    //
    FvExtHeader = malloc(FileSize);
    if (FvExtHeader == NULL) {
      fclose (FvExtHeaderFile);
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Read the FV Extension Header
    //
    fread (FvExtHeader, sizeof (UINT8), FileSize, FvExtHeaderFile);
    fclose (FvExtHeaderFile);

    //
    // See if there is an override for the FV Name GUID
    //
    if (mFvDataInfo.FvNameGuidSet) {
      memcpy (&FvExtHeader->FvName, &mFvDataInfo.FvNameGuid, sizeof (EFI_GUID));
    }
    memcpy (&mFvDataInfo.FvNameGuid, &FvExtHeader->FvName, sizeof (EFI_GUID));
    mFvDataInfo.FvNameGuidSet = TRUE;
  } else if (mFvDataInfo.FvNameGuidSet) {
    //
    // Allocate a buffer for the FV Extension Header
    //
    FvExtHeader = malloc(sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER));
    if (FvExtHeader == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    memcpy (&FvExtHeader->FvName, &mFvDataInfo.FvNameGuid, sizeof (EFI_GUID));
    FvExtHeader->ExtHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);
  }

  //
  // Debug message Fv Name Guid
  //
  if (mFvDataInfo.FvNameGuidSet) {
      DebugMsg (NULL, 0, 9, "FV Name Guid", "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
                  (unsigned) mFvDataInfo.FvNameGuid.Data1,
                  mFvDataInfo.FvNameGuid.Data2,
                  mFvDataInfo.FvNameGuid.Data3,
                  mFvDataInfo.FvNameGuid.Data4[0],
                  mFvDataInfo.FvNameGuid.Data4[1],
                  mFvDataInfo.FvNameGuid.Data4[2],
                  mFvDataInfo.FvNameGuid.Data4[3],
                  mFvDataInfo.FvNameGuid.Data4[4],
                  mFvDataInfo.FvNameGuid.Data4[5],
                  mFvDataInfo.FvNameGuid.Data4[6],
                  mFvDataInfo.FvNameGuid.Data4[7]);
  }

  if (CompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0 ||
    CompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem3Guid) == 0) {
    mFvDataInfo.IsPiFvImage = TRUE;
  }

  //
  // 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");
  }
  VerboseMsg ("FV Map file name is %s", FvMapName);

  //
  // 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");

  //
  // Calculate the FV size and Update Fv Size based on the actual FFS files.
  // And Update mFvDataInfo data.
  //
  Status = CalculateFvSize (&mFvDataInfo);
  if (EFI_ERROR (Status)) {
    goto Finish;
  }
  VerboseMsg ("the generated FV image size is %u bytes", (unsigned) mFvDataInfo.Size);

  //
  // support fv image and empty fv image
  //
  FvImageSize = mFvDataInfo.Size;

  //
  // Allocate the FV, assure FvImage Header 8 byte alignment
  //
  FvBufferHeader = malloc (FvImageSize + sizeof (UINT64));
  if (FvBufferHeader == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Finish;
  }
  FvImage = (UINT8 *) (((UINTN) FvBufferHeader + 7) & ~7);

  //
  // Initialize the FV to the erase polarity
  //
  if (mFvDataInfo.FvAttributes == 0) {
    //
    // Set Default Fv Attribute
    //
    mFvDataInfo.FvAttributes = FV_DEFAULT_ATTRIBUTE;
  }
  if (mFvDataInfo.FvAttributes & EFI_FVB2_ERASE_POLARITY) {
    memset (FvImage, -1, FvImageSize);
  } else {
    memset (FvImage, 0, FvImageSize);
  }

  //
  // Initialize FV header
  //
  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage;

  //
  // Initialize the zero vector to all zeros.
  //
  memset (FvHeader->ZeroVector, 0, 16);

  //
  // Copy the Fv file system GUID
  //
  memcpy (&FvHeader->FileSystemGuid, &mFvDataInfo.FvFileSystemGuid, sizeof (EFI_GUID));

  FvHeader->FvLength        = FvImageSize;
  FvHeader->Signature       = EFI_FVH_SIGNATURE;
  FvHeader->Attributes      = mFvDataInfo.FvAttributes;
  FvHeader->Revision        = EFI_FVH_REVISION;
  FvHeader->ExtHeaderOffset = 0;
  FvHeader->Reserved[0]     = 0;

  //
  // Copy firmware block map
  //
  for (Index = 0; mFvDataInfo.FvBlocks[Index].Length != 0; Index++) {
    FvHeader->BlockMap[Index].NumBlocks   = mFvDataInfo.FvBlocks[Index].NumBlocks;
    FvHeader->BlockMap[Index].Length      = mFvDataInfo.FvBlocks[Index].Length;
  }

  //
  // Add block map terminator
  //
  FvHeader->BlockMap[Index].NumBlocks   = 0;
  FvHeader->BlockMap[Index].Length      = 0;

  //
  // Complete the header
  //
  FvHeader->HeaderLength  = (UINT16) (((UINTN) &(FvHeader->BlockMap[Index + 1])) - (UINTN) FvImage);
  FvHeader->Checksum      = 0;
  FvHeader->Checksum      = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));

  //
  // If there is no FFS file, generate one empty FV
  //
  if (mFvDataInfo.FvFiles[0][0] == 0 && !mFvDataInfo.FvNameGuidSet) {
    goto WriteFile;
  }

  //
  // Initialize our "file" view of the buffer
  //
  FvImageMemoryFile.FileImage           = (CHAR8 *)FvImage;
  FvImageMemoryFile.CurrentFilePointer  = (CHAR8 *)FvImage + FvHeader->HeaderLength;
  FvImageMemoryFile.Eof                 = (CHAR8 *)FvImage + FvImageSize;

  //
  // Initialize the FV library.
  //
  InitializeFvLib (FvImageMemoryFile.FileImage, FvImageSize);

  //
  // Initialize the VTF file address.
  //
  VtfFileImage = (EFI_FFS_FILE_HEADER *) FvImageMemoryFile.Eof;

  //
  // Open FvMap file
  //
  FvMapFile = fopen (LongFilePath (FvMapName), "w");
  if (FvMapFile == NULL) {
    Error (NULL, 0, 0001, "Error opening file", FvMapName);
    Status = EFI_ABORTED;
    goto Finish;
  }

  //
  // Open FvReport file
  //
  FvReportFile = fopen (LongFilePath (FvReportName), "w");
  if (FvReportFile == NULL) {
    Error (NULL, 0, 0001, "Error opening file", FvReportName);
    Status = EFI_ABORTED;
    goto Finish;
  }
  //
  // record FV size information into FvMap file.
  //
  if (mFvTotalSize != 0) {
    fprintf (FvMapFile, EFI_FV_TOTAL_SIZE_STRING);
    fprintf (FvMapFile, " = 0x%x\n", (unsigned) mFvTotalSize);
  }
  if (mFvTakenSize != 0) {
    fprintf (FvMapFile, EFI_FV_TAKEN_SIZE_STRING);
    fprintf (FvMapFile, " = 0x%x\n", (unsigned) mFvTakenSize);
  }
  if (mFvTotalSize != 0 && mFvTakenSize != 0) {
    fprintf (FvMapFile, EFI_FV_SPACE_SIZE_STRING);
    fprintf (FvMapFile, " = 0x%x\n\n", (unsigned) (mFvTotalSize - mFvTakenSize));
  }

  //
  // record FV size information to FvReportFile.
  //
  fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TOTAL_SIZE_STRING, (unsigned) mFvTotalSize);
  fprintf (FvReportFile, "%s = 0x%x\n", EFI_FV_TAKEN_SIZE_STRING, (unsigned) mFvTakenSize);

  //
  // Add PI FV extension header
  //
  if (FvExtHeader != NULL) {
    //
    // Add FV Extended Header contents to the FV as a PAD file
    //
    AddPadFile (&FvImageMemoryFile, 4, VtfFileImage, FvExtHeader, 0);

    //
    // Fv Extension header change update Fv Header Check sum
    //
    FvHeader->Checksum      = 0;
    FvHeader->Checksum      = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
  }

  //
  // Add files to FV
  //
  for (Index = 0; mFvDataInfo.FvFiles[Index][0] != 0; Index++) {
    //
    // Add the file
    //
    Status = AddFile (&FvImageMemoryFile, &mFvDataInfo, Index, &VtfFileImage, FvMapFile, FvReportFile);

    //
    // Exit if error detected while adding the file
    //
    if (EFI_ERROR (Status)) {
      goto Finish;
    }
  }

  //
  // If there is a VTF file, some special actions need to occur.
  //
  if ((UINTN) VtfFileImage != (UINTN) FvImageMemoryFile.Eof) {
    //
    // Pad from the end of the last file to the beginning of the VTF file.
    // If the left space is less than sizeof (EFI_FFS_FILE_HEADER)?
    //
    Status = PadFvImage (&FvImageMemoryFile, VtfFileImage);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add pad file between the last file and the VTF file.");
      goto Finish;
    }

    if (!mArm && !mRiscV && !mLoongArch) {
      //
      // 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.
      //
      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.");
          goto Finish;
        }
        DebugMsg (NULL, 0, 9, "Update Reset vector in VTF file", NULL);
      }
    }
  }

  if (mArm) {
    Status = UpdateArmResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");
      goto Finish;
    }

    //
    // Update Checksum for FvHeader
    //
    FvHeader->Checksum = 0;
    FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
  }

  if (mRiscV) {
     //
     // Update RISCV reset vector.
     //
     Status = UpdateRiscvResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
     if (EFI_ERROR (Status)) {
       Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector for RISC-V.");
       goto Finish;
    }
    //
    // Update Checksum for FvHeader
    //
    FvHeader->Checksum = 0;
    FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
  }

  if (mLoongArch) {
    Status = UpdateLoongArchResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");
      goto Finish;
    }
    //
    // Update Checksum for FvHeader
    //
    FvHeader->Checksum = 0;
    FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
  }

  //
  // Update FV Alignment attribute to the largest alignment of all the FFS files in the FV
  //
  if (((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) &&
      (((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16)) < MaxFfsAlignment) {
    FvHeader->Attributes = ((MaxFfsAlignment << 16) | (FvHeader->Attributes & 0xFFFF));
    //
    // Update Checksum for FvHeader
    //
    FvHeader->Checksum      = 0;
    FvHeader->Checksum      = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
  }

  //
  // If there are large FFS in FV, the file system GUID should set to system 3 GUID.
  //
  if (mIsLargeFfs && CompareGuid (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0) {
    memcpy (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem3Guid, sizeof (EFI_GUID));
    FvHeader->Checksum      = 0;
    FvHeader->Checksum      = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
  }

WriteFile:
  //
  // Write fv file
  //
  FvFile = fopen (LongFilePath (FvFileName), "wb");
  if (FvFile == NULL) {
    Error (NULL, 0, 0001, "Error opening file", FvFileName);
    Status = EFI_ABORTED;
    goto Finish;
  }

  if (fwrite (FvImage, 1, FvImageSize, FvFile) != FvImageSize) {
    Error (NULL, 0, 0002, "Error writing file", FvFileName);
    Status = EFI_ABORTED;
    goto Finish;
  }

Finish:
  if (FvBufferHeader != NULL) {
    free (FvBufferHeader);
  }

  if (FvExtHeader != NULL) {
    free (FvExtHeader);
  }

  if (FvMapName != NULL) {
    free (FvMapName);
  }

  if (FvReportName != NULL) {
    free (FvReportName);
  }

  if (FvFile != NULL) {
    fflush (FvFile);
    fclose (FvFile);
  }

  if (FvMapFile != NULL) {
    fflush (FvMapFile);
    fclose (FvMapFile);
  }

  if (FvReportFile != NULL) {
    fflush (FvReportFile);
    fclose (FvReportFile);
  }
  return Status;
}

EFI_STATUS
UpdatePeiCoreEntryInFit (
  IN FIT_TABLE     *FitTablePtr,
  IN UINT64        PeiCorePhysicalAddress
  )
/*++

Routine Description:

  This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from
  Sec to Pei Core

Arguments:

  FitTablePtr             - The pointer of FIT_TABLE.
  PeiCorePhysicalAddress  - The address of Pei Core entry.

Returns:

  EFI_SUCCESS             - The PEI_CORE FIT entry was updated successfully.
  EFI_NOT_FOUND           - Not found the PEI_CORE FIT entry.

--*/
{
  FIT_TABLE *TmpFitPtr;
  UINTN     Index;
  UINTN     NumFitComponents;

  TmpFitPtr         = FitTablePtr;
  NumFitComponents  = TmpFitPtr->CompSize;

  for (Index = 0; Index < NumFitComponents; Index++) {
    if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_PEICORE) {
      TmpFitPtr->CompAddress = PeiCorePhysicalAddress;
      return EFI_SUCCESS;
    }

    TmpFitPtr++;
  }

  return EFI_NOT_FOUND;
}

VOID
UpdateFitCheckSum (
  IN FIT_TABLE   *FitTablePtr
  )
/*++

Routine Description:

  This function is used to update the checksum for FIT.


Arguments:

  FitTablePtr             - The pointer of FIT_TABLE.

Returns:

  None.

--*/
{
  if ((FitTablePtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) {
    FitTablePtr->CheckSum = 0;
    FitTablePtr->CheckSum = CalculateChecksum8 ((UINT8 *) FitTablePtr, FitTablePtr->CompSize * 16);
  }
}

EFI_STATUS
CalculateFvSize (
  FV_INFO *FvInfoPtr
  )
/*++
Routine Description:
  Calculate the FV size and Update Fv Size based on the actual FFS files.
  And Update FvInfo data.

Arguments:
  FvInfoPtr     - The pointer to FV_INFO structure.

Returns:
  EFI_ABORTED   - Ffs Image Error
  EFI_SUCCESS   - Successfully update FvSize
--*/
{
  UINTN               CurrentOffset;
  UINTN               OrigOffset;
  UINTN               Index;
  FILE                *fpin;
  UINTN               FfsFileSize;
  UINTN               FvExtendHeaderSize;
  UINT32              FfsAlignment;
  UINT32              FfsHeaderSize;
  EFI_FFS_FILE_HEADER FfsHeader;
  UINTN               VtfFileSize;
  UINTN               MaxPadFileSize;

  FvExtendHeaderSize = 0;
  MaxPadFileSize = 0;
  VtfFileSize = 0;
  fpin  = NULL;
  Index = 0;

  //
  // Compute size for easy access later
  //
  FvInfoPtr->Size = 0;
  for (Index = 0; FvInfoPtr->FvBlocks[Index].NumBlocks > 0 && FvInfoPtr->FvBlocks[Index].Length > 0; Index++) {
    FvInfoPtr->Size += FvInfoPtr->FvBlocks[Index].NumBlocks * FvInfoPtr->FvBlocks[Index].Length;
  }

  //
  // Calculate the required sizes for all FFS files.
  //
  CurrentOffset = sizeof (EFI_FIRMWARE_VOLUME_HEADER);

  for (Index = 1;; Index ++) {
    CurrentOffset += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
    if (FvInfoPtr->FvBlocks[Index].NumBlocks == 0 || FvInfoPtr->FvBlocks[Index].Length == 0) {
      break;
    }
  }

  //
  // Calculate PI extension header
  //
  if (mFvDataInfo.FvExtHeaderFile[0] != '\0') {
    fpin = fopen (LongFilePath (mFvDataInfo.FvExtHeaderFile), "rb");
    if (fpin == NULL) {
      Error (NULL, 0, 0001, "Error opening file", mFvDataInfo.FvExtHeaderFile);
      return EFI_ABORTED;
    }
    FvExtendHeaderSize = _filelength (fileno (fpin));
    fclose (fpin);
    if (sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize >= MAX_FFS_SIZE) {
      CurrentOffset += sizeof (EFI_FFS_FILE_HEADER2) + FvExtendHeaderSize;
      mIsLargeFfs = TRUE;
    } else {
      CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize;
    }
    CurrentOffset = (CurrentOffset + 7) & (~7);
  } else if (mFvDataInfo.FvNameGuidSet) {
    CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);
    CurrentOffset = (CurrentOffset + 7) & (~7);
  }

  //
  // Accumulate every FFS file size.
  //
  for (Index = 0; FvInfoPtr->FvFiles[Index][0] != 0; Index++) {
    //
    // Open FFS file
    //
    fpin = NULL;
    fpin = fopen (LongFilePath (FvInfoPtr->FvFiles[Index]), "rb");
    if (fpin == NULL) {
      Error (NULL, 0, 0001, "Error opening file", FvInfoPtr->FvFiles[Index]);
      return EFI_ABORTED;
    }
    //
    // Get the file size
    //
    FfsFileSize = _filelength (fileno (fpin));
    if (FfsFileSize >= MAX_FFS_SIZE) {
      FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER2);
      mIsLargeFfs = TRUE;
    } else {
      FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER);
    }
    //
    // Read Ffs File header
    //
    fread (&FfsHeader, sizeof (UINT8), sizeof (EFI_FFS_FILE_HEADER), fpin);
    //
    // close file
    //
    fclose (fpin);

    if (FvInfoPtr->IsPiFvImage) {
        //
        // Check whether this ffs file is vtf file
        //
        if (IsVtfFile (&FfsHeader)) {
          if (VtfFileFlag) {
            //
            // One Fv image can't have two vtf files.
            //
            Error (NULL, 0, 3000,"Invalid", "One Fv image can't have two vtf files.");
            return EFI_ABORTED;
          }
          VtfFileFlag = TRUE;
        VtfFileSize = FfsFileSize;
        continue;
      }

      //
      // Get the alignment of FFS file
      //
      ReadFfsAlignment (&FfsHeader, &FfsAlignment);
      FfsAlignment = 1 << FfsAlignment;
      //
      // Add Pad file
      //
      if (((CurrentOffset + FfsHeaderSize) % FfsAlignment) != 0) {
        //
        // Only EFI_FFS_FILE_HEADER is needed for a pad section.
        //
        OrigOffset    = CurrentOffset;
        CurrentOffset = (CurrentOffset + FfsHeaderSize + sizeof(EFI_FFS_FILE_HEADER) + FfsAlignment - 1) & ~(FfsAlignment - 1);
        CurrentOffset -= FfsHeaderSize;
        if ((CurrentOffset - OrigOffset) > MaxPadFileSize) {
          MaxPadFileSize = CurrentOffset - OrigOffset;
        }
      }
    }

    //
    // Add ffs file size
    //
    if (FvInfoPtr->SizeofFvFiles[Index] > FfsFileSize) {
      CurrentOffset += FvInfoPtr->SizeofFvFiles[Index];
    } else {
      CurrentOffset += FfsFileSize;
    }

    //
    // Make next ffs file start at QWord Boundary
    //
    if (FvInfoPtr->IsPiFvImage) {
      CurrentOffset = (CurrentOffset + EFI_FFS_FILE_HEADER_ALIGNMENT - 1) & ~(EFI_FFS_FILE_HEADER_ALIGNMENT - 1);
    }
  }
  CurrentOffset += VtfFileSize;
  DebugMsg (NULL, 0, 9, "FvImage size", "The calculated fv image size is 0x%x and the current set fv image size is 0x%x", (unsigned) CurrentOffset, (unsigned) FvInfoPtr->Size);

  if (FvInfoPtr->Size == 0) {
    //
    // Update FvInfo data
    //
    FvInfoPtr->FvBlocks[0].NumBlocks = CurrentOffset / FvInfoPtr->FvBlocks[0].Length + ((CurrentOffset % FvInfoPtr->FvBlocks[0].Length)?1:0);
    FvInfoPtr->Size = FvInfoPtr->FvBlocks[0].NumBlocks * FvInfoPtr->FvBlocks[0].Length;
    FvInfoPtr->FvBlocks[1].NumBlocks = 0;
    FvInfoPtr->FvBlocks[1].Length = 0;
  } else if (FvInfoPtr->Size < CurrentOffset) {
    //
    // Not invalid
    //
    Error (NULL, 0, 3000, "Invalid", "the required fv image size 0x%x exceeds the set fv image size 0x%x", (unsigned) CurrentOffset, (unsigned) FvInfoPtr->Size);
    return EFI_INVALID_PARAMETER;
  }

  //
  // Set Fv Size Information
  //
  mFvTotalSize = FvInfoPtr->Size;
  mFvTakenSize = CurrentOffset;
  if ((mFvTakenSize == mFvTotalSize) && (MaxPadFileSize > 0)) {
    //
    // This FV means TOP FFS has been taken. Then, check whether there is padding data for use.
    //
    mFvTakenSize = mFvTakenSize - MaxPadFileSize;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
FfsRebaseImageRead (
  IN     VOID    *FileHandle,
  IN     UINTN   FileOffset,
  IN OUT UINT32  *ReadSize,
  OUT    VOID    *Buffer
  )
/*++

Routine Description:

  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file

Arguments:

  FileHandle - The handle to the PE/COFF file

  FileOffset - The offset, in bytes, into the file to read

  ReadSize   - The number of bytes to read from the file starting at FileOffset

  Buffer     - A pointer to the buffer to read the data into.

Returns:

  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset

--*/
{
  CHAR8   *Destination8;
  CHAR8   *Source8;
  UINT32  Length;

  Destination8  = Buffer;
  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
  Length        = *ReadSize;
  while (Length--) {
    *(Destination8++) = *(Source8++);
  }

  return EFI_SUCCESS;
}

EFI_STATUS
GetChildFvFromFfs (
  IN      FV_INFO               *FvInfo,
  IN      EFI_FFS_FILE_HEADER   *FfsFile,
  IN      UINTN                 XipOffset
  )
/*++

Routine Description:

  This function gets all child FvImages in the input FfsFile, and records
  their base address to the parent image.

Arguments:
  FvInfo            A pointer to FV_INFO structure.
  FfsFile           A pointer to Ffs file image that may contain FvImage.
  XipOffset         The offset address to the parent FvImage base.

Returns:

  EFI_SUCCESS        Base address of child Fv image is recorded.
--*/
{
  EFI_STATUS                          Status;
  UINTN                               Index;
  EFI_FILE_SECTION_POINTER            SubFvSection;
  EFI_FIRMWARE_VOLUME_HEADER          *SubFvImageHeader;
  EFI_PHYSICAL_ADDRESS                SubFvBaseAddress;
  EFI_FILE_SECTION_POINTER            CorePe32;
  UINT16                              MachineType;

  for (Index = 1;; Index++) {
    //
    // Find FV section
    //
    Status = GetSectionByType (FfsFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, Index, &SubFvSection);
    if (EFI_ERROR (Status)) {
      break;
    }
    SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + GetSectionHeaderLength(SubFvSection.FVImageSection));

    //
    // See if there's an SEC core in the child FV
    Status = FindCorePeSection(SubFvImageHeader, SubFvImageHeader->FvLength, EFI_FV_FILETYPE_SECURITY_CORE, &CorePe32);

    // if we couldn't find the SEC core, look for a PEI core
    if (EFI_ERROR(Status)) {
      Status = FindCorePeSection(SubFvImageHeader, SubFvImageHeader->FvLength, EFI_FV_FILETYPE_PEI_CORE, &CorePe32);
    }

    if (!EFI_ERROR(Status)) {
      Status = GetCoreMachineType(CorePe32, &MachineType);
      if (EFI_ERROR(Status)) {
        Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC/PEI Core.");
        return EFI_ABORTED;
      }

      // machine type is ARM, set a flag so ARM reset vector processing occurs
      if ((MachineType == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || (MachineType == IMAGE_FILE_MACHINE_ARM64)) {
        VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
        mArm = TRUE;
      }

      // Machine type is LOONGARCH64, set a flag so LoongArch64 reset vector processed.
      if (MachineType == IMAGE_FILE_MACHINE_LOONGARCH64) {
        VerboseMsg("Located LoongArch64 SEC core in child FV");
        mLoongArch = TRUE;
      }
    }

    //
    // Rebase on Flash
    //
    SubFvBaseAddress = FvInfo->BaseAddress + (UINTN) SubFvImageHeader - (UINTN) FfsFile + XipOffset;
    mFvBaseAddress[mFvBaseAddressNumber ++ ] = SubFvBaseAddress;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
FfsRebase (
  IN OUT  FV_INFO               *FvInfo,
  IN      CHAR8                 *FileName,
  IN OUT  EFI_FFS_FILE_HEADER   *FfsFile,
  IN      UINTN                 XipOffset,
  IN      FILE                  *FvMapFile
  )
/*++

Routine Description:

  This function determines if a file is XIP and should be rebased.  It will
  rebase any PE32 sections found in the file using the base address.

Arguments:

  FvInfo            A pointer to FV_INFO structure.
  FileName          Ffs File PathName
  FfsFile           A pointer to Ffs file image.
  XipOffset         The offset address to use for rebasing the XIP file image.
  FvMapFile         FvMapFile to record the function address in one Fvimage

Returns:

  EFI_SUCCESS             The image was properly rebased.
  EFI_INVALID_PARAMETER   An input parameter is invalid.
  EFI_ABORTED             An error occurred while rebasing the input file image.
  EFI_OUT_OF_RESOURCES    Could not allocate a required resource.
  EFI_NOT_FOUND           No compressed sections could be found.

--*/
{
  EFI_STATUS                            Status;
  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;
  PE_COFF_LOADER_IMAGE_CONTEXT          OrigImageContext;
  EFI_PHYSICAL_ADDRESS                  XipBase;
  EFI_PHYSICAL_ADDRESS                  NewPe32BaseAddress;
  UINTN                                 Index;
  EFI_FILE_SECTION_POINTER              CurrentPe32Section;
  EFI_FFS_FILE_STATE                    SavedState;
  EFI_IMAGE_OPTIONAL_HEADER_UNION       *ImgHdr;
  EFI_TE_IMAGE_HEADER                   *TEImageHeader;
  UINT8                                 *MemoryImagePointer;
  EFI_IMAGE_SECTION_HEADER              *SectionHeader;
  CHAR8                                 PeFileName [MAX_LONG_FILE_PATH];
  CHAR8                                 *Cptr;
  FILE                                  *PeFile;
  UINT8                                 *PeFileBuffer;
  UINT32                                PeFileSize;
  CHAR8                                 *PdbPointer;
  UINT32                                FfsHeaderSize;
  UINT32                                CurSecHdrSize;

  Index              = 0;
  MemoryImagePointer = NULL;
  TEImageHeader      = NULL;
  ImgHdr             = NULL;
  SectionHeader      = NULL;
  Cptr               = NULL;
  PeFile             = NULL;
  PeFileBuffer       = NULL;

  //
  // Don't need to relocate image when BaseAddress is zero and no ForceRebase Flag specified.
  //
  if ((FvInfo->BaseAddress == 0) && (FvInfo->ForceRebase == -1)) {
    return EFI_SUCCESS;
  }

  //
  // If ForceRebase Flag specified to FALSE, will always not take rebase action.
  //
  if (FvInfo->ForceRebase == 0) {
    return EFI_SUCCESS;
  }


  XipBase = FvInfo->BaseAddress + XipOffset;

  //
  // We only process files potentially containing PE32 sections.
  //
  switch (FfsFile->Type) {
    case EFI_FV_FILETYPE_SECURITY_CORE:
    case EFI_FV_FILETYPE_PEI_CORE:
    case EFI_FV_FILETYPE_PEIM:
    case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
    case EFI_FV_FILETYPE_DRIVER:
    case EFI_FV_FILETYPE_DXE_CORE:
      break;
    case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
      //
      // Rebase the inside FvImage.
      //
      GetChildFvFromFfs (FvInfo, FfsFile, XipOffset);

      //
      // Search PE/TE section in FV sectin.
      //
      break;
    default:
      return EFI_SUCCESS;
  }

  FfsHeaderSize = GetFfsHeaderLength(FfsFile);
  //
  // Rebase each PE32 section
  //
  Status      = EFI_SUCCESS;
  for (Index = 1;; Index++) {
    //
    // Init Value
    //
    NewPe32BaseAddress = 0;

    //
    // Find Pe Image
    //
    Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
    if (EFI_ERROR (Status)) {
      break;
    }
    CurSecHdrSize = GetSectionHeaderLength(CurrentPe32Section.CommonHeader);

    //
    // Initialize context
    //
    memset (&ImageContext, 0, sizeof (ImageContext));
    ImageContext.Handle     = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
      return Status;
    }

    if ( (ImageContext.Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) ||
         (ImageContext.Machine == IMAGE_FILE_MACHINE_ARM64) ) {
      mArm = TRUE;
    }

    if (ImageContext.Machine == IMAGE_FILE_MACHINE_RISCV64) {
      mRiscV = TRUE;
    }

    if (ImageContext.Machine == IMAGE_FILE_MACHINE_LOONGARCH64) {
      mLoongArch = TRUE;
    }

    //
    // Keep Image Context for PE image in FV
    //
    memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext));

    //
    // Get File PdbPointer
    //
    PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);

    //
    // Get PeHeader pointer
    //
    ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset);

    //
    // Calculate the PE32 base address, based on file type
    //
    switch (FfsFile->Type) {
      case EFI_FV_FILETYPE_SECURITY_CORE:
      case EFI_FV_FILETYPE_PEI_CORE:
      case EFI_FV_FILETYPE_PEIM:
      case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
        //
        // Check if section-alignment and file-alignment match or not
        //
        if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
          //
          // Xip module has the same section alignment and file alignment.
          //
          Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
          return EFI_ABORTED;
        }
        //
        // PeImage has no reloc section. It will try to get reloc data from the original EFI image.
        //
        if (ImageContext.RelocationsStripped) {
          //
          // Construct the original efi file Name
          //
          if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
            Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);
            return EFI_ABORTED;
          }
          strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1);
          PeFileName[MAX_LONG_FILE_PATH - 1] = 0;
          Cptr = PeFileName + strlen (PeFileName);
          while (*Cptr != '.') {
            Cptr --;
          }
          if (*Cptr != '.') {
            Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
            return EFI_ABORTED;
          } else {
            *(Cptr + 1) = 'e';
            *(Cptr + 2) = 'f';
            *(Cptr + 3) = 'i';
            *(Cptr + 4) = '\0';
          }
          PeFile = fopen (LongFilePath (PeFileName), "rb");
          if (PeFile == NULL) {
            Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
            //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
            //return EFI_ABORTED;
            break;
          }
          //
          // Get the file size
          //
          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;
          }
          //
          // Read Pe File
          //
          fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile);
          //
          // close file
          //
          fclose (PeFile);
          //
          // Handle pointer to the original efi image.
          //
          ImageContext.Handle = PeFileBuffer;
          Status              = PeCoffLoaderGetImageInfo (&ImageContext);
          if (EFI_ERROR (Status)) {
            Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
            return Status;
          }
          ImageContext.RelocationsStripped = FALSE;
        }

        NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
        break;

      case EFI_FV_FILETYPE_DRIVER:
      case EFI_FV_FILETYPE_DXE_CORE:
        //
        // Check if section-alignment and file-alignment match or not
        //
        if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
          //
          // Xip module has the same section alignment and file alignment.
          //
          Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
          return EFI_ABORTED;
        }
        NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
        break;

      default:
        //
        // Not supported file type
        //
        return EFI_SUCCESS;
    }

    //
    // Relocation doesn't exist
    //
    if (ImageContext.RelocationsStripped) {
      Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
      continue;
    }

    //
    // Relocation exist and rebase
    //
    //
    // Load and Relocate Image Data
    //
    MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
    if (MemoryImagePointer == NULL) {
      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
      return EFI_OUT_OF_RESOURCES;
    }
    memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
    ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1));

    Status =  PeCoffLoaderLoadImage (&ImageContext);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
      free ((VOID *) MemoryImagePointer);
      return Status;
    }

    ImageContext.DestinationAddress = NewPe32BaseAddress;
    Status                          = PeCoffLoaderRelocateImage (&ImageContext);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);
      free ((VOID *) MemoryImagePointer);
      return Status;
    }

    //
    // Copy Relocated data to raw image file.
    //
    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
                       (UINTN) ImgHdr +
                       sizeof (UINT32) +
                       sizeof (EFI_IMAGE_FILE_HEADER) +
                       ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
                       );

    for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
      CopyMem (
        (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData,
        (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
        SectionHeader->SizeOfRawData
        );
    }

    free ((VOID *) MemoryImagePointer);
    MemoryImagePointer = NULL;
    if (PeFileBuffer != NULL) {
      free (PeFileBuffer);
      PeFileBuffer = NULL;
    }

    //
    // Update Image Base Address
    //
    if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
    } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
      ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
    } else {
      Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
        ImgHdr->Pe32.OptionalHeader.Magic,
        FileName
        );
      return EFI_ABORTED;
    }

    //
    // Now update file checksum
    //
    if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
      SavedState  = FfsFile->State;
      FfsFile->IntegrityCheck.Checksum.File = 0;
      FfsFile->State                        = 0;
      FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
                                                (UINT8 *) ((UINT8 *)FfsFile + FfsHeaderSize),
                                                GetFfsFileLength (FfsFile) - FfsHeaderSize
                                                );
      FfsFile->State = SavedState;
    }

    //
    // Get this module function address from ModulePeMapFile and add them into FvMap file
    //

    //
    // Default use FileName as map file path
    //
    if (PdbPointer == NULL) {
      PdbPointer = FileName;
    }

    WriteMapFile (FvMapFile, PdbPointer, FfsFile, NewPe32BaseAddress, &OrigImageContext);
  }

  if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
      FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
      FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&
      FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
      ) {
    //
    // Only Peim code may have a TE section
    //
    return EFI_SUCCESS;
  }

  //
  // Now process TE sections
  //
  for (Index = 1;; Index++) {
    NewPe32BaseAddress = 0;

    //
    // Find Te Image
    //
    Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);
    if (EFI_ERROR (Status)) {
      break;
    }

    CurSecHdrSize = GetSectionHeaderLength(CurrentPe32Section.CommonHeader);

    //
    // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
    // by GenTEImage
    //
    TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize);

    //
    // Initialize context, load image info.
    //
    memset (&ImageContext, 0, sizeof (ImageContext));
    ImageContext.Handle     = (VOID *) TEImageHeader;
    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
      return Status;
    }

    if ( (ImageContext.Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) ||
         (ImageContext.Machine == IMAGE_FILE_MACHINE_ARM64) ) {
      mArm = TRUE;
    }

    if (ImageContext.Machine == IMAGE_FILE_MACHINE_LOONGARCH64) {
      mLoongArch = TRUE;
    }

    //
    // Keep Image Context for TE image in FV
    //
    memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext));

    //
    // Get File PdbPointer
    //
    PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);

    //
    // Set new rebased address.
    //
    NewPe32BaseAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \
                         - TEImageHeader->StrippedSize - (UINTN) FfsFile;

    //
    // if reloc is stripped, try to get the original efi image to get reloc info.
    //
    if (ImageContext.RelocationsStripped) {
      //
      // Construct the original efi file name
      //
      if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
        Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);
        return EFI_ABORTED;
      }
      strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1);
      PeFileName[MAX_LONG_FILE_PATH - 1] = 0;
      Cptr = PeFileName + strlen (PeFileName);
      while (*Cptr != '.') {
        Cptr --;
      }

      if (*Cptr != '.') {
        Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
        return EFI_ABORTED;
      } else {
        *(Cptr + 1) = 'e';
        *(Cptr + 2) = 'f';
        *(Cptr + 3) = 'i';
        *(Cptr + 4) = '\0';
      }

      PeFile = fopen (LongFilePath (PeFileName), "rb");
      if (PeFile == NULL) {
        Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
        //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
        //return EFI_ABORTED;
      } else {
        //
        // Get the file size
        //
        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;
        }
        //
        // Read Pe File
        //
        fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile);
        //
        // close file
        //
        fclose (PeFile);
        //
        // Append reloc section into TeImage
        //
        ImageContext.Handle = PeFileBuffer;
        Status              = PeCoffLoaderGetImageInfo (&ImageContext);
        if (EFI_ERROR (Status)) {
          Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
          return Status;
        }
        ImageContext.RelocationsStripped = FALSE;
      }
    }
    //
    // Relocation doesn't exist
    //
    if (ImageContext.RelocationsStripped) {
      Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
      continue;
    }

    //
    // Relocation exist and rebase
    //
    //
    // Load and Relocate Image Data
    //
    MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
    if (MemoryImagePointer == NULL) {
      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
      return EFI_OUT_OF_RESOURCES;
    }
    memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
    ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1));

    Status =  PeCoffLoaderLoadImage (&ImageContext);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
      free ((VOID *) MemoryImagePointer);
      return Status;
    }
    //
    // Reloacate TeImage
    //
    ImageContext.DestinationAddress = NewPe32BaseAddress;
    Status                          = PeCoffLoaderRelocateImage (&ImageContext);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);
      free ((VOID *) MemoryImagePointer);
      return Status;
    }

    //
    // Copy the relocated image into raw image file.
    //
    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);
    for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {
      if (!ImageContext.IsTeImage) {
        CopyMem (
          (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
          (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
          SectionHeader->SizeOfRawData
          );
      } else {
        CopyMem (
          (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData,
          (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress),
          SectionHeader->SizeOfRawData
          );
      }
    }

    //
    // Free the allocated memory resource
    //
    free ((VOID *) MemoryImagePointer);
    MemoryImagePointer = NULL;
    if (PeFileBuffer != NULL) {
      free (PeFileBuffer);
      PeFileBuffer = NULL;
    }

    //
    // Update Image Base Address
    //
    TEImageHeader->ImageBase = NewPe32BaseAddress;

    //
    // Now update file checksum
    //
    if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
      SavedState  = FfsFile->State;
      FfsFile->IntegrityCheck.Checksum.File = 0;
      FfsFile->State                        = 0;
      FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
                                                (UINT8 *)((UINT8 *)FfsFile + FfsHeaderSize),
                                                GetFfsFileLength (FfsFile) - FfsHeaderSize
                                                );
      FfsFile->State = SavedState;
    }
    //
    // Get this module function address from ModulePeMapFile and add them into FvMap file
    //

    //
    // Default use FileName as map file path
    //
    if (PdbPointer == NULL) {
      PdbPointer = FileName;
    }

    WriteMapFile (
      FvMapFile,
      PdbPointer,
      FfsFile,
      NewPe32BaseAddress,
      &OrigImageContext
      );
  }

  return EFI_SUCCESS;
}

EFI_STATUS
ParseCapInf (
  IN  MEMORY_FILE  *InfFile,
  OUT CAP_INFO     *CapInfo
  )
/*++

Routine Description:

  This function parses a Cap.INF file and copies info into a CAP_INFO structure.

Arguments:

  InfFile        Memory file image.
  CapInfo        Information read from INF file.

Returns:

  EFI_SUCCESS       INF file information successfully retrieved.
  EFI_ABORTED       INF file has an invalid format.
  EFI_NOT_FOUND     A required string was not found in the INF file.
--*/
{
  CHAR8       Value[MAX_LONG_FILE_PATH];
  UINT64      Value64;
  UINTN       Index, Number;
  EFI_STATUS  Status;

  //
  // Initialize Cap info
  //
  // memset (CapInfo, 0, sizeof (CAP_INFO));
  //

  //
  // Read the Capsule Guid
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_CAPSULE_GUID_STRING, 0, Value);
  if (Status == EFI_SUCCESS) {
    //
    // Get the Capsule Guid
    //
    Status = StringToGuid (Value, &CapInfo->CapGuid);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_CAPSULE_GUID_STRING, Value);
      return EFI_ABORTED;
    }
    DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, Value);
  }

  //
  // Read the Capsule Header Size
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_CAPSULE_HEADER_SIZE_STRING, 0, Value);
  if (Status == EFI_SUCCESS) {
    Status = AsciiStringToUint64 (Value, FALSE, &Value64);
    if (EFI_ERROR (Status)) {
      Error (NULL, 0, 2000, "Invalid parameter", "%s = %s", EFI_CAPSULE_HEADER_SIZE_STRING, Value);
      return EFI_ABORTED;
    }
    CapInfo->HeaderSize = (UINT32) Value64;
    DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = %s", EFI_CAPSULE_HEADER_SIZE_STRING, Value);
  }

  //
  // Read the Capsule Flag
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_CAPSULE_FLAGS_STRING, 0, Value);
  if (Status == EFI_SUCCESS) {
    if (strstr (Value, "PopulateSystemTable") != NULL) {
      CapInfo->Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;
      if (strstr (Value, "InitiateReset") != NULL) {
        CapInfo->Flags |= CAPSULE_FLAGS_INITIATE_RESET;
      }
    } else if (strstr (Value, "PersistAcrossReset") != NULL) {
      CapInfo->Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
      if (strstr (Value, "InitiateReset") != NULL) {
        CapInfo->Flags |= CAPSULE_FLAGS_INITIATE_RESET;
      }
    } else {
      Error (NULL, 0, 2000, "Invalid parameter", "invalid Flag setting for %s.", EFI_CAPSULE_FLAGS_STRING);
      return EFI_ABORTED;
    }
    DebugMsg (NULL, 0, 9, "Capsule Flag", Value);
  }

  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_OEM_CAPSULE_FLAGS_STRING, 0, Value);
  if (Status == EFI_SUCCESS) {
    Status = AsciiStringToUint64 (Value, FALSE, &Value64);
    if (EFI_ERROR (Status) || Value64 > 0xffff) {
      Error (NULL, 0, 2000, "Invalid parameter",
        "invalid Flag setting for %s. Must be integer value between 0x0000 and 0xffff.",
        EFI_OEM_CAPSULE_FLAGS_STRING);
      return EFI_ABORTED;
    }
    CapInfo->Flags |= Value64;
    DebugMsg (NULL, 0, 9, "Capsule Extend Flag", Value);
  }

  //
  // Read Capsule File name
  //
  Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FILE_NAME_STRING, 0, Value);
  if (Status == EFI_SUCCESS) {
    //
    // Get output file name
    //
    strcpy (CapInfo->CapName, Value);
  }

  //
  // Read the Capsule FileImage
  //
  Number = 0;
  for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_CAP; Index++) {
    if (CapInfo->CapFiles[Index][0] != '\0') {
      continue;
    }
    //
    // Read the capsule file name
    //
    Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Number++, Value);

    if (Status == EFI_SUCCESS) {
      //
      // Add the file
      //
      strcpy (CapInfo->CapFiles[Index], Value);
      DebugMsg (NULL, 0, 9, "Capsule component file", "the %uth file name is %s", (unsigned) Index, CapInfo->CapFiles[Index]);
    } else {
      break;
    }
  }

  if (Index == 0) {
    Warning (NULL, 0, 0, "Capsule components are not specified.", NULL);
  }

  return EFI_SUCCESS;
}

EFI_STATUS
GenerateCapImage (
  IN CHAR8                *InfFileImage,
  IN UINTN                InfFileSize,
  IN CHAR8                *CapFileName
  )
/*++

Routine Description:

  This is the main function which will be called from application to create UEFI Capsule image.

Arguments:

  InfFileImage   Buffer containing the INF file contents.
  InfFileSize    Size of the contents of the InfFileImage buffer.
  CapFileName    Requested name for the Cap file.

Returns:

  EFI_SUCCESS             Function completed successfully.
  EFI_OUT_OF_RESOURCES    Could not allocate required resources.
  EFI_ABORTED             Error encountered.
  EFI_INVALID_PARAMETER   A required parameter was NULL.

--*/
{
  UINT32                CapSize;
  UINT8                 *CapBuffer;
  EFI_CAPSULE_HEADER    *CapsuleHeader;
  MEMORY_FILE           InfMemoryFile;
  UINT32                FileSize;
  UINT32                Index;
  FILE                  *fpin, *fpout;
  EFI_STATUS            Status;

  if (InfFileImage != NULL) {
    //
    // Initialize file structures
    //
    InfMemoryFile.FileImage           = InfFileImage;
    InfMemoryFile.CurrentFilePointer  = InfFileImage;
    InfMemoryFile.Eof                 = InfFileImage + InfFileSize;

    //
    // Parse the Cap inf file for header information
    //
    Status = ParseCapInf (&InfMemoryFile, &mCapDataInfo);
    if (Status != EFI_SUCCESS) {
      return Status;
    }
  }

  if (mCapDataInfo.HeaderSize == 0) {
    //
    // make header size align 16 bytes.
    //
    mCapDataInfo.HeaderSize = sizeof (EFI_CAPSULE_HEADER);
    mCapDataInfo.HeaderSize = (mCapDataInfo.HeaderSize + 0xF) & ~0xF;
  }

  if (mCapDataInfo.HeaderSize < sizeof (EFI_CAPSULE_HEADER)) {
    Error (NULL, 0, 2000, "Invalid parameter", "The specified HeaderSize cannot be less than the size of EFI_CAPSULE_HEADER.");
    return EFI_INVALID_PARAMETER;
  }

  if (CapFileName == NULL && mCapDataInfo.CapName[0] != '\0') {
    CapFileName = mCapDataInfo.CapName;
  }

  if (CapFileName == NULL) {
    Error (NULL, 0, 2001, "Missing required argument", "Output Capsule file name");
    return EFI_INVALID_PARAMETER;
  }

  //
  // Set Default Capsule Guid value
  //
  if (CompareGuid (&mCapDataInfo.CapGuid, &mZeroGuid) == 0) {
    memcpy (&mCapDataInfo.CapGuid, &mDefaultCapsuleGuid, sizeof (EFI_GUID));
  }
  //
  // Calculate the size of capsule image.
  //
  Index    = 0;
  FileSize = 0;
  CapSize  = mCapDataInfo.HeaderSize;
  while (mCapDataInfo.CapFiles [Index][0] != '\0') {
    fpin = fopen (LongFilePath (mCapDataInfo.CapFiles[Index]), "rb");
    if (fpin == NULL) {
      Error (NULL, 0, 0001, "Error opening file", mCapDataInfo.CapFiles[Index]);
      return EFI_ABORTED;
    }
    FileSize  = _filelength (fileno (fpin));
    CapSize  += FileSize;
    fclose (fpin);
    Index ++;
  }

  //
  // Allocate buffer for capsule image.
  //
  CapBuffer = (UINT8 *) malloc (CapSize);
  if (CapBuffer == NULL) {
    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated for creating the capsule.");
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Initialize the capsule header to zero
  //
  memset (CapBuffer, 0, mCapDataInfo.HeaderSize);

  //
  // create capsule header and get capsule body
  //
  CapsuleHeader = (EFI_CAPSULE_HEADER *) CapBuffer;
  memcpy (&CapsuleHeader->CapsuleGuid, &mCapDataInfo.CapGuid, sizeof (EFI_GUID));
  CapsuleHeader->HeaderSize       = mCapDataInfo.HeaderSize;
  CapsuleHeader->Flags            = mCapDataInfo.Flags;
  CapsuleHeader->CapsuleImageSize = CapSize;

  Index    = 0;
  FileSize = 0;
  CapSize  = CapsuleHeader->HeaderSize;
  while (mCapDataInfo.CapFiles [Index][0] != '\0') {
    fpin = fopen (LongFilePath (mCapDataInfo.CapFiles[Index]), "rb");
    if (fpin == NULL) {
      Error (NULL, 0, 0001, "Error opening file", mCapDataInfo.CapFiles[Index]);
      free (CapBuffer);
      return EFI_ABORTED;
    }
    FileSize = _filelength (fileno (fpin));
    fread (CapBuffer + CapSize, 1, FileSize, fpin);
    fclose (fpin);
    Index ++;
    CapSize += FileSize;
  }

  //
  // write capsule data into the output file
  //
  fpout = fopen (LongFilePath (CapFileName), "wb");
  if (fpout == NULL) {
    Error (NULL, 0, 0001, "Error opening file", CapFileName);
    free (CapBuffer);
    return EFI_ABORTED;
  }

  fwrite (CapBuffer, 1, CapSize, fpout);
  fclose (fpout);
  free (CapBuffer);

  VerboseMsg ("The size of the generated capsule image is %u bytes", (unsigned) CapSize);

  return EFI_SUCCESS;
}
