/** @file
This file contains the internal functions required to generate a Firmware Volume.

Copyright (c) 2004 - 2017, 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>
This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

**/

//
// Include files
//

#if defined(__FreeBSD__)
#include <uuid.h>
#elif defined(__GNUC__)
#include <uuid/uuid.h>
#endif
#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"
#include "WinNtInclude.h"

#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION       0xEB000000
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION      0x14000000

BOOLEAN mArm = FALSE;
STATIC UINT32   MaxFfsAlignment = 0;
BOOLEAN VtfFileFlag = FALSE;

EFI_GUID  mEfiFirmwareVolumeTopFileGuid       = EFI_FFS_VOLUME_TOP_FILE_GUID;
EFI_GUID  mFileGuidArray [MAX_NUMBER_OF_FILES_IN_FV];
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
};

//
// This data array will be located at the base of the Firmware Volume Header (FVH)
// in the boot block.  It must not exceed 14 bytes of code.  The last 2 bytes
// will be used to keep the FVH checksum consistent.
// This code will be run in response to a starutp IPI for HT-enabled systems.
//
#define SIZEOF_STARTUP_DATA_ARRAY 0x10

UINT8                                   m128kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {
  //
  // EA D0 FF 00 F0               ; far jmp F000:FFD0
  // 0, 0, 0, 0, 0, 0, 0, 0, 0,   ; Reserved bytes
  // 0, 0                         ; Checksum Padding
  //
  0xEA,
  0xD0,
  0xFF,
  0x0,
  0xF0,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00
};

