summaryrefslogtreecommitdiff
path: root/BaseTools/Source/C/GenFfs/GenFfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/C/GenFfs/GenFfs.c')
-rw-r--r--BaseTools/Source/C/GenFfs/GenFfs.c962
1 files changed, 0 insertions, 962 deletions
diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c
deleted file mode 100644
index c5d657bd09..0000000000
--- a/BaseTools/Source/C/GenFfs/GenFfs.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/** @file
-This file contains functions required to generate a Firmware File System file.
-
-Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <Common/UefiBaseTypes.h>
-#include <Common/PiFirmwareFile.h>
-#include <IndustryStandard/PeImage.h>
-#include <Guid/FfsSectionAlignmentPadding.h>
-
-#include "CommonLib.h"
-#include "ParseInf.h"
-#include "EfiUtilityMsgs.h"
-
-#define UTILITY_NAME "GenFfs"
-#define UTILITY_MAJOR_VERSION 0
-#define UTILITY_MINOR_VERSION 1
-
-STATIC CHAR8 *mFfsFileType[] = {
- NULL, // 0x00
- "EFI_FV_FILETYPE_RAW", // 0x01
- "EFI_FV_FILETYPE_FREEFORM", // 0x02
- "EFI_FV_FILETYPE_SECURITY_CORE", // 0x03
- "EFI_FV_FILETYPE_PEI_CORE", // 0x04
- "EFI_FV_FILETYPE_DXE_CORE", // 0x05
- "EFI_FV_FILETYPE_PEIM", // 0x06
- "EFI_FV_FILETYPE_DRIVER", // 0x07
- "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER", // 0x08
- "EFI_FV_FILETYPE_APPLICATION", // 0x09
- "EFI_FV_FILETYPE_SMM", // 0x0A
- "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE",// 0x0B
- "EFI_FV_FILETYPE_COMBINED_SMM_DXE", // 0x0C
- "EFI_FV_FILETYPE_SMM_CORE" // 0x0D
- };
-
-STATIC CHAR8 *mAlignName[] = {
- "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
- "1K", "2K", "4K", "8K", "16K", "32K", "64K"
- };
-
-STATIC CHAR8 *mFfsValidAlignName[] = {
- "8", "16", "128", "512", "1K", "4K", "32K", "64K"
- };
-
-STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536};
-
-STATIC EFI_GUID mZeroGuid = {0};
-
-STATIC EFI_GUID mEfiFfsSectionAlignmentPaddingGuid = EFI_FFS_SECTION_ALIGNMENT_PADDING_GUID;
-
-STATIC
-VOID
-Version (
- VOID
- )
-/*++
-
-Routine Description:
-
- Print out version information for this utility.
-
-Arguments:
-
- None
-
-Returns:
-
- None
-
---*/
-{
- fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
-}
-
-STATIC
-VOID
-Usage (
- VOID
- )
-/*++
-
-Routine Description:
-
- Print Error / Help message.
-
-Arguments:
-
- VOID
-
-Returns:
-
- None
-
---*/
-{
- //
- // Summary usage
- //
- fprintf (stdout, "\nUsage: %s [options]\n\n", UTILITY_NAME);
-
- //
- // Copyright declaration
- //
- fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");
-
- //
- // Details Option
- //
- fprintf (stdout, "Options:\n");
- fprintf (stdout, " -o FileName, --outputfile FileName\n\
- File is FFS file to be created.\n");
- fprintf (stdout, " -t Type, --filetype Type\n\
- Type is one FV file type defined in PI spec, which is\n\
- EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FREEFORM,\n\
- EFI_FV_FILETYPE_SECURITY_CORE, EFI_FV_FILETYPE_PEIM,\n\
- EFI_FV_FILETYPE_PEI_CORE, EFI_FV_FILETYPE_DXE_CORE,\n\
- EFI_FV_FILETYPE_DRIVER, EFI_FV_FILETYPE_APPLICATION,\n\
- EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,\n\
- EFI_FV_FILETYPE_SMM, EFI_FV_FILETYPE_SMM_CORE,\n\
- EFI_FV_FILETYPE_COMBINED_SMM_DXE, \n\
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE.\n");
- fprintf (stdout, " -g FileGuid, --fileguid FileGuid\n\
- FileGuid is one module guid.\n\
- Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
- fprintf (stdout, " -x, --fixed Indicates that the file may not be moved\n\
- from its present location.\n");
- fprintf (stdout, " -s, --checksum Indicates to calculate file checksum.\n");
- fprintf (stdout, " -a FileAlign, --align FileAlign\n\
- FileAlign points to file alignment, which only support\n\
- the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n");
- fprintf (stdout, " -i SectionFile, --sectionfile SectionFile\n\
- Section file will be contained in this FFS file.\n");
- fprintf (stdout, " -n SectionAlign, --sectionalign SectionAlign\n\
- SectionAlign points to section alignment, which support\n\
- the alignment scope 1~64K. It is specified together\n\
- with sectionfile to point its alignment in FFS file.\n");
- fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
- fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
- fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");
- fprintf (stdout, " --version Show program's version number and exit.\n");
- fprintf (stdout, " -h, --help Show this help message and exit.\n");
-}
-
-STATIC
-EFI_STATUS
-StringtoAlignment (
- IN CHAR8 *AlignBuffer,
- OUT UINT32 *AlignNumber
- )
-/*++
-
-Routine Description:
-
- Converts Align String to align value (1~64K).
-
-Arguments:
-
- AlignBuffer - Pointer to Align string.
- AlignNumber - Pointer to Align value.
-
-Returns:
-
- EFI_SUCCESS Successfully convert align string to align value.
- EFI_INVALID_PARAMETER Align string is invalid or align value is not in scope.
-
---*/
-{
- UINT32 Index = 0;
- //
- // Check AlignBuffer
- //
- if (AlignBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- for (Index = 0; Index < sizeof (mAlignName) / sizeof (CHAR8 *); Index ++) {
- if (stricmp (AlignBuffer, mAlignName [Index]) == 0) {
- *AlignNumber = 1 << Index;
- return EFI_SUCCESS;
- }
- }
- return EFI_INVALID_PARAMETER;
-}
-
-STATIC
-UINT8
-StringToType (
- IN CHAR8 *String
- )
-/*++
-
-Routine Description:
-
- Converts File Type String to value. EFI_FV_FILETYPE_ALL indicates that an
- unrecognized file type was specified.
-
-Arguments:
-
- String - File type string
-
-Returns:
-
- File Type Value
-
---*/
-{
- UINT8 Index = 0;
-
- if (String == NULL) {
- return EFI_FV_FILETYPE_ALL;
- }
-
- for (Index = 0; Index < sizeof (mFfsFileType) / sizeof (CHAR8 *); Index ++) {
- if (mFfsFileType [Index] != NULL && (stricmp (String, mFfsFileType [Index]) == 0)) {
- return Index;
- }
- }
- return EFI_FV_FILETYPE_ALL;
-}
-
-STATIC
-EFI_STATUS
-GetSectionContents (
- IN CHAR8 **InputFileName,
- IN UINT32 *InputFileAlign,
- IN UINT32 InputFileNum,
- IN EFI_FFS_FILE_ATTRIBUTES FfsAttrib,
- OUT UINT8 *FileBuffer,
- OUT UINT32 *BufferLength,
- OUT UINT32 *MaxAlignment,
- OUT UINT8 *PESectionNum
- )
-/*++
-
-Routine Description:
-
- Get the contents of all section files specified in InputFileName
- into FileBuffer.
-
-Arguments:
-
- InputFileName - Name of the input file.
-
- InputFileAlign - Alignment required by the input file data.
-
- InputFileNum - Number of input files. Should be at least 1.
-
- FileBuffer - Output buffer to contain data
-
- BufferLength - On input, this is size of the FileBuffer.
- On output, this is the actual length of the data.
-
- MaxAlignment - The max alignment required by all the input file datas.
-
- PeSectionNum - Calculate the number of Pe/Te Section in this FFS file.
-
-Returns:
-
- EFI_SUCCESS on successful return
- EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.
- EFI_ABORTED if unable to open input file.
- EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.
---*/
-{
- UINT32 Size;
- UINT32 Offset;
- UINT32 FileSize;
- UINT32 Index;
- FILE *InFile;
- EFI_FREEFORM_SUBTYPE_GUID_SECTION *SectHeader;
- EFI_COMMON_SECTION_HEADER2 TempSectHeader;
- EFI_TE_IMAGE_HEADER TeHeader;
- UINT32 TeOffset;
- EFI_GUID_DEFINED_SECTION GuidSectHeader;
- EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;
- UINT32 HeaderSize;
- UINT32 MaxEncounteredAlignment;
-
- Size = 0;
- Offset = 0;
- TeOffset = 0;
- MaxEncounteredAlignment = 1;
-
- //
- // Go through our array of file names and copy their contents
- // to the output buffer.
- //
- for (Index = 0; Index < InputFileNum; Index++) {
- //
- // make sure section ends on a DWORD boundary
- //
- while ((Size & 0x03) != 0) {
- Size++;
- }
-
- //
- // Open file and read contents
- //
- InFile = fopen (LongFilePath (InputFileName[Index]), "rb");
- if (InFile == NULL) {
- Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);
- return EFI_ABORTED;
- }
-
- fseek (InFile, 0, SEEK_END);
- FileSize = ftell (InFile);
- fseek (InFile, 0, SEEK_SET);
- DebugMsg (NULL, 0, 9, "Input section files",
- "the input section name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize);
-
- //
- // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
- //
- TeOffset = 0;
- if (FileSize >= MAX_FFS_SIZE) {
- HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
- } else {
- HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
- }
- fread (&TempSectHeader, 1, HeaderSize, InFile);
- if (TempSectHeader.Type == EFI_SECTION_TE) {
- (*PESectionNum) ++;
- fread (&TeHeader, 1, sizeof (TeHeader), InFile);
- if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
- TeOffset = TeHeader.StrippedSize - sizeof (TeHeader);
- }
- } else if (TempSectHeader.Type == EFI_SECTION_PE32) {
- (*PESectionNum) ++;
- } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {
- fseek (InFile, 0, SEEK_SET);
- if (FileSize >= MAX_SECTION_SIZE) {
- fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);
- if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
- HeaderSize = GuidSectHeader2.DataOffset;
- }
- } else {
- fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
- if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
- HeaderSize = GuidSectHeader.DataOffset;
- }
- }
- (*PESectionNum) ++;
- } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION ||
- TempSectHeader.Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
- //
- // for the encapsulated section, assume it contains Pe/Te section
- //
- (*PESectionNum) ++;
- }
-
- fseek (InFile, 0, SEEK_SET);
-
- //
- // Revert TeOffset to the converse value relative to Alignment
- // This is to assure the original PeImage Header at Alignment.
- //
- if ((TeOffset != 0) && (InputFileAlign [Index] != 0)) {
- TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);
- TeOffset = TeOffset % InputFileAlign [Index];
- }
-
- //
- // make sure section data meet its alignment requirement by adding one pad section.
- // But the different sections have the different section header. Necessary or not?
- // Based on section type to adjust offset? Todo
- //
- if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {
- Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);
- Offset = Offset - Size - HeaderSize - TeOffset;
-
- if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {
- //
- // The maximal alignment is 64K, the raw section size must be less than 0xffffff
- //
- memset (FileBuffer + Size, 0, Offset);
- SectHeader = (EFI_FREEFORM_SUBTYPE_GUID_SECTION *) (FileBuffer + Size);
- SectHeader->CommonHeader.Size[0] = (UINT8) (Offset & 0xff);
- SectHeader->CommonHeader.Size[1] = (UINT8) ((Offset & 0xff00) >> 8);
- SectHeader->CommonHeader.Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);
-
- //
- // Only add a special reducible padding section if
- // - this FFS has the FFS_ATTRIB_FIXED attribute,
- // - none of the preceding sections have alignment requirements,
- // - the size of the padding is sufficient for the
- // EFI_SECTION_FREEFORM_SUBTYPE_GUID header.
- //
- if ((FfsAttrib & FFS_ATTRIB_FIXED) != 0 &&
- MaxEncounteredAlignment <= 1 &&
- Offset >= sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION)) {
- SectHeader->CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID;
- SectHeader->SubTypeGuid = mEfiFfsSectionAlignmentPaddingGuid;
- } else {
- SectHeader->CommonHeader.Type = EFI_SECTION_RAW;
- }
- }
- DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment",
- "Pad Raw section size is %u", (unsigned) Offset);
-
- Size = Size + Offset;
- }
-
- //
- // Get the Max alignment of all input file datas
- //
- if (MaxEncounteredAlignment < InputFileAlign [Index]) {
- MaxEncounteredAlignment = InputFileAlign [Index];
- }
-
- //
- // Now read the contents of the file into the buffer
- // Buffer must be enough to contain the file content.
- //
- if ((FileSize > 0) && (FileBuffer != NULL) && ((Size + FileSize) <= *BufferLength)) {
- if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {
- Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);
- fclose (InFile);
- return EFI_ABORTED;
- }
- }
-
- fclose (InFile);
- Size += FileSize;
- }
-
- *MaxAlignment = MaxEncounteredAlignment;
-
- //
- // Set the actual length of the data.
- //
- if (Size > *BufferLength) {
- *BufferLength = Size;
- return EFI_BUFFER_TOO_SMALL;
- } else {
- *BufferLength = Size;
- return EFI_SUCCESS;
- }
-}
-
-int
-main (
- int argc,
- CHAR8 *argv[]
- )
-/*++
-
-Routine Description:
-
- Main function.
-
-Arguments:
-
- argc - Number of command line parameters.
- argv - Array of pointers to parameter strings.
-
-Returns:
- STATUS_SUCCESS - Utility exits successfully.
- STATUS_ERROR - Some error occurred during execution.
-
---*/
-{
- EFI_STATUS Status;
- EFI_FFS_FILE_ATTRIBUTES FfsAttrib;
- UINT32 FfsAlign;
- EFI_FV_FILETYPE FfsFiletype;
- CHAR8 *OutputFileName;
- EFI_GUID FileGuid = {0};
- UINT32 InputFileNum;
- UINT32 *InputFileAlign;
- CHAR8 **InputFileName;
- UINT8 *FileBuffer;
- UINT32 FileSize;
- UINT32 MaxAlignment;
- EFI_FFS_FILE_HEADER2 FfsFileHeader;
- FILE *FfsFile;
- UINT32 Index;
- UINT64 LogLevel;
- UINT8 PeSectionNum;
- UINT32 HeaderSize;
-
- //
- // Init local variables
- //
- LogLevel = 0;
- Index = 0;
- FfsAttrib = 0;
- FfsAlign = 0;
- FfsFiletype = EFI_FV_FILETYPE_ALL;
- OutputFileName = NULL;
- InputFileNum = 0;
- InputFileName = NULL;
- InputFileAlign = NULL;
- FileBuffer = NULL;
- FileSize = 0;
- MaxAlignment = 1;
- FfsFile = NULL;
- Status = EFI_SUCCESS;
- PeSectionNum = 0;
-
- SetUtilityName (UTILITY_NAME);
-
- if (argc == 1) {
- Error (NULL, 0, 1001, "Missing options", "no options input");
- Usage ();
- return STATUS_ERROR;
- }
-
- //
- // Parse command line
- //
- argc --;
- argv ++;
-
- if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
- Version ();
- Usage ();
- return STATUS_SUCCESS;
- }
-
- if (stricmp (argv[0], "--version") == 0) {
- Version ();
- return STATUS_SUCCESS;
- }
-
- while (argc > 0) {
- if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--filetype") == 0)) {
- if (argv[1] == NULL || argv[1][0] == '-') {
- Error (NULL, 0, 1003, "Invalid option value", "file type is missing for -t option");
- goto Finish;
- }
- FfsFiletype = StringToType (argv[1]);
- if (FfsFiletype == EFI_FV_FILETYPE_ALL) {
- Error (NULL, 0, 1003, "Invalid option value", "%s is not a valid file type", argv[1]);
- goto Finish;
- }
- argc -= 2;
- argv += 2;
- continue;
- }
-
- if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {
- if (argv[1] == NULL || argv[1][0] == '-') {
- Error (NULL, 0, 1003, "Invalid option value", "Output file is missing for -o option");
- goto Finish;
- }
- OutputFileName = argv[1];
- argc -= 2;
- argv += 2;
- continue;
- }
-
- if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--fileguid") == 0)) {
- Status = StringToGuid (argv[1], &FileGuid);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
- goto Finish;
- }
- argc -= 2;
- argv += 2;
- continue;
- }
-
- if ((stricmp (argv[0], "-x") == 0) || (stricmp (argv[0], "--fixed") == 0)) {
- FfsAttrib |= FFS_ATTRIB_FIXED;
- argc -= 1;
- argv += 1;
- continue;
- }
-
- if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--checksum") == 0)) {
- FfsAttrib |= FFS_ATTRIB_CHECKSUM;
- argc -= 1;
- argv += 1;
- continue;
- }
-
- if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) {
- if (argv[1] == NULL || argv[1][0] == '-') {
- Error (NULL, 0, 1003, "Invalid option value", "Align value is missing for -a option");
- goto Finish;
- }
- for (Index = 0; Index < sizeof (mFfsValidAlignName) / sizeof (CHAR8 *); Index ++) {
- if (stricmp (argv[1], mFfsValidAlignName[Index]) == 0) {
- break;
- }
- }
- if (Index == sizeof (mFfsValidAlignName) / sizeof (CHAR8 *)) {
- if ((stricmp (argv[1], "1") == 0) || (stricmp (argv[1], "2") == 0) || (stricmp (argv[1], "4") == 0)) {
- //
- // 1, 2, 4 byte alignment same to 8 byte alignment
- //
- Index = 0;
- } else {
- Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
- goto Finish;
- }
- }
- FfsAlign = Index;
- argc -= 2;
- argv += 2;
- continue;
- }
-
- if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--sectionfile") == 0)) {
- //
- // Get Input file name and its alignment
- //
- if (argv[1] == NULL || argv[1][0] == '-') {
- Error (NULL, 0, 1003, "Invalid option value", "input section file is missing for -i option");
- goto Finish;
- }
-
- //
- // Allocate Input file name buffer and its alignment buffer.
- //
- if ((InputFileNum == 0) && (InputFileName == NULL)) {
- InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));
- if (InputFileName == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return STATUS_ERROR;
- }
- memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
-
- InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
- if (InputFileAlign == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- free (InputFileName);
- return STATUS_ERROR;
- }
- memset (InputFileAlign, 0, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));
- } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {
- //
- // InputFileName and alignment buffer too small, need to realloc
- //
- InputFileName = (CHAR8 **) realloc (
- InputFileName,
- (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
- );
-
- if (InputFileName == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- free (InputFileAlign);
- return STATUS_ERROR;
- }
- memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));
-
- InputFileAlign = (UINT32 *) realloc (
- InputFileAlign,
- (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)
- );
-
- if (InputFileAlign == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- free (InputFileName);
- return STATUS_ERROR;
- }
- memset (&(InputFileAlign[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));
- }
-
- InputFileName[InputFileNum] = argv[1];
- argc -= 2;
- argv += 2;
-
- if (argc <= 0) {
- InputFileNum ++;
- break;
- }
-
- //
- // Section File alignment requirement
- //
- if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {
- Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum]));
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
- goto Finish;
- }
- argc -= 2;
- argv += 2;
- }
- InputFileNum ++;
- continue;
- }
-
- if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {
- Error (NULL, 0, 1000, "Unknown option", "SectionAlign option must be specified with section file.");
- goto Finish;
- }
-
- if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
- SetPrintLevel (VERBOSE_LOG_LEVEL);
- VerboseMsg ("Verbose output Mode Set!");
- argc --;
- argv ++;
- continue;
- }
-
- if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
- SetPrintLevel (KEY_LOG_LEVEL);
- KeyMsg ("Quiet output Mode Set!");
- argc --;
- argv ++;
- continue;
- }
-
- if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
- Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
- goto Finish;
- }
- if (LogLevel > 9) {
- Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
- goto Finish;
- }
- SetPrintLevel (LogLevel);
- DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
- argc -= 2;
- argv += 2;
- continue;
- }
-
- Error (NULL, 0, 1000, "Unknown option", argv[0]);
- goto Finish;
- }
-
- VerboseMsg ("%s tool start.", UTILITY_NAME);
-
- //
- // Check the complete input parameters.
- //
- if (FfsFiletype == EFI_FV_FILETYPE_ALL) {
- Error (NULL, 0, 1001, "Missing option", "filetype");
- goto Finish;
- }
-
- if (CompareGuid (&FileGuid, &mZeroGuid) == 0) {
- Error (NULL, 0, 1001, "Missing option", "fileguid");
- goto Finish;
- }
-
- if (InputFileNum == 0) {
- Error (NULL, 0, 1001, "Missing option", "Input files");
- goto Finish;
- }
-
- //
- // Output input parameter information
- //
- VerboseMsg ("Fv File type is %s", mFfsFileType [FfsFiletype]);
- VerboseMsg ("Output file name is %s", OutputFileName);
- VerboseMsg ("FFS File Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- (unsigned) FileGuid.Data1,
- FileGuid.Data2,
- FileGuid.Data3,
- FileGuid.Data4[0],
- FileGuid.Data4[1],
- FileGuid.Data4[2],
- FileGuid.Data4[3],
- FileGuid.Data4[4],
- FileGuid.Data4[5],
- FileGuid.Data4[6],
- FileGuid.Data4[7]);
- if ((FfsAttrib & FFS_ATTRIB_FIXED) != 0) {
- VerboseMsg ("FFS File has the fixed file attribute");
- }
- if ((FfsAttrib & FFS_ATTRIB_CHECKSUM) != 0) {
- VerboseMsg ("FFS File requires the checksum of the whole file");
- }
- VerboseMsg ("FFS file alignment is %s", mFfsValidAlignName[FfsAlign]);
- for (Index = 0; Index < InputFileNum; Index ++) {
- if (InputFileAlign[Index] == 0) {
- //
- // Minimum alignment is 1 byte.
- //
- InputFileAlign[Index] = 1;
- }
- VerboseMsg ("the %dth input section name is %s and section alignment is %u", Index, InputFileName[Index], (unsigned) InputFileAlign[Index]);
- }
-
- //
- // Calculate the size of all input section files.
- //
- Status = GetSectionContents (
- InputFileName,
- InputFileAlign,
- InputFileNum,
- FfsAttrib,
- FileBuffer,
- &FileSize,
- &MaxAlignment,
- &PeSectionNum
- );
-
- if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE ||
- FfsFiletype == EFI_FV_FILETYPE_PEI_CORE ||
- FfsFiletype == EFI_FV_FILETYPE_DXE_CORE) && (PeSectionNum != 1)) {
- Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %u Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum);
- goto Finish;
- }
-
- if ((FfsFiletype == EFI_FV_FILETYPE_PEIM ||
- FfsFiletype == EFI_FV_FILETYPE_DRIVER ||
- FfsFiletype == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER ||
- FfsFiletype == EFI_FV_FILETYPE_APPLICATION) && (PeSectionNum < 1)) {
- Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have at least one Pe or Te section, but no Pe/Te section is input", mFfsFileType [FfsFiletype]);
- goto Finish;
- }
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FileBuffer = (UINT8 *) malloc (FileSize);
- if (FileBuffer == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- goto Finish;
- }
- memset (FileBuffer, 0, FileSize);
-
- //
- // read all input file contents into a buffer
- //
- Status = GetSectionContents (
- InputFileName,
- InputFileAlign,
- InputFileNum,
- FfsAttrib,
- FileBuffer,
- &FileSize,
- &MaxAlignment,
- &PeSectionNum
- );
- }
-
- if (EFI_ERROR (Status)) {
- goto Finish;
- }
-
- if (FileBuffer == NULL && FileSize != 0) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- goto Finish;
- }
-
- //
- // Create Ffs file header.
- //
- memset (&FfsFileHeader, 0, sizeof (EFI_FFS_FILE_HEADER2));
- memcpy (&FfsFileHeader.Name, &FileGuid, sizeof (EFI_GUID));
- FfsFileHeader.Type = FfsFiletype;
- //
- // Update FFS Alignment based on the max alignment required by input section files
- //
- VerboseMsg ("the max alignment of all input sections is %u", (unsigned) MaxAlignment);
- for (Index = 0; Index < sizeof (mFfsValidAlign) / sizeof (UINT32) - 1; Index ++) {
- if ((MaxAlignment > mFfsValidAlign [Index]) && (MaxAlignment <= mFfsValidAlign [Index + 1])) {
- break;
- }
- }
- if (FfsAlign < Index) {
- FfsAlign = Index;
- }
- VerboseMsg ("the alignment of the generated FFS file is %u", (unsigned) mFfsValidAlign [FfsAlign + 1]);
-
- //
- // Now FileSize includes the EFI_FFS_FILE_HEADER
- //
- if (FileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
- HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
- FileSize += sizeof (EFI_FFS_FILE_HEADER2);
- FfsFileHeader.ExtendedSize = FileSize;
- memset(FfsFileHeader.Size, 0, sizeof (UINT8) * 3);
- FfsAttrib |= FFS_ATTRIB_LARGE_FILE;
- } else {
- HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
- FileSize += sizeof (EFI_FFS_FILE_HEADER);
- FfsFileHeader.Size[0] = (UINT8) (FileSize & 0xFF);
- FfsFileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8);
- FfsFileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16);
- }
- VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);
-
- FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
-
- //
- // Fill in checksums and state, these must be zero for checksumming
- //
- // FileHeader.IntegrityCheck.Checksum.Header = 0;
- // FileHeader.IntegrityCheck.Checksum.File = 0;
- // FileHeader.State = 0;
- //
- FfsFileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (
- (UINT8 *) &FfsFileHeader,
- HeaderSize
- );
-
- if (FfsFileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {
- //
- // Ffs header checksum = zero, so only need to calculate ffs body.
- //
- FfsFileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (
- FileBuffer,
- FileSize - HeaderSize
- );
- } else {
- FfsFileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
- }
-
- FfsFileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
-
- //
- // Open output file to write ffs data.
- //
- if (OutputFileName != NULL) {
- remove(OutputFileName);
- FfsFile = fopen (LongFilePath (OutputFileName), "wb");
- if (FfsFile == NULL) {
- Error (NULL, 0, 0001, "Error opening file", OutputFileName);
- goto Finish;
- }
- //
- // write header
- //
- fwrite (&FfsFileHeader, 1, HeaderSize, FfsFile);
- //
- // write data
- //
- if (FileBuffer != NULL) {
- fwrite (FileBuffer, 1, FileSize - HeaderSize, FfsFile);
- }
-
- fclose (FfsFile);
- }
-
-Finish:
- if (InputFileName != NULL) {
- free (InputFileName);
- }
- if (InputFileAlign != NULL) {
- free (InputFileAlign);
- }
- if (FileBuffer != NULL) {
- free (FileBuffer);
- }
- //
- // If any errors were reported via the standard error reporting
- // routines, then the status has been saved. Get the value and
- // return it to the caller.
- //
- VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
-
- return GetUtilityStatus ();
-}