UINT8                                   m64kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = {
  //
  // EB CE                               ; jmp short ($-0x30)
  // ; (from offset 0x0 to offset 0xFFD0)
  // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes
  // 0, 0                                ; Checksum Padding
  //
  0xEB,
  0xCE,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00
};

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 alignmnet
    //
    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 Boundry
	  //
	  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                               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;

  //
  // 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));
  }

  if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && pImageContext->Machine == EFI_IMAGE_MACHINE_IA64) {
    //
    // Process IPF PLABEL to get the real address after the image has been rebased. 
    // PLABEL structure is got by AddressOfEntryPoint offset to ImageBuffer stored in pImageContext->Handle.
    //
    fprintf (FvMapFile, "EntryPoint=0x%010llx", (unsigned long long) (*(UINT64 *)((UINTN) pImageContext->Handle + (UINTN) AddressOfEntryPoint)));
  } else {
    fprintf (FvMapFile, "EntryPoint=0x%010llx", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));
  }
  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;
  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) {
        //
        // 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) {
      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, "Resouce", "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 Boundry
  //
  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;
  EFI_PHYSICAL_ADDRESS      *SecCoreEntryAddressPtr;
  INT32                     Ia32SecEntryOffset;
  UINT32                    *Ia32ResetAddressPtr;
  UINT8                     *BytePointer;
  UINT8                     *BytePointer2;
  UINT16                    *WordPointer;
  UINT16                    CheckSum;
  UINT32                    IpiVector;
  UINTN                     Index;
  EFI_FFS_FILE_STATE        SavedState;
  UINT64                    FitAddress;
  FIT_TABLE                 *FitTablePtr;
  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 == EFI_IMAGE_MACHINE_IA32 ||
        MachineType == EFI_IMAGE_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
  //
  Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile);
  if (EFI_ERROR (Status) || PeiCoreFile == NULL) {
    Error (NULL, 0, 3000, "Invalid", "could not find the PEI core in the FV.");
    return EFI_ABORTED;
  }
  //
  // 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 == EFI_IMAGE_MACHINE_IA64) {
    //
    // Update PEI_CORE address
    //
    //
    // Set the uncached attribute bit in the physical address
    //
    PeiCorePhysicalAddress |= 0x8000000000000000ULL;

    //
    // Check if address is aligned on a 16 byte boundary
    //
    if (PeiCorePhysicalAddress & 0xF) {
      Error (NULL, 0, 3000, "Invalid",
        "PEI_CORE entry point is not aligned on a 16 byte boundary, address specified is %llXh.",
        (unsigned long long) PeiCorePhysicalAddress
        );
      return EFI_ABORTED;
    }
    //
    // First Get the FIT table address
    //
    FitAddress  = (*(UINT64 *) (FvImage->Eof - IPF_FIT_ADDRESS_OFFSET)) & 0xFFFFFFFF;

    FitTablePtr = (FIT_TABLE *) (FvImage->FileImage + (FitAddress - FvInfo->BaseAddress));

    Status      = UpdatePeiCoreEntryInFit (FitTablePtr, PeiCorePhysicalAddress);

    if (!EFI_ERROR (Status)) {
      UpdateFitCheckSum (FitTablePtr);
    }

    //
    // Update SEC_CORE address
    //
    //
    // Set the uncached attribute bit in the physical address
    //
    SecCorePhysicalAddress |= 0x8000000000000000ULL;
    //
    // Check if address is aligned on a 16 byte boundary
    //
    if (SecCorePhysicalAddress & 0xF) {
      Error (NULL, 0, 3000, "Invalid",
        "SALE_ENTRY entry point is not aligned on a 16 byte boundary, address specified is %llXh.",
        (unsigned long long) SecCorePhysicalAddress
        );
      return EFI_ABORTED;
    }
    //
    // Update the address
    //
    SecCoreEntryAddressPtr  = (EFI_PHYSICAL_ADDRESS *) ((UINTN) FvImage->Eof - IPF_SALE_ENTRY_ADDRESS_OFFSET);
    *SecCoreEntryAddressPtr = SecCorePhysicalAddress;

  } else if (MachineType == EFI_IMAGE_MACHINE_IA32 || MachineType == EFI_IMAGE_MACHINE_X64) {
    //
    // 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);

    //
    // Update the Startup AP in the FVH header block ZeroVector region.
    //
    BytePointer   = (UINT8 *) ((UINTN) FvImage->FileImage);
    if (FvInfo->Size <= 0x10000) {
      BytePointer2 = m64kRecoveryStartupApDataArray;
    } else if (FvInfo->Size <= 0x20000) {
      BytePointer2 = m128kRecoveryStartupApDataArray;
    } else {
      BytePointer2 = m128kRecoveryStartupApDataArray;
      //
      // Find the position to place Ap reset vector, the offset
      // between the position and the end of Fvrecovery.fv file
      // should not exceed 128kB to prevent Ap reset vector from
      // outside legacy E and F segment
      //
      Status = FindApResetVectorPosition (FvImage, &BytePointer);
      if (EFI_ERROR (Status)) {
        Error (NULL, 0, 3000, "Invalid", "FV image does not have enough space to place AP reset vector. The FV image needs to reserve at least 4KB of unused space.");
        return EFI_ABORTED;
      }
    }

    for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY; Index++) {
      BytePointer[Index] = BytePointer2[Index];
    }
    //
    // Calculate the checksum
    //
    CheckSum              = 0x0000;
    WordPointer = (UINT16 *) (BytePointer);
    for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY / 2; Index++) {
      CheckSum = (UINT16) (CheckSum + ((UINT16) *WordPointer));
      WordPointer++;
    }
    //
    // Update the checksum field
    //
    WordPointer   = (UINT16 *) (BytePointer + SIZEOF_STARTUP_DATA_ARRAY - 2);
    *WordPointer  = (UINT16) (0x10000 - (UINT32) CheckSum);
    
    //
    // IpiVector at the 4k aligned address in the top 2 blocks in the PEI FV. 
    //
    IpiVector  = (UINT32) (FV_IMAGES_TOP_ADDRESS - ((UINTN) FvImage->Eof - (UINTN) BytePointer));
    DebugMsg (NULL, 0, 9, "Startup AP Vector address", "IpiVector at 0x%X", (unsigned) IpiVector);
    if ((IpiVector & 0xFFF) != 0) {
      Error (NULL, 0, 3000, "Invalid", "Startup AP Vector address are not 4K aligned, because the FV size is not 4K aligned");
      return EFI_ABORTED;
    }
    IpiVector  = IpiVector >> 12;
    IpiVector  = IpiVector & 0xFF;

    //
    // Write IPI Vector at Offset FvrecoveryFileSize - 8
    //
    Ia32ResetAddressPtr   = (UINT32 *) ((UINTN) FvImage->Eof - 8);
    *Ia32ResetAddressPtr  = IpiVector;
  } else if (MachineType == EFI_IMAGE_MACHINE_ARMT) {
    //
    // 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 == EFI_IMAGE_MACHINE_AARCH64) {
    //
    // 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 == EFI_IMAGE_MACHINE_ARMT) {
    // 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) {

      VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM SEC vector");

      // B SecEntryPoint - signed_immed_24 part +/-32MB offset
      // on ARM, the PC is always 8 ahead, so we're not really jumping from the base address, but from base address + 8
      ResetVector[0] = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress - 8) >> 2;

      if (ResetVector[0] > 0x00FFFFFF) {
        Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 32MB of the start of the FV");
        return EFI_ABORTED;
      }

      // Add opcode for an uncondional branch with no link. i.e.: " B SecEntryPoint"
      ResetVector[0] |= ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;

      // SWI handler movs   pc,lr. Just in case a debugger uses SWI
      ResetVector[2] = 0xE1B0F07E;

      // Place holder to support a common interrupt handler from ROM.
      // Currently not suppprted. 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 == EFI_IMAGE_MACHINE_AARCH64) {
    // 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 potensioally 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 uncondional 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
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 != EFI_IMAGE_MACHINE_IA32) && (*MachineType != EFI_IMAGE_MACHINE_IA64) && (*MachineType != EFI_IMAGE_MACHINE_X64) && (*MachineType != EFI_IMAGE_MACHINE_EBC) && 
      (*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64)) {
    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) {
      //
      // 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));
  }
  
  //
  // 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               Index;
  FILE                *fpin;
  UINTN               FfsFileSize;
  UINTN               FvExtendHeaderSize;
  UINT32              FfsAlignment;
  UINT32              FfsHeaderSize;
  EFI_FFS_FILE_HEADER FfsHeader;
  UINTN               VtfFileSize;
  
  FvExtendHeaderSize = 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);
  }

  //
  // Accumlate 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.
        //
        CurrentOffset = (CurrentOffset + FfsHeaderSize + sizeof(EFI_FFS_FILE_HEADER) + FfsAlignment - 1) & ~(FfsAlignment - 1);
        CurrentOffset -= FfsHeaderSize;
      }
	  }

    //
    // Add ffs file size
    //
    if (FvInfoPtr->SizeofFvFiles[Index] > FfsFileSize) {
    	CurrentOffset += FvInfoPtr->SizeofFvFiles[Index];
    } else {
    	CurrentOffset += FfsFileSize;
    }
    	
    //
    // Make next ffs file start at QWord Boundry
    //
    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;

  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 struture.
  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 procesing occurs
      if ((MachineType == EFI_IMAGE_MACHINE_ARMT) || (MachineType == EFI_IMAGE_MACHINE_AARCH64)) {
        VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
        mArm = 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 struture.
  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 == EFI_IMAGE_MACHINE_ARMT) ||
         (ImageContext.Machine == EFI_IMAGE_MACHINE_AARCH64) ) {
      mArm = 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", "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", "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", FileName);
      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 == EFI_IMAGE_MACHINE_ARMT) ||
         (ImageContext.Machine == EFI_IMAGE_MACHINE_AARCH64) ) {
      mArm = 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
FindApResetVectorPosition (
  IN  MEMORY_FILE  *FvImage,
  OUT UINT8        **Pointer
  )
/*++

Routine Description:

  Find the position in this FvImage to place Ap reset vector.

Arguments:

  FvImage       Memory file for the FV memory image.
  Pointer       Pointer to pointer to position.

Returns:

  EFI_NOT_FOUND   - No satisfied position is found.
  EFI_SUCCESS     - The suitable position is return.

--*/
{
  EFI_FFS_FILE_HEADER   *PadFile;
  UINT32                Index;
  EFI_STATUS            Status;
  UINT8                 *FixPoint;
  UINT32                FileLength;

  for (Index = 1; ;Index ++) {
    //
    // Find Pad File to add ApResetVector info
    //
    Status = GetFileByType (EFI_FV_FILETYPE_FFS_PAD, Index, &PadFile);
    if (EFI_ERROR (Status) || (PadFile == NULL)) {
      //
      // No Pad file to be found.
      //
      break;
    }
    //
    // Get Pad file size.
    //
    FileLength = GetFfsFileLength(PadFile);
    FileLength = (FileLength + EFI_FFS_FILE_HEADER_ALIGNMENT - 1) & ~(EFI_FFS_FILE_HEADER_ALIGNMENT - 1); 
    //
    // FixPoint must be align on 0x1000 relative to FvImage Header
    //
    FixPoint = (UINT8*) PadFile + GetFfsHeaderLength(PadFile);
    FixPoint = FixPoint + 0x1000 - (((UINTN) FixPoint - (UINTN) FvImage->FileImage) & 0xFFF);
    //
    // FixPoint be larger at the last place of one fv image.
    //
    while (((UINTN) FixPoint + SIZEOF_STARTUP_DATA_ARRAY - (UINTN) PadFile) <= FileLength) {
      FixPoint += 0x1000;
    }
    FixPoint -= 0x1000;
    
    if ((UINTN) FixPoint < ((UINTN) PadFile + GetFfsHeaderLength(PadFile))) {
      //
      // No alignment FixPoint in this Pad File.
      //
      continue;
    }

    if ((UINTN) FvImage->Eof - (UINTN)FixPoint <= 0x20000) {    
      //
      // Find the position to place ApResetVector
      //
      *Pointer = FixPoint;
      return EFI_SUCCESS;
    }
  }
  
  return EFI_NOT_FOUND;
}

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;
}
