diff options
| author | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
|---|---|---|
| committer | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
| commit | 7e2ccccace24636f29ddc210b94606abd4c7e42b (patch) | |
| tree | 545d43ea12671048956cafeb12303e84d601e571 /BaseTools/Source/C/VolInfo | |
| parent | 27b044605cd5f6b33a3d231576003850b3fe305b (diff) | |
| download | edk2-trunk.tar.xz | |
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'BaseTools/Source/C/VolInfo')
| -rw-r--r-- | BaseTools/Source/C/VolInfo/GNUmakefile | 34 | ||||
| -rw-r--r-- | BaseTools/Source/C/VolInfo/Makefile | 32 | ||||
| -rw-r--r-- | BaseTools/Source/C/VolInfo/VolInfo.c | 5048 | ||||
| -rw-r--r-- | BaseTools/Source/C/VolInfo/VolInfo.h | 62 |
4 files changed, 2588 insertions, 2588 deletions
diff --git a/BaseTools/Source/C/VolInfo/GNUmakefile b/BaseTools/Source/C/VolInfo/GNUmakefile index 9795b28add..8d6fa7bc1d 100644 --- a/BaseTools/Source/C/VolInfo/GNUmakefile +++ b/BaseTools/Source/C/VolInfo/GNUmakefile @@ -1,17 +1,17 @@ -## @file
-# GNU/Linux makefile for 'VolInfo' module build.
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-MAKEROOT ?= ..
-
-APPNAME = VolInfo
-
-OBJECTS = VolInfo.o
-
-include $(MAKEROOT)/Makefiles/app.makefile
-
-LIBS = -lCommon
-
-
+## @file +# GNU/Linux makefile for 'VolInfo' module build. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +MAKEROOT ?= .. + +APPNAME = VolInfo + +OBJECTS = VolInfo.o + +include $(MAKEROOT)/Makefiles/app.makefile + +LIBS = -lCommon + + diff --git a/BaseTools/Source/C/VolInfo/Makefile b/BaseTools/Source/C/VolInfo/Makefile index 47f6d35ea2..09611c6d4b 100644 --- a/BaseTools/Source/C/VolInfo/Makefile +++ b/BaseTools/Source/C/VolInfo/Makefile @@ -1,16 +1,16 @@ -## @file
-# Windows makefile for 'VolInfo' module build.
-#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-!INCLUDE ..\Makefiles\ms.common
-
-APPNAME = VolInfo
-
-LIBS = $(LIB_PATH)\Common.lib
-
-OBJECTS = VolInfo.obj
-
-!INCLUDE ..\Makefiles\ms.app
-
+## @file +# Windows makefile for 'VolInfo' module build. +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +!INCLUDE ..\Makefiles\ms.common + +APPNAME = VolInfo + +LIBS = $(LIB_PATH)\Common.lib + +OBJECTS = VolInfo.obj + +!INCLUDE ..\Makefiles\ms.app + diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index 428011ca04..bf675d9309 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -1,2524 +1,2524 @@ -/** @file
-The tool dumps the contents of a firmware volume
-
-Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
-Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com><BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-#ifdef __GNUC__
-#include <unistd.h>
-#else
-#include <direct.h>
-#endif
-
-#include <FvLib.h>
-#include <Common/UefiBaseTypes.h>
-#include <Common/UefiCapsule.h>
-#include <Common/PiFirmwareFile.h>
-#include <Common/PiFirmwareVolume.h>
-#include <Guid/PiFirmwareFileSystem.h>
-#include <IndustryStandard/PeImage.h>
-#include <Protocol/GuidedSectionExtraction.h>
-
-#include "Compress.h"
-#include "Decompress.h"
-#include "VolInfo.h"
-#include "CommonLib.h"
-#include "EfiUtilityMsgs.h"
-#include "FirmwareVolumeBufferLib.h"
-#include "OsPath.h"
-#include "ParseGuidedSectionTools.h"
-#include "StringFuncs.h"
-#include "ParseInf.h"
-#include "PeCoffLib.h"
-
-//
-// Utility global variables
-//
-
-EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
-EFI_GUID gPeiAprioriFileNameGuid = { 0x1b45cc0a, 0x156a, 0x428a, { 0XAF, 0x62, 0x49, 0x86, 0x4d, 0xa0, 0xe6, 0xe6 }};
-EFI_GUID gAprioriGuid = { 0xFC510EE7, 0xFFDC, 0x11D4, { 0xBD, 0x41, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 }};
-
-#define UTILITY_MAJOR_VERSION 1
-#define UTILITY_MINOR_VERSION 0
-
-#define UTILITY_NAME "VolInfo"
-
-#define EFI_SECTION_ERROR EFIERR (100)
-
-//
-// Structure to keep a list of guid-to-basenames
-//
-typedef struct _GUID_TO_BASENAME {
- struct _GUID_TO_BASENAME *Next;
- INT8 Guid[PRINTED_GUID_BUFFER_SIZE];
- INT8 BaseName[MAX_LINE_LEN];
-} GUID_TO_BASENAME;
-
-static GUID_TO_BASENAME *mGuidBaseNameList = NULL;
-
-//
-// Store GUIDed Section guid->tool mapping
-//
-EFI_HANDLE mParsedGuidedSectionTools = NULL;
-
-CHAR8* mUtilityFilename = NULL;
-
-BOOLEAN EnableHash = FALSE;
-CHAR8 *OpenSslPath = NULL;
-
-EFI_STATUS
-ParseGuidBaseNameFile (
- CHAR8 *FileName
- );
-
-EFI_STATUS
-FreeGuidBaseNameList (
- VOID
- );
-
-EFI_STATUS
-PrintGuidName (
- IN UINT8 *GuidStr
- );
-
-EFI_STATUS
-ParseSection (
- IN UINT8 *SectionBuffer,
- IN UINT32 BufferLength
- );
-
-EFI_STATUS
-DumpDepexSection (
- IN UINT8 *Ptr,
- IN UINT32 SectionLength
- );
-
-STATIC
-EFI_STATUS
-ReadHeader (
- IN FILE *InputFile,
- OUT UINT32 *FvSize,
- OUT BOOLEAN *ErasePolarity
- );
-
-STATIC
-EFI_STATUS
-PrintAprioriFile (
- EFI_FFS_FILE_HEADER *FileHeader
- );
-
-STATIC
-EFI_STATUS
-PrintFileInfo (
- EFI_FIRMWARE_VOLUME_HEADER *FvImage,
- EFI_FFS_FILE_HEADER *FileHeader,
- BOOLEAN ErasePolarity
- );
-
-static
-EFI_STATUS
-PrintFvInfo (
- IN VOID *Fv,
- IN BOOLEAN IsChildFv
- );
-
-static
-VOID
-LoadGuidedSectionToolsTxt (
- IN CHAR8* FirmwareVolumeFilename
- );
-
-EFI_STATUS
-CombinePath (
- IN CHAR8* DefaultPath,
- IN CHAR8* AppendPath,
- OUT CHAR8* NewPath
-);
-
-void
-Usage (
- VOID
- );
-
-UINT32
-UnicodeStrLen (
- IN CHAR16 *String
- )
- /*++
-
- Routine Description:
-
- Returns the length of a null-terminated unicode string.
-
- Arguments:
-
- String - The pointer to a null-terminated unicode string.
-
- Returns:
-
- N/A
-
- --*/
-{
- UINT32 Length;
-
- for (Length = 0; *String != L'\0'; String++, Length++) {
- ;
- }
- return Length;
-}
-
-VOID
-Unicode2AsciiString (
- IN CHAR16 *Source,
- OUT CHAR8 *Destination
- )
- /*++
-
- Routine Description:
-
- Convert a null-terminated unicode string to a null-terminated ascii string.
-
- Arguments:
-
- Source - The pointer to the null-terminated input unicode string.
- Destination - The pointer to the null-terminated output ascii string.
-
- Returns:
-
- N/A
-
- --*/
-{
- while (*Source != '\0') {
- *(Destination++) = (CHAR8) *(Source++);
- }
- //
- // End the ascii with a NULL.
- //
- *Destination = '\0';
-}
-
-int
-main (
- int argc,
- char *argv[]
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- argc - GC_TODO: add argument description
- ] - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- FILE *InputFile;
- int BytesRead;
- EFI_FIRMWARE_VOLUME_HEADER *FvImage;
- UINT32 FvSize;
- EFI_STATUS Status;
- int Offset;
- BOOLEAN ErasePolarity;
- UINT64 LogLevel;
- CHAR8 *OpenSslEnv;
- CHAR8 *OpenSslCommand;
-
- SetUtilityName (UTILITY_NAME);
- //
- // Print utility header
- //
- printf ("%s Version %d.%d Build %s\n",
- UTILITY_NAME,
- UTILITY_MAJOR_VERSION,
- UTILITY_MINOR_VERSION,
- __BUILD_VERSION
- );
-
- if (argc == 1) {
- Usage ();
- return -1;
- }
-
- argc--;
- argv++;
- LogLevel = 0;
- Offset = 0;
-
- //
- // Look for help options
- //
- if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) ||
- (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {
- Usage();
- return STATUS_SUCCESS;
- }
- //
- // Version has already be printed, so just return success
- //
- if (strcmp(argv[0], "--version") == 0) {
- return STATUS_SUCCESS;
- }
-
- //
- // If they specified -x xref guid/basename cross-reference files, process it.
- // This will print the basename beside each file guid. To use it, specify
- // -x xref_filename to processdsc, then use xref_filename as a parameter
- // here.
- //
- while (argc > 0) {
- if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {
- ParseGuidBaseNameFile (argv[1]);
- printf("ParseGuidBaseNameFile: %s\n", argv[1]);
- argc -= 2;
- argv += 2;
- continue;
- }
- if (strcmp(argv[0], "--offset") == 0) {
- //
- // Hex or decimal?
- //
- if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {
- if (sscanf (argv[1], "%x", &Offset) != 1) {
- Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);
- return GetUtilityStatus ();
- }
- } else {
- if (sscanf (argv[1], "%d", &Offset) != 1) {
- Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);
- return GetUtilityStatus ();
- }
- //
- // See if they said something like "64K"
- //
- if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {
- Offset *= 1024;
- }
- }
-
- argc -= 2;
- argv += 2;
- continue;
- }
- if ((stricmp (argv[0], "--hash") == 0)) {
- if (EnableHash == TRUE) {
- //
- // --hash already given in the option, ignore this one
- //
- argc --;
- argv ++;
- continue;
- }
- EnableHash = TRUE;
- OpenSslCommand = "openssl";
- OpenSslEnv = getenv("OPENSSL_PATH");
- if (OpenSslEnv == NULL) {
- OpenSslPath = OpenSslCommand;
- } else {
- //
- // We add quotes to the Openssl Path in case it has space characters
- //
- OpenSslPath = malloc(2+strlen(OpenSslEnv)+strlen(OpenSslCommand)+1);
- if (OpenSslPath == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return GetUtilityStatus ();
- }
- CombinePath(OpenSslEnv, OpenSslCommand, OpenSslPath);
- }
- if (OpenSslPath == NULL){
- Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);
- return GetUtilityStatus ();
- }
- argc --;
- argv ++;
- continue;
- }
-
- if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
- SetPrintLevel (VERBOSE_LOG_LEVEL);
- argc --;
- argv ++;
- continue;
- }
-
- if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
- SetPrintLevel (KEY_LOG_LEVEL);
- 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]);
- return -1;
- }
- if (LogLevel > 9) {
- Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
- return -1;
- }
- SetPrintLevel (LogLevel);
- DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
- argc -= 2;
- argv += 2;
- continue;
- }
-
- mUtilityFilename = argv[0];
- argc --;
- argv ++;
- }
-
- //
- // Open the file containing the FV
- //
- if (mUtilityFilename == NULL) {
- Error (NULL, 0, 1001, "Missing option", "Input files are not specified");
- return GetUtilityStatus ();
- }
- InputFile = fopen (LongFilePath (mUtilityFilename), "rb");
- if (InputFile == NULL) {
- Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename);
- return GetUtilityStatus ();
- }
- //
- // Skip over pad bytes if specified. This is used if they prepend 0xff
- // data to the FV image binary.
- //
- if (Offset != 0) {
- fseek (InputFile, Offset, SEEK_SET);
- }
- //
- // Determine size of FV
- //
- Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename);
- fclose (InputFile);
- return GetUtilityStatus ();
- }
- //
- // Allocate a buffer for the FV image
- //
- FvImage = malloc (FvSize);
- if (FvImage == NULL) {
- Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
- fclose (InputFile);
- return GetUtilityStatus ();
- }
- //
- // Seek to the start of the image, then read the entire FV to the buffer
- //
- fseek (InputFile, Offset, SEEK_SET);
- BytesRead = fread (FvImage, 1, FvSize, InputFile);
- fclose (InputFile);
- if ((unsigned int) BytesRead != FvSize) {
- Error (NULL, 0, 0004, "error reading FvImage from", mUtilityFilename);
- free (FvImage);
- return GetUtilityStatus ();
- }
-
- LoadGuidedSectionToolsTxt (mUtilityFilename);
-
- PrintFvInfo (FvImage, FALSE);
-
- //
- // Clean up
- //
- free (FvImage);
- FreeGuidBaseNameList ();
- return GetUtilityStatus ();
-}
-
-
-static
-EFI_STATUS
-PrintFvInfo (
- IN VOID *Fv,
- IN BOOLEAN IsChildFv
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- Fv - Firmware Volume to print information about
- IsChildFv - Flag specifies whether the input FV is a child FV.
-
-Returns:
-
- EFI_STATUS
-
---*/
-{
- EFI_STATUS Status;
- UINTN NumberOfFiles;
- BOOLEAN ErasePolarity;
- UINTN FvSize;
- EFI_FFS_FILE_HEADER *CurrentFile;
- UINTN Key;
-
- Status = FvBufGetSize (Fv, &FvSize);
-
- NumberOfFiles = 0;
- ErasePolarity =
- (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?
- TRUE : FALSE;
-
- //
- // Get the first file
- //
- Key = 0;
- Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
- return GetUtilityStatus ();
- }
- //
- // Display information about files found
- //
- while (CurrentFile != NULL) {
- //
- // Increment the number of files counter
- //
- NumberOfFiles++;
-
- //
- // Display info about this file
- //
- Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
- return GetUtilityStatus ();
- }
- //
- // Get the next file
- //
- Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
- if (Status == EFI_NOT_FOUND) {
- CurrentFile = NULL;
- } else if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
- return GetUtilityStatus ();
- }
- }
-
- if (IsChildFv) {
- printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles);
- } else {
- printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles);
- }
-
- return EFI_SUCCESS;
-}
-
-UINT32
-GetOccupiedSize (
- IN UINT32 ActualSize,
- IN UINT32 Alignment
- )
-/*++
-
-Routine Description:
-
- This function returns the next larger size that meets the alignment
- requirement specified.
-
-Arguments:
-
- ActualSize The size.
- Alignment The desired alignment.
-
-Returns:
-
- EFI_SUCCESS Function completed successfully.
- EFI_ABORTED The function encountered an error.
-
---*/
-{
- UINT32 OccupiedSize;
-
- OccupiedSize = ActualSize;
- while ((OccupiedSize & (Alignment - 1)) != 0) {
- OccupiedSize++;
- }
-
- return OccupiedSize;
-}
-
-static
-CHAR8 *
-SectionNameToStr (
- IN EFI_SECTION_TYPE Type
- )
-/*++
-
-Routine Description:
-
- Converts EFI Section names to Strings
-
-Arguments:
-
- Type - The EFI Section type
-
-Returns:
-
- CHAR8* - Pointer to the String containing the section name.
-
---*/
-{
- CHAR8 *SectionStr;
- CHAR8 *SectionTypeStringTable[] = {
- //
- // 0X00
- //
- "EFI_SECTION_ALL",
- //
- // 0x01
- //
- "EFI_SECTION_COMPRESSION",
- //
- // 0x02
- //
- "EFI_SECTION_GUID_DEFINED",
- //
- // 0x03
- //
- "Unknown section type - Reserved 0x03",
- //
- // 0x04
- //
- "Unknown section type - Reserved 0x04",
- //
- // 0x05
- //
- "Unknown section type - Reserved 0x05",
- //
- // 0x06
- //
- "Unknown section type - Reserved 0x06",
- //
- // 0x07
- //
- "Unknown section type - Reserved 0x07",
- //
- // 0x08
- //
- "Unknown section type - Reserved 0x08",
- //
- // 0x09
- //
- "Unknown section type - Reserved 0x09",
- //
- // 0x0A
- //
- "Unknown section type - Reserved 0x0A",
- //
- // 0x0B
- //
- "Unknown section type - Reserved 0x0B",
- //
- // 0x0C
- //
- "Unknown section type - Reserved 0x0C",
- //
- // 0x0D
- //
- "Unknown section type - Reserved 0x0D",
- //
- // 0x0E
- //
- "Unknown section type - Reserved 0x0E",
- //
- // 0x0F
- //
- "Unknown section type - Reserved 0x0E",
- //
- // 0x10
- //
- "EFI_SECTION_PE32",
- //
- // 0x11
- //
- "EFI_SECTION_PIC",
- //
- // 0x12
- //
- "EFI_SECTION_TE",
- //
- // 0x13
- //
- "EFI_SECTION_DXE_DEPEX",
- //
- // 0x14
- //
- "EFI_SECTION_VERSION",
- //
- // 0x15
- //
- "EFI_SECTION_USER_INTERFACE",
- //
- // 0x16
- //
- "EFI_SECTION_COMPATIBILITY16",
- //
- // 0x17
- //
- "EFI_SECTION_FIRMWARE_VOLUME_IMAGE",
- //
- // 0x18
- //
- "EFI_SECTION_FREEFORM_SUBTYPE_GUID",
- //
- // 0x19
- //
- "EFI_SECTION_RAW",
- //
- // 0x1A
- //
- "Unknown section type - 0x1A",
- //
- // 0x1B
- //
- "EFI_SECTION_PEI_DEPEX",
- //
- // 0x1C
- //
- "EFI_SECTION_MM_DEPEX",
- //
- // 0x1C+
- //
- "Unknown section type - Reserved - beyond last defined section"
- };
-
- if (Type > EFI_SECTION_LAST_SECTION_TYPE) {
- Type = EFI_SECTION_LAST_SECTION_TYPE + 1;
- }
-
- SectionStr = malloc (100);
- if (SectionStr == NULL) {
- printf ("Error: Out of memory resources.\n");
- return SectionStr;
- }
- strcpy (SectionStr, SectionTypeStringTable[Type]);
- return SectionStr;
-}
-
-STATIC
-EFI_STATUS
-ReadHeader (
- IN FILE *InputFile,
- OUT UINT32 *FvSize,
- OUT BOOLEAN *ErasePolarity
- )
-/*++
-
-Routine Description:
-
- This function determines the size of the FV and the erase polarity. The
- erase polarity is the FALSE value for file state.
-
-Arguments:
-
- InputFile The file that contains the FV image.
- FvSize The size of the FV.
- ErasePolarity The FV erase polarity.
-
-Returns:
-
- EFI_SUCCESS Function completed successfully.
- EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
- EFI_ABORTED The function encountered an error.
-
---*/
-{
- EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
- EFI_FV_BLOCK_MAP_ENTRY BlockMap;
- UINTN Signature[2];
- UINTN BytesRead;
- UINT32 Size;
- size_t ReadSize;
-
- BytesRead = 0;
- Size = 0;
- //
- // Check input parameters
- //
- if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {
- Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");
- return EFI_INVALID_PARAMETER;
- }
- //
- // Read the header
- //
- ReadSize = fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
- if (ReadSize != 1) {
- return EFI_ABORTED;
- }
- BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
- Signature[0] = VolumeHeader.Signature;
- Signature[1] = 0;
-
- //
- // Print FV header information
- //
- printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);
- printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);
-
- if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {
- printf (" EFI_FVB2_READ_DISABLED_CAP\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {
- printf (" EFI_FVB2_READ_ENABLED_CAP\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {
- printf (" EFI_FVB2_READ_STATUS\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {
- printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {
- printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {
- printf (" EFI_FVB2_WRITE_STATUS\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {
- printf (" EFI_FVB2_LOCK_CAP\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {
- printf (" EFI_FVB2_LOCK_STATUS\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {
- printf (" EFI_FVB2_STICKY_WRITE\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {
- printf (" EFI_FVB2_MEMORY_MAPPED\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {
- printf (" EFI_FVB2_ERASE_POLARITY\n");
- *ErasePolarity = TRUE;
- }
-
-#if (PI_SPECIFICATION_VERSION < 0x00010000)
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {
- printf (" EFI_FVB2_ALIGNMENT\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {
- printf (" EFI_FVB2_ALIGNMENT_2\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {
- printf (" EFI_FVB2_ALIGNMENT_4\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {
- printf (" EFI_FVB2_ALIGNMENT_8\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {
- printf (" EFI_FVB2_ALIGNMENT_16\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {
- printf (" EFI_FVB2_ALIGNMENT_32\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {
- printf (" EFI_FVB2_ALIGNMENT_64\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {
- printf (" EFI_FVB2_ALIGNMENT_128\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {
- printf (" EFI_FVB2_ALIGNMENT_256\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {
- printf (" EFI_FVB2_ALIGNMENT_512\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {
- printf (" EFI_FVB2_ALIGNMENT_1K\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {
- printf (" EFI_FVB2_ALIGNMENT_2K\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {
- printf (" EFI_FVB2_ALIGNMENT_4K\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {
- printf (" EFI_FVB2_ALIGNMENT_8K\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {
- printf (" EFI_FVB2_ALIGNMENT_16K\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {
- printf (" EFI_FVB2_ALIGNMENT_32K\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {
- printf (" EFI_FVB2_ALIGNMENT_64K\n");
- }
-
-#else
-
- if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {
- printf (" EFI_FVB2_READ_LOCK_CAP\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {
- printf (" EFI_FVB2_READ_LOCK_STATUS\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {
- printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
- }
-
- if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {
- printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
- }
-
- switch (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {
- case EFI_FVB2_ALIGNMENT_1:
- printf (" EFI_FVB2_ALIGNMENT_1\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_2:
- printf (" EFI_FVB2_ALIGNMENT_2\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_4:
- printf (" EFI_FVB2_ALIGNMENT_4\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_8:
- printf (" EFI_FVB2_ALIGNMENT_8\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_16:
- printf (" EFI_FVB2_ALIGNMENT_16\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_32:
- printf (" EFI_FVB2_ALIGNMENT_32\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_64:
- printf (" EFI_FVB2_ALIGNMENT_64\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_128:
- printf (" EFI_FVB2_ALIGNMENT_128\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_256:
- printf (" EFI_FVB2_ALIGNMENT_256\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_512:
- printf (" EFI_FVB2_ALIGNMENT_512\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_1K:
- printf (" EFI_FVB2_ALIGNMENT_1K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_2K:
- printf (" EFI_FVB2_ALIGNMENT_2K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_4K:
- printf (" EFI_FVB2_ALIGNMENT_4K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_8K:
- printf (" EFI_FVB2_ALIGNMENT_8K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_16K:
- printf (" EFI_FVB2_ALIGNMENT_16K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_32K:
- printf (" EFI_FVB2_ALIGNMENT_32K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_64K:
- printf (" EFI_FVB2_ALIGNMENT_64K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_128K:
- printf (" EFI_FVB2_ALIGNMENT_128K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_256K:
- printf (" EFI_FVB2_ALIGNMENT_256K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_512K:
- printf (" EFI_FVB2_ALIGNMENT_512K\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_1M:
- printf (" EFI_FVB2_ALIGNMENT_1M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_2M:
- printf (" EFI_FVB2_ALIGNMENT_2M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_4M:
- printf (" EFI_FVB2_ALIGNMENT_4M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_8M:
- printf (" EFI_FVB2_ALIGNMENT_8M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_16M:
- printf (" EFI_FVB2_ALIGNMENT_16M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_32M:
- printf (" EFI_FVB2_ALIGNMENT_32M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_64M:
- printf (" EFI_FVB2_ALIGNMENT_64M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_128M:
- printf (" EFI_FVB2_ALIGNMENT_128M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_256M:
- printf (" EFI_FVB2_ALIGNMENT_256M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_512M:
- printf (" EFI_FVB2_ALIGNMENT_512M\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_1G:
- printf (" EFI_FVB2_ALIGNMENT_1G\n");
- break;
-
- case EFI_FVB2_ALIGNMENT_2G:
- printf (" EFI_FVB2_ALIGNMENT_2G\n");
- break;
- }
-
-#endif
- printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);
- printf ("File System ID: ");
- PrintGuid (&VolumeHeader.FileSystemGuid);
- //
- // printf ("\n");
- //
- printf ("Revision: 0x%04X\n", VolumeHeader.Revision);
-
- do {
- ReadSize = fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
- if (ReadSize != 1) {
- return EFI_ABORTED;
- }
- BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
-
- if (BlockMap.NumBlocks != 0) {
- printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);
- printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);
- Size += BlockMap.NumBlocks * BlockMap.Length;
- }
-
- } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));
-
- if (BytesRead != VolumeHeader.HeaderLength) {
- printf ("ERROR: Header length not consistent with Block Maps!\n");
- return EFI_ABORTED;
- }
-
- if (VolumeHeader.FvLength != Size) {
- printf ("ERROR: Volume Size not consistent with Block Maps!\n");
- return EFI_ABORTED;
- }
-
- printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);
-
- *FvSize = Size;
-
- //
- // rewind (InputFile);
- //
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-PrintAprioriFile (
- EFI_FFS_FILE_HEADER *FileHeader
- )
-/*++
-
-Routine Description:
-
- Print GUIDs from the APRIORI file
-
-Arguments:
-
- FileHeader - The file header
-
-Returns:
-
- EFI_SUCCESS - The APRIORI file was parsed correctly
- EFI_SECTION_ERROR - Problem with file parsing
-
---*/
-{
- UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
- UINT32 HeaderSize;
-
- HeaderSize = FvBufGetFfsHeaderSize (FileHeader);
-
- if (FileHeader->Type != EFI_FV_FILETYPE_FREEFORM)
- return EFI_SECTION_ERROR;
-
- EFI_COMMON_SECTION_HEADER* SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) FileHeader + HeaderSize);
- if (SectionHeader->Type != EFI_SECTION_RAW)
- return EFI_SECTION_ERROR;
-
- UINT32 SectionLength = GetSectionFileLength (SectionHeader);
- EFI_GUID* FileName = (EFI_GUID *) ((UINT8 *) SectionHeader + sizeof (EFI_COMMON_SECTION_HEADER));
- while (((UINT8 *) FileName) < ((UINT8 *) SectionHeader + SectionLength)) {
- PrintGuidToBuffer (FileName, GuidBuffer, sizeof (GuidBuffer), TRUE);
- printf ("%s ", GuidBuffer);
- PrintGuidName (GuidBuffer);
- printf ("\n");
- FileName++;
- }
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-PrintFileInfo (
- EFI_FIRMWARE_VOLUME_HEADER *FvImage,
- EFI_FFS_FILE_HEADER *FileHeader,
- BOOLEAN ErasePolarity
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- FvImage - GC_TODO: add argument description
- FileHeader - GC_TODO: add argument description
- ErasePolarity - GC_TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - GC_TODO: Add description for return value
- EFI_ABORTED - GC_TODO: Add description for return value
-
---*/
-{
- UINT32 FileLength;
- UINT8 FileState;
- UINT8 Checksum;
- EFI_FFS_FILE_HEADER2 BlankHeader;
- EFI_STATUS Status;
- UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
- UINT32 HeaderSize;
-#if (PI_SPECIFICATION_VERSION < 0x00010000)
- UINT16 *Tail;
-#endif
- //
- // Check if we have free space
- //
- HeaderSize = FvBufGetFfsHeaderSize(FileHeader);
- if (ErasePolarity) {
- memset (&BlankHeader, -1, HeaderSize);
- } else {
- memset (&BlankHeader, 0, HeaderSize);
- }
-
- if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {
- return EFI_SUCCESS;
- }
- //
- // Print file information.
- //
- printf ("============================================================\n");
-
- printf ("File Name: ");
- PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);
- printf ("%s ", GuidBuffer);
- PrintGuidName (GuidBuffer);
- printf ("\n");
-
- //
- // PrintGuid (&FileHeader->Name);
- // printf ("\n");
- //
- FileLength = FvBufGetFfsFileSize (FileHeader);
- printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));
- printf ("File Length: 0x%08X\n", (unsigned) FileLength);
- printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);
- printf ("File State: 0x%02X\n", FileHeader->State);
-
- //
- // Print file state
- //
- FileState = GetFileState (ErasePolarity, FileHeader);
-
- switch (FileState) {
-
- case EFI_FILE_HEADER_CONSTRUCTION:
- printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
- return EFI_SUCCESS;
-
- case EFI_FILE_HEADER_INVALID:
- printf (" EFI_FILE_HEADER_INVALID\n");
- return EFI_SUCCESS;
-
- case EFI_FILE_HEADER_VALID:
- printf (" EFI_FILE_HEADER_VALID\n");
- Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);
- Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
- Checksum = (UINT8) (Checksum - FileHeader->State);
- if (Checksum != 0) {
- printf ("ERROR: Header checksum invalid.\n");
- return EFI_ABORTED;
- }
-
- return EFI_SUCCESS;
-
- case EFI_FILE_DELETED:
- printf (" EFI_FILE_DELETED\n");
-
- case EFI_FILE_MARKED_FOR_UPDATE:
- printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
-
- case EFI_FILE_DATA_VALID:
- printf (" EFI_FILE_DATA_VALID\n");
-
- //
- // Calculate header checksum
- //
- Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);
- Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
- Checksum = (UINT8) (Checksum - FileHeader->State);
- if (Checksum != 0) {
- Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);
- return EFI_ABORTED;
- }
-
- FileLength = FvBufGetFfsFileSize (FileHeader);
-
- if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
- //
- // Calculate file checksum
- //
- Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);
- Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;
- if (Checksum != 0) {
- Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);
- return EFI_ABORTED;
- }
- } else {
- if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
- Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum -- not set to fixed value of 0xAA", GuidBuffer);
- return EFI_ABORTED;
- }
- }
-#if (PI_SPECIFICATION_VERSION < 0x00010000)
- //
- // Verify tail if present
- //
- if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
- //
- // Verify tail is complement of integrity check field in the header.
- //
- Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));
- if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {
- Error (NULL, 0, 0003, "error parsing FFS file", \
- "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);
- return EFI_ABORTED;
- }
- }
- #endif
- break;
-
- default:
- Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);
- return EFI_ABORTED;
- }
-
- printf ("File Type: 0x%02X ", FileHeader->Type);
-
- switch (FileHeader->Type) {
-
- case EFI_FV_FILETYPE_RAW:
- printf ("EFI_FV_FILETYPE_RAW\n");
- break;
-
- case EFI_FV_FILETYPE_FREEFORM:
- printf ("EFI_FV_FILETYPE_FREEFORM\n");
- break;
-
- case EFI_FV_FILETYPE_SECURITY_CORE:
- printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
- break;
-
- case EFI_FV_FILETYPE_PEI_CORE:
- printf ("EFI_FV_FILETYPE_PEI_CORE\n");
- break;
-
- case EFI_FV_FILETYPE_DXE_CORE:
- printf ("EFI_FV_FILETYPE_DXE_CORE\n");
- break;
-
- case EFI_FV_FILETYPE_PEIM:
- printf ("EFI_FV_FILETYPE_PEIM\n");
- break;
-
- case EFI_FV_FILETYPE_DRIVER:
- printf ("EFI_FV_FILETYPE_DRIVER\n");
- break;
-
- case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
- printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
- break;
-
- case EFI_FV_FILETYPE_APPLICATION:
- printf ("EFI_FV_FILETYPE_APPLICATION\n");
- break;
-
- case EFI_FV_FILETYPE_SMM:
- printf ("EFI_FV_FILETYPE_MM\n");
- break;
-
- case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
- printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
- break;
-
- case EFI_FV_FILETYPE_COMBINED_SMM_DXE:
- printf ("EFI_FV_FILETYPE_COMBINED_MM_DXE\n");
- break;
-
- case EFI_FV_FILETYPE_SMM_CORE:
- printf ("EFI_FV_FILETYPE_MM_CORE\n");
- break;
-
- case EFI_FV_FILETYPE_MM_STANDALONE:
- printf ("EFI_FV_FILETYPE_MM_STANDALONE\n");
- break;
-
- case EFI_FV_FILETYPE_MM_CORE_STANDALONE:
- printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n");
- break;
-
- case EFI_FV_FILETYPE_FFS_PAD:
- printf ("EFI_FV_FILETYPE_FFS_PAD\n");
- break;
-
- default:
- printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);
- return EFI_ABORTED;
- break;
- }
-
- switch (FileHeader->Type) {
-
- case EFI_FV_FILETYPE_ALL:
- case EFI_FV_FILETYPE_RAW:
- case EFI_FV_FILETYPE_FFS_PAD:
- break;
-
- default:
- //
- // All other files have sections
- //
- Status = ParseSection (
- (UINT8 *) ((UINTN) FileHeader + HeaderSize),
- FvBufGetFfsFileSize (FileHeader) - HeaderSize
- );
- if (EFI_ERROR (Status)) {
- //
- // printf ("ERROR: Parsing the FFS file.\n");
- //
- return EFI_ABORTED;
- }
- break;
- }
-
- if (!CompareGuid (
- &FileHeader->Name,
- &gPeiAprioriFileNameGuid
- ))
- {
- printf("\n");
- printf("PEI APRIORI FILE:\n");
- return PrintAprioriFile (FileHeader);
- }
- if (!CompareGuid (
- &FileHeader->Name,
- &gAprioriGuid
- ))
- {
- printf("\n");
- printf("DXE APRIORI FILE:\n");
- return PrintAprioriFile (FileHeader);
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-RebaseImageRead (
- 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
-SetAddressToSectionHeader (
- IN CHAR8 *FileName,
- IN OUT UINT8 *FileBuffer,
- IN UINT64 NewPe32BaseAddress
- )
-/*++
-
-Routine Description:
-
- Set new base address into the section header of PeImage
-
-Arguments:
-
- FileName - Name of file
- FileBuffer - Pointer to PeImage.
- NewPe32BaseAddress - New Base Address for PE image.
-
-Returns:
-
- EFI_SUCCESS Set new base address into this image successfully.
-
---*/
-{
- EFI_STATUS Status;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
- UINTN Index;
- EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
- EFI_IMAGE_SECTION_HEADER *SectionHeader;
-
- //
- // Initialize context
- //
- memset (&ImageContext, 0, sizeof (ImageContext));
- ImageContext.Handle = (VOID *) FileBuffer;
- ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
- Status = PeCoffLoaderGetImageInfo (&ImageContext);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
- return Status;
- }
-
- if (ImageContext.RelocationsStripped) {
- Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
- return Status;
- }
-
- //
- // Get PeHeader pointer
- //
- ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
-
- //
- // Get section header list
- //
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
- (UINTN) ImgHdr +
- sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
- );
-
- //
- // Set base address into the first section header that doesn't point to code section.
- //
- for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
- if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
- *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;
- break;
- }
- }
-
- //
- // BaseAddress is set to section header.
- //
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-RebaseImage (
- IN CHAR8 *FileName,
- IN OUT UINT8 *FileBuffer,
- IN UINT64 NewPe32BaseAddress
- )
-/*++
-
-Routine Description:
-
- Set new base address into PeImage, and fix up PeImage based on new address.
-
-Arguments:
-
- FileName - Name of file
- FileBuffer - Pointer to PeImage.
- NewPe32BaseAddress - New Base Address for PE image.
-
-Returns:
-
- EFI_INVALID_PARAMETER - BaseAddress is not valid.
- EFI_SUCCESS - Update PeImage is correctly.
-
---*/
-{
- EFI_STATUS Status;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
- UINTN Index;
- EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
- UINT8 *MemoryImagePointer;
- EFI_IMAGE_SECTION_HEADER *SectionHeader;
-
- //
- // Initialize context
- //
- memset (&ImageContext, 0, sizeof (ImageContext));
- ImageContext.Handle = (VOID *) FileBuffer;
- ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
- Status = PeCoffLoaderGetImageInfo (&ImageContext);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
- return Status;
- }
-
- if (ImageContext.RelocationsStripped) {
- Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
- return Status;
- }
-
- //
- // Get PeHeader pointer
- //
- ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
-
- //
- // 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) & (~((INT64)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 (
- FileBuffer + SectionHeader->PointerToRawData,
- (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
- SectionHeader->SizeOfRawData
- );
- }
-
- free ((VOID *) MemoryImagePointer);
-
- //
- // 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;
- }
-
- //
- // Set new base address into section header
- //
- Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);
-
- return Status;
-}
-
-EFI_STATUS
-CombinePath (
- IN CHAR8* DefaultPath,
- IN CHAR8* AppendPath,
- OUT CHAR8* NewPath
-)
-{
- UINT32 DefaultPathLen;
- UINT64 Index;
- CHAR8 QuotesStr[] = "\"";
- strcpy(NewPath, QuotesStr);
- DefaultPathLen = strlen(DefaultPath);
- strcat(NewPath, DefaultPath);
- Index = 0;
- for (; Index < DefaultPathLen + 1; Index ++) {
- if (NewPath[Index] == '\\' || NewPath[Index] == '/') {
- if (NewPath[Index + 1] != '\0') {
- NewPath[Index] = '/';
- }
- }
- }
- if (NewPath[Index -1] != '/') {
- NewPath[Index] = '/';
- NewPath[Index + 1] = '\0';
- }
- strcat(NewPath, AppendPath);
- strcat(NewPath, QuotesStr);
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ParseSection (
- IN UINT8 *SectionBuffer,
- IN UINT32 BufferLength
- )
-/*++
-
-Routine Description:
-
- Parses EFI Sections
-
-Arguments:
-
- SectionBuffer - Buffer containing the section to parse.
- BufferLength - Length of SectionBuffer
-
-Returns:
-
- EFI_SECTION_ERROR - Problem with section parsing.
- (a) compression errors
- (b) unrecognized section
- EFI_UNSUPPORTED - Do not know how to parse the section.
- EFI_SUCCESS - Section successfully parsed.
- EFI_OUT_OF_RESOURCES - Memory allocation failed.
-
---*/
-{
- EFI_SECTION_TYPE Type;
- UINT8 *Ptr;
- UINT32 SectionLength;
- UINT32 SectionHeaderLen;
- CHAR8 *SectionName;
- EFI_STATUS Status;
- UINT32 ParsedLength;
- UINT8 *CompressedBuffer;
- UINT32 CompressedLength;
- UINT8 *UncompressedBuffer;
- UINT32 UncompressedLength;
- UINT8 *ToolOutputBuffer;
- UINT32 ToolOutputLength;
- UINT8 CompressionType;
- UINT32 DstSize;
- UINT32 ScratchSize;
- UINT8 *ScratchBuffer;
- DECOMPRESS_FUNCTION DecompressFunction;
- GETINFO_FUNCTION GetInfoFunction;
- // CHAR16 *name;
- CHAR8 *ExtractionTool;
- CHAR8 *ToolInputFile;
- CHAR8 *ToolOutputFile;
- CHAR8 *SystemCommand;
- EFI_GUID *EfiGuid;
- UINT16 DataOffset;
- UINT16 Attributes;
- UINT32 RealHdrLen;
- CHAR8 *ToolInputFileName;
- CHAR8 *ToolOutputFileName;
- CHAR8 *UIFileName;
- CHAR8 *VersionString;
-
- ParsedLength = 0;
- ToolInputFileName = NULL;
- ToolOutputFileName = NULL;
-
- while (ParsedLength < BufferLength) {
- Ptr = SectionBuffer + ParsedLength;
-
- SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);
- Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;
-
- //
- // This is sort of an odd check, but is necessary because FFS files are
- // padded to a QWORD boundary, meaning there is potentially a whole section
- // header worth of 0xFF bytes.
- //
- if (SectionLength == 0xffffff && Type == 0xff) {
- ParsedLength += 4;
- continue;
- }
-
- //
- // Get real section file size
- //
- SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);
- SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
-
- SectionName = SectionNameToStr (Type);
- if (SectionName != NULL) {
- printf ("------------------------------------------------------------\n");
- printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);
- free (SectionName);
- }
-
- switch (Type) {
- case EFI_SECTION_RAW:
- case EFI_SECTION_PIC:
- case EFI_SECTION_TE:
- // default is no more information
- break;
-
- case EFI_SECTION_PE32:
- if (EnableHash) {
- ToolInputFileName = "edk2Temp_InputEfi.tmp";
- ToolOutputFileName = "edk2Temp_OutputHash.tmp";
- RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);
- PutFileImage (
- ToolInputFileName,
- (CHAR8*)Ptr + SectionHeaderLen,
- SectionLength - SectionHeaderLen
- );
-
- SystemCommand = malloc (
- strlen (OPENSSL_COMMAND_FORMAT_STRING) +
- strlen (OpenSslPath) +
- strlen (ToolInputFileName) +
- strlen (ToolOutputFileName) +
- 1
- );
- if (SystemCommand == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- sprintf (
- SystemCommand,
- OPENSSL_COMMAND_FORMAT_STRING,
- OpenSslPath,
- ToolOutputFileName,
- ToolInputFileName
- );
-
- if (system (SystemCommand) != EFI_SUCCESS) {
- Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);
- }
- else {
- FILE *fp;
- CHAR8 *StrLine;
- CHAR8 *NewStr;
- UINT32 nFileLen;
- if((fp = fopen(ToolOutputFileName,"r")) == NULL) {
- Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);
- }
- else {
- fseek(fp,0,SEEK_SET);
- fseek(fp,0,SEEK_END);
- nFileLen = ftell(fp);
- fseek(fp,0,SEEK_SET);
- StrLine = malloc(nFileLen);
- if (StrLine == NULL) {
- fclose(fp);
- free (SystemCommand);
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- fgets(StrLine, nFileLen, fp);
- NewStr = strrchr (StrLine, '=');
- printf (" SHA1: %s\n", NewStr + 1);
- free (StrLine);
- fclose(fp);
- }
- }
- remove(ToolInputFileName);
- remove(ToolOutputFileName);
- free (SystemCommand);
- }
- break;
-
- case EFI_SECTION_USER_INTERFACE:
- UIFileName = (CHAR8 *) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString) + 1);
- if (UIFileName == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UIFileName);
- printf (" String: %s\n", UIFileName);
- free (UIFileName);
- break;
-
- case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
- printf ("/------------ Firmware Volume section start ---------------\\\n");
- Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);
- return EFI_SECTION_ERROR;
- }
- printf ("\\------------ Firmware Volume section end -----------------/\n");
- break;
-
- case EFI_SECTION_COMPATIBILITY16:
- //
- // Section does not contain any further header information.
- //
- break;
-
- case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
- printf (" Guid: ");
- if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER))
- PrintGuid (&((EFI_FREEFORM_SUBTYPE_GUID_SECTION *)Ptr)->SubTypeGuid);
- else
- PrintGuid (&((EFI_FREEFORM_SUBTYPE_GUID_SECTION2 *)Ptr)->SubTypeGuid);
- printf ("\n");
- break;
-
- case EFI_SECTION_PEI_DEPEX:
- case EFI_SECTION_DXE_DEPEX:
- case EFI_SECTION_SMM_DEPEX:
- DumpDepexSection (Ptr, SectionLength);
- break;
-
- case EFI_SECTION_VERSION:
- printf (" Build Number: 0x%04X\n", *(UINT16 *)(Ptr + SectionHeaderLen));
- VersionString = (CHAR8 *) malloc (UnicodeStrLen (((EFI_VERSION_SECTION *) Ptr)->VersionString) + 1);
- if (VersionString == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- Unicode2AsciiString (((EFI_VERSION_SECTION *) Ptr)->VersionString, VersionString);
- printf (" Version String: %s\n", VersionString);
- break;
-
- case EFI_SECTION_COMPRESSION:
- UncompressedBuffer = NULL;
- if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {
- RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);
- UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;
- CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;
- } else {
- RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);
- UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;
- CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;
- }
- CompressedLength = SectionLength - RealHdrLen;
- printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);
-
- if (CompressionType == EFI_NOT_COMPRESSED) {
- printf (" Compression Type: EFI_NOT_COMPRESSED\n");
- if (CompressedLength != UncompressedLength) {
- Error (
- NULL,
- 0,
- 0,
- "file is not compressed, but the compressed length does not match the uncompressed length",
- NULL
- );
- return EFI_SECTION_ERROR;
- }
-
- UncompressedBuffer = Ptr + RealHdrLen;
- } else if (CompressionType == EFI_STANDARD_COMPRESSION) {
- GetInfoFunction = EfiGetInfo;
- DecompressFunction = EfiDecompress;
- printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
-
- CompressedBuffer = Ptr + RealHdrLen;
-
- Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);
- return EFI_SECTION_ERROR;
- }
-
- if (DstSize != UncompressedLength) {
- Error (NULL, 0, 0003, "compression error in the compression section", NULL);
- return EFI_SECTION_ERROR;
- }
-
- ScratchBuffer = malloc (ScratchSize);
- if (ScratchBuffer == NULL) {
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- UncompressedBuffer = malloc (UncompressedLength);
- if (UncompressedBuffer == NULL) {
- free (ScratchBuffer);
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- Status = DecompressFunction (
- CompressedBuffer,
- CompressedLength,
- UncompressedBuffer,
- UncompressedLength,
- ScratchBuffer,
- ScratchSize
- );
- free (ScratchBuffer);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "decompress failed", NULL);
- free (UncompressedBuffer);
- return EFI_SECTION_ERROR;
- }
- } else {
- Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);
- return EFI_SECTION_ERROR;
- }
-
- printf ("/------------ Encapsulation section start -----------------\\\n");
- Status = ParseSection (UncompressedBuffer, UncompressedLength);
- printf ("\\------------ Encapsulation section end -------------------/\n");
-
- if (CompressionType == EFI_STANDARD_COMPRESSION) {
- //
- // We need to deallocate Buffer
- //
- free (UncompressedBuffer);
- }
-
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "failed to parse section", NULL);
- return EFI_SECTION_ERROR;
- }
- break;
-
- case EFI_SECTION_GUID_DEFINED:
- if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {
- EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;
- DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;
- Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;
- } else {
- EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;
- DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;
- Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;
- }
- printf (" SectionDefinitionGuid: ");
- PrintGuid (EfiGuid);
- printf ("\n");
- printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);
- printf (" Attributes: 0x%04X\n", (unsigned) Attributes);
-
- ExtractionTool =
- LookupGuidedSectionToolPath (
- mParsedGuidedSectionTools,
- EfiGuid
- );
-
- if (ExtractionTool != NULL) {
- #ifndef __GNUC__
- ToolInputFile = CloneString (tmpnam (NULL));
- ToolOutputFile = CloneString (tmpnam (NULL));
- #else
- char tmp1[] = "/tmp/fileXXXXXX";
- char tmp2[] = "/tmp/fileXXXXXX";
- int fd1;
- int fd2;
- fd1 = mkstemp(tmp1);
- fd2 = mkstemp(tmp2);
- ToolInputFile = CloneString(tmp1);
- ToolOutputFile = CloneString(tmp2);
- close(fd1);
- close(fd2);
- #endif
-
- if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) {
- if (ToolInputFile != NULL) {
- free (ToolInputFile);
- }
- if (ToolOutputFile != NULL) {
- free (ToolOutputFile);
- }
- free (ExtractionTool);
-
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Construction 'system' command string
- //
- SystemCommand = malloc (
- strlen (EXTRACT_COMMAND_FORMAT_STRING) +
- strlen (ExtractionTool) +
- strlen (ToolInputFile) +
- strlen (ToolOutputFile) +
- 1
- );
- if (SystemCommand == NULL) {
- free (ToolInputFile);
- free (ToolOutputFile);
- free (ExtractionTool);
-
- Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- return EFI_OUT_OF_RESOURCES;
- }
- sprintf (
- SystemCommand,
- EXTRACT_COMMAND_FORMAT_STRING,
- ExtractionTool,
- ToolOutputFile,
- ToolInputFile
- );
- free (ExtractionTool);
-
- if (!CompareGuid (
- EfiGuid,
- &gEfiCrc32GuidedSectionExtractionProtocolGuid
- )
- ) {
- DataOffset -= 4;
- }
- Status =
- PutFileImage (
- ToolInputFile,
- (CHAR8*)Ptr + DataOffset,
- SectionLength - DataOffset
- );
-
- system (SystemCommand);
- remove (ToolInputFile);
- free (ToolInputFile);
-
- Status =
- GetFileImage (
- ToolOutputFile,
- (CHAR8 **)&ToolOutputBuffer,
- &ToolOutputLength
- );
- remove (ToolOutputFile);
- free (ToolOutputFile);
- free (SystemCommand);
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);
- return EFI_SECTION_ERROR;
- }
-
- printf ("/------------ Encapsulation section start -----------------\\\n");
- Status = ParseSection (
- ToolOutputBuffer,
- ToolOutputLength
- );
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
- return EFI_SECTION_ERROR;
- }
- printf ("\\------------ Encapsulation section end -------------------/\n");
-
- //
- // Check for CRC32 sections which we can handle internally if needed.
- //
- } else if (!CompareGuid (
- EfiGuid,
- &gEfiCrc32GuidedSectionExtractionProtocolGuid
- )
- ) {
- //
- // CRC32 guided section
- //
- printf ("/------------ Encapsulation section start -----------------\\\n");
- Status = ParseSection (
- Ptr + DataOffset,
- SectionLength - DataOffset
- );
- if (EFI_ERROR (Status)) {
- Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);
- return EFI_SECTION_ERROR;
- }
- printf ("\\------------ Encapsulation section end -------------------/\n");
- } else {
- //
- // We don't know how to parse it now.
- //
- Error (NULL, 0, 0003, "Error parsing section", \
- "EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in GuidedSectionTools.txt (built in the FV directory).");
- return EFI_UNSUPPORTED;
- }
- break;
-
- default:
- //
- // Unknown section, return error
- //
- Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);
- return EFI_SECTION_ERROR;
- }
-
- ParsedLength += SectionLength;
- //
- // We make then next section begin on a 4-byte boundary
- //
- ParsedLength = GetOccupiedSize (ParsedLength, 4);
- }
-
- if (ParsedLength < BufferLength) {
- Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);
- return EFI_SECTION_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-DumpDepexSection (
- IN UINT8 *Ptr,
- IN UINT32 SectionLength
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- Ptr - GC_TODO: add argument description
- SectionLength - GC_TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - GC_TODO: Add description for return value
-
---*/
-{
- UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
-
- //
- // Need at least a section header + data
- //
- if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {
- return EFI_SUCCESS;
- }
-
- Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
- SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
- while (SectionLength > 0) {
- printf (" ");
- switch (*Ptr) {
- case EFI_DEP_BEFORE:
- printf ("BEFORE\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_AFTER:
- printf ("AFTER\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_PUSH:
- printf ("PUSH\n ");
- PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);
- printf ("%s ", GuidBuffer);
- PrintGuidName (GuidBuffer);
- printf ("\n");
- //
- // PrintGuid ((EFI_GUID *)(Ptr + 1));
- //
- Ptr += 17;
- SectionLength -= 17;
- break;
-
- case EFI_DEP_AND:
- printf ("AND\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_OR:
- printf ("OR\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_NOT:
- printf ("NOT\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_TRUE:
- printf ("TRUE\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_FALSE:
- printf ("FALSE\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_END:
- printf ("END DEPEX\n");
- Ptr++;
- SectionLength--;
- break;
-
- case EFI_DEP_SOR:
- printf ("SOR\n");
- Ptr++;
- SectionLength--;
- break;
-
- default:
- printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);
- return EFI_SUCCESS;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-PrintGuidName (
- IN UINT8 *GuidStr
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- GuidStr - GC_TODO: add argument description
-
-Returns:
-
- EFI_SUCCESS - GC_TODO: Add description for return value
- EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
-
---*/
-{
- GUID_TO_BASENAME *GPtr;
- //
- // If we have a list of guid-to-basenames, then go through the list to
- // look for a guid string match. If found, print the basename to stdout,
- // otherwise return a failure.
- //
- GPtr = mGuidBaseNameList;
- while (GPtr != NULL) {
- if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {
- printf ("%s", GPtr->BaseName);
- return EFI_SUCCESS;
- }
-
- GPtr = GPtr->Next;
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-EFI_STATUS
-ParseGuidBaseNameFile (
- CHAR8 *FileName
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- FileName - GC_TODO: add argument description
-
-Returns:
-
- EFI_DEVICE_ERROR - GC_TODO: Add description for return value
- EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
- EFI_SUCCESS - GC_TODO: Add description for return value
-
---*/
-{
- FILE *Fptr;
- CHAR8 Line[MAX_LINE_LEN];
- CHAR8 FormatString[MAX_LINE_LEN];
- GUID_TO_BASENAME *GPtr;
-
- if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {
- printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Generate the format string for fscanf
- //
- sprintf (
- FormatString,
- "%%%us %%%us",
- (unsigned) sizeof (GPtr->Guid) - 1,
- (unsigned) sizeof (GPtr->BaseName) - 1
- );
-
- while (fgets (Line, sizeof (Line), Fptr) != NULL) {
- //
- // Allocate space for another guid/basename element
- //
- GPtr = malloc (sizeof (GUID_TO_BASENAME));
- if (GPtr == NULL) {
- fclose (Fptr);
- return EFI_OUT_OF_RESOURCES;
- }
-
- memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));
- if (sscanf (Line, FormatString, GPtr->Guid, GPtr->BaseName) == 2) {
- GPtr->Next = mGuidBaseNameList;
- mGuidBaseNameList = GPtr;
- } else {
- //
- // Some sort of error. Just continue.
- //
- free (GPtr);
- }
- }
-
- fclose (Fptr);
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-FreeGuidBaseNameList (
- VOID
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- None
-
-Returns:
-
- EFI_SUCCESS - GC_TODO: Add description for return value
-
---*/
-{
- GUID_TO_BASENAME *Next;
-
- while (mGuidBaseNameList != NULL) {
- Next = mGuidBaseNameList->Next;
- free (mGuidBaseNameList);
- mGuidBaseNameList = Next;
- }
-
- return EFI_SUCCESS;
-}
-
-
-static
-VOID
-LoadGuidedSectionToolsTxt (
- IN CHAR8* FirmwareVolumeFilename
- )
-{
- CHAR8* PeerFilename;
- CHAR8* Places[] = {
- NULL,
- //NULL,
- };
- UINTN Index;
-
- Places[0] = FirmwareVolumeFilename;
- //Places[1] = mUtilityFilename;
-
- mParsedGuidedSectionTools = NULL;
-
- for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {
- PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");
- //printf("Loading %s...\n", PeerFilename);
- if (OsPathExists (PeerFilename)) {
- mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);
- }
- free (PeerFilename);
- if (mParsedGuidedSectionTools != NULL) {
- return;
- }
- }
-}
-
-
-void
-Usage (
- VOID
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- None
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- //
- // Summary usage
- //
- fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);
-
- //
- // Copyright declaration
- //
- fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
- fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");
-
- //
- // Details Option
- //
- fprintf (stdout, "optional arguments:\n");
- fprintf (stdout, " -h, --help\n\
- Show this help message and exit\n");
- fprintf (stdout, " --version\n\
- Show program's version number and exit\n");
- fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\
- Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
- fprintf (stdout, " -v, --verbose\n\
- Print informational statements\n");
- fprintf (stdout, " -q, --quiet\n\
- Returns the exit code, error messages will be displayed\n");
- fprintf (stdout, " -s, --silent\n\
- Returns only the exit code; informational and error\n\
- messages are not displayed\n");
- fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
- Parse the basename to file-guid cross reference file(s)\n");
- fprintf (stdout, " -f OFFSET, --offset OFFSET\n\
- The offset from the start of the input file to start \n\
- processing an FV\n");
- fprintf (stdout, " --hash\n\
- Generate HASH value of the entire PE image\n");
- fprintf (stdout, " --sfo\n\
- Reserved for future use\n");
-}
-
+/** @file +The tool dumps the contents of a firmware volume + +Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR> +Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com><BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <assert.h> +#ifdef __GNUC__ +#include <unistd.h> +#else +#include <direct.h> +#endif + +#include <FvLib.h> +#include <Common/UefiBaseTypes.h> +#include <Common/UefiCapsule.h> +#include <Common/PiFirmwareFile.h> +#include <Common/PiFirmwareVolume.h> +#include <Guid/PiFirmwareFileSystem.h> +#include <IndustryStandard/PeImage.h> +#include <Protocol/GuidedSectionExtraction.h> + +#include "Compress.h" +#include "Decompress.h" +#include "VolInfo.h" +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" +#include "FirmwareVolumeBufferLib.h" +#include "OsPath.h" +#include "ParseGuidedSectionTools.h" +#include "StringFuncs.h" +#include "ParseInf.h" +#include "PeCoffLib.h" + +// +// Utility global variables +// + +EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; +EFI_GUID gPeiAprioriFileNameGuid = { 0x1b45cc0a, 0x156a, 0x428a, { 0XAF, 0x62, 0x49, 0x86, 0x4d, 0xa0, 0xe6, 0xe6 }}; +EFI_GUID gAprioriGuid = { 0xFC510EE7, 0xFFDC, 0x11D4, { 0xBD, 0x41, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 }}; + +#define UTILITY_MAJOR_VERSION 1 +#define UTILITY_MINOR_VERSION 0 + +#define UTILITY_NAME "VolInfo" + +#define EFI_SECTION_ERROR EFIERR (100) + +// +// Structure to keep a list of guid-to-basenames +// +typedef struct _GUID_TO_BASENAME { + struct _GUID_TO_BASENAME *Next; + INT8 Guid[PRINTED_GUID_BUFFER_SIZE]; + INT8 BaseName[MAX_LINE_LEN]; +} GUID_TO_BASENAME; + +static GUID_TO_BASENAME *mGuidBaseNameList = NULL; + +// +// Store GUIDed Section guid->tool mapping +// +EFI_HANDLE mParsedGuidedSectionTools = NULL; + +CHAR8* mUtilityFilename = NULL; + +BOOLEAN EnableHash = FALSE; +CHAR8 *OpenSslPath = NULL; + +EFI_STATUS +ParseGuidBaseNameFile ( + CHAR8 *FileName + ); + +EFI_STATUS +FreeGuidBaseNameList ( + VOID + ); + +EFI_STATUS +PrintGuidName ( + IN UINT8 *GuidStr + ); + +EFI_STATUS +ParseSection ( + IN UINT8 *SectionBuffer, + IN UINT32 BufferLength + ); + +EFI_STATUS +DumpDepexSection ( + IN UINT8 *Ptr, + IN UINT32 SectionLength + ); + +STATIC +EFI_STATUS +ReadHeader ( + IN FILE *InputFile, + OUT UINT32 *FvSize, + OUT BOOLEAN *ErasePolarity + ); + +STATIC +EFI_STATUS +PrintAprioriFile ( + EFI_FFS_FILE_HEADER *FileHeader + ); + +STATIC +EFI_STATUS +PrintFileInfo ( + EFI_FIRMWARE_VOLUME_HEADER *FvImage, + EFI_FFS_FILE_HEADER *FileHeader, + BOOLEAN ErasePolarity + ); + +static +EFI_STATUS +PrintFvInfo ( + IN VOID *Fv, + IN BOOLEAN IsChildFv + ); + +static +VOID +LoadGuidedSectionToolsTxt ( + IN CHAR8* FirmwareVolumeFilename + ); + +EFI_STATUS +CombinePath ( + IN CHAR8* DefaultPath, + IN CHAR8* AppendPath, + OUT CHAR8* NewPath +); + +void +Usage ( + VOID + ); + +UINT32 +UnicodeStrLen ( + IN CHAR16 *String + ) + /*++ + + Routine Description: + + Returns the length of a null-terminated unicode string. + + Arguments: + + String - The pointer to a null-terminated unicode string. + + Returns: + + N/A + + --*/ +{ + UINT32 Length; + + for (Length = 0; *String != L'\0'; String++, Length++) { + ; + } + return Length; +} + +VOID +Unicode2AsciiString ( + IN CHAR16 *Source, + OUT CHAR8 *Destination + ) + /*++ + + Routine Description: + + Convert a null-terminated unicode string to a null-terminated ascii string. + + Arguments: + + Source - The pointer to the null-terminated input unicode string. + Destination - The pointer to the null-terminated output ascii string. + + Returns: + + N/A + + --*/ +{ + while (*Source != '\0') { + *(Destination++) = (CHAR8) *(Source++); + } + // + // End the ascii with a NULL. + // + *Destination = '\0'; +} + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + argc - GC_TODO: add argument description + ] - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + FILE *InputFile; + int BytesRead; + EFI_FIRMWARE_VOLUME_HEADER *FvImage; + UINT32 FvSize; + EFI_STATUS Status; + int Offset; + BOOLEAN ErasePolarity; + UINT64 LogLevel; + CHAR8 *OpenSslEnv; + CHAR8 *OpenSslCommand; + + SetUtilityName (UTILITY_NAME); + // + // Print utility header + // + printf ("%s Version %d.%d Build %s\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION, + __BUILD_VERSION + ); + + if (argc == 1) { + Usage (); + return -1; + } + + argc--; + argv++; + LogLevel = 0; + Offset = 0; + + // + // Look for help options + // + if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) || + (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) { + Usage(); + return STATUS_SUCCESS; + } + // + // Version has already be printed, so just return success + // + if (strcmp(argv[0], "--version") == 0) { + return STATUS_SUCCESS; + } + + // + // If they specified -x xref guid/basename cross-reference files, process it. + // This will print the basename beside each file guid. To use it, specify + // -x xref_filename to processdsc, then use xref_filename as a parameter + // here. + // + while (argc > 0) { + if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) { + ParseGuidBaseNameFile (argv[1]); + printf("ParseGuidBaseNameFile: %s\n", argv[1]); + argc -= 2; + argv += 2; + continue; + } + if (strcmp(argv[0], "--offset") == 0) { + // + // Hex or decimal? + // + if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) { + if (sscanf (argv[1], "%x", &Offset) != 1) { + Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]); + return GetUtilityStatus (); + } + } else { + if (sscanf (argv[1], "%d", &Offset) != 1) { + Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]); + return GetUtilityStatus (); + } + // + // See if they said something like "64K" + // + if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') { + Offset *= 1024; + } + } + + argc -= 2; + argv += 2; + continue; + } + if ((stricmp (argv[0], "--hash") == 0)) { + if (EnableHash == TRUE) { + // + // --hash already given in the option, ignore this one + // + argc --; + argv ++; + continue; + } + EnableHash = TRUE; + OpenSslCommand = "openssl"; + OpenSslEnv = getenv("OPENSSL_PATH"); + if (OpenSslEnv == NULL) { + OpenSslPath = OpenSslCommand; + } else { + // + // We add quotes to the Openssl Path in case it has space characters + // + OpenSslPath = malloc(2+strlen(OpenSslEnv)+strlen(OpenSslCommand)+1); + if (OpenSslPath == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return GetUtilityStatus (); + } + CombinePath(OpenSslEnv, OpenSslCommand, OpenSslPath); + } + if (OpenSslPath == NULL){ + Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL); + return GetUtilityStatus (); + } + argc --; + argv ++; + continue; + } + + if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) { + SetPrintLevel (VERBOSE_LOG_LEVEL); + argc --; + argv ++; + continue; + } + + if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) { + SetPrintLevel (KEY_LOG_LEVEL); + 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]); + return -1; + } + if (LogLevel > 9) { + Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel); + return -1; + } + SetPrintLevel (LogLevel); + DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]); + argc -= 2; + argv += 2; + continue; + } + + mUtilityFilename = argv[0]; + argc --; + argv ++; + } + + // + // Open the file containing the FV + // + if (mUtilityFilename == NULL) { + Error (NULL, 0, 1001, "Missing option", "Input files are not specified"); + return GetUtilityStatus (); + } + InputFile = fopen (LongFilePath (mUtilityFilename), "rb"); + if (InputFile == NULL) { + Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename); + return GetUtilityStatus (); + } + // + // Skip over pad bytes if specified. This is used if they prepend 0xff + // data to the FV image binary. + // + if (Offset != 0) { + fseek (InputFile, Offset, SEEK_SET); + } + // + // Determine size of FV + // + Status = ReadHeader (InputFile, &FvSize, &ErasePolarity); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename); + fclose (InputFile); + return GetUtilityStatus (); + } + // + // Allocate a buffer for the FV image + // + FvImage = malloc (FvSize); + if (FvImage == NULL) { + Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL); + fclose (InputFile); + return GetUtilityStatus (); + } + // + // Seek to the start of the image, then read the entire FV to the buffer + // + fseek (InputFile, Offset, SEEK_SET); + BytesRead = fread (FvImage, 1, FvSize, InputFile); + fclose (InputFile); + if ((unsigned int) BytesRead != FvSize) { + Error (NULL, 0, 0004, "error reading FvImage from", mUtilityFilename); + free (FvImage); + return GetUtilityStatus (); + } + + LoadGuidedSectionToolsTxt (mUtilityFilename); + + PrintFvInfo (FvImage, FALSE); + + // + // Clean up + // + free (FvImage); + FreeGuidBaseNameList (); + return GetUtilityStatus (); +} + + +static +EFI_STATUS +PrintFvInfo ( + IN VOID *Fv, + IN BOOLEAN IsChildFv + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Fv - Firmware Volume to print information about + IsChildFv - Flag specifies whether the input FV is a child FV. + +Returns: + + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + UINTN NumberOfFiles; + BOOLEAN ErasePolarity; + UINTN FvSize; + EFI_FFS_FILE_HEADER *CurrentFile; + UINTN Key; + + Status = FvBufGetSize (Fv, &FvSize); + + NumberOfFiles = 0; + ErasePolarity = + (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ? + TRUE : FALSE; + + // + // Get the first file + // + Key = 0; + Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image"); + return GetUtilityStatus (); + } + // + // Display information about files found + // + while (CurrentFile != NULL) { + // + // Increment the number of files counter + // + NumberOfFiles++; + + // + // Display info about this file + // + Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV"); + return GetUtilityStatus (); + } + // + // Get the next file + // + Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile); + if (Status == EFI_NOT_FOUND) { + CurrentFile = NULL; + } else if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image"); + return GetUtilityStatus (); + } + } + + if (IsChildFv) { + printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles); + } else { + printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles); + } + + return EFI_SUCCESS; +} + +UINT32 +GetOccupiedSize ( + IN UINT32 ActualSize, + IN UINT32 Alignment + ) +/*++ + +Routine Description: + + This function returns the next larger size that meets the alignment + requirement specified. + +Arguments: + + ActualSize The size. + Alignment The desired alignment. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_ABORTED The function encountered an error. + +--*/ +{ + UINT32 OccupiedSize; + + OccupiedSize = ActualSize; + while ((OccupiedSize & (Alignment - 1)) != 0) { + OccupiedSize++; + } + + return OccupiedSize; +} + +static +CHAR8 * +SectionNameToStr ( + IN EFI_SECTION_TYPE Type + ) +/*++ + +Routine Description: + + Converts EFI Section names to Strings + +Arguments: + + Type - The EFI Section type + +Returns: + + CHAR8* - Pointer to the String containing the section name. + +--*/ +{ + CHAR8 *SectionStr; + CHAR8 *SectionTypeStringTable[] = { + // + // 0X00 + // + "EFI_SECTION_ALL", + // + // 0x01 + // + "EFI_SECTION_COMPRESSION", + // + // 0x02 + // + "EFI_SECTION_GUID_DEFINED", + // + // 0x03 + // + "Unknown section type - Reserved 0x03", + // + // 0x04 + // + "Unknown section type - Reserved 0x04", + // + // 0x05 + // + "Unknown section type - Reserved 0x05", + // + // 0x06 + // + "Unknown section type - Reserved 0x06", + // + // 0x07 + // + "Unknown section type - Reserved 0x07", + // + // 0x08 + // + "Unknown section type - Reserved 0x08", + // + // 0x09 + // + "Unknown section type - Reserved 0x09", + // + // 0x0A + // + "Unknown section type - Reserved 0x0A", + // + // 0x0B + // + "Unknown section type - Reserved 0x0B", + // + // 0x0C + // + "Unknown section type - Reserved 0x0C", + // + // 0x0D + // + "Unknown section type - Reserved 0x0D", + // + // 0x0E + // + "Unknown section type - Reserved 0x0E", + // + // 0x0F + // + "Unknown section type - Reserved 0x0E", + // + // 0x10 + // + "EFI_SECTION_PE32", + // + // 0x11 + // + "EFI_SECTION_PIC", + // + // 0x12 + // + "EFI_SECTION_TE", + // + // 0x13 + // + "EFI_SECTION_DXE_DEPEX", + // + // 0x14 + // + "EFI_SECTION_VERSION", + // + // 0x15 + // + "EFI_SECTION_USER_INTERFACE", + // + // 0x16 + // + "EFI_SECTION_COMPATIBILITY16", + // + // 0x17 + // + "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", + // + // 0x18 + // + "EFI_SECTION_FREEFORM_SUBTYPE_GUID", + // + // 0x19 + // + "EFI_SECTION_RAW", + // + // 0x1A + // + "Unknown section type - 0x1A", + // + // 0x1B + // + "EFI_SECTION_PEI_DEPEX", + // + // 0x1C + // + "EFI_SECTION_MM_DEPEX", + // + // 0x1C+ + // + "Unknown section type - Reserved - beyond last defined section" + }; + + if (Type > EFI_SECTION_LAST_SECTION_TYPE) { + Type = EFI_SECTION_LAST_SECTION_TYPE + 1; + } + + SectionStr = malloc (100); + if (SectionStr == NULL) { + printf ("Error: Out of memory resources.\n"); + return SectionStr; + } + strcpy (SectionStr, SectionTypeStringTable[Type]); + return SectionStr; +} + +STATIC +EFI_STATUS +ReadHeader ( + IN FILE *InputFile, + OUT UINT32 *FvSize, + OUT BOOLEAN *ErasePolarity + ) +/*++ + +Routine Description: + + This function determines the size of the FV and the erase polarity. The + erase polarity is the FALSE value for file state. + +Arguments: + + InputFile The file that contains the FV image. + FvSize The size of the FV. + ErasePolarity The FV erase polarity. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. + EFI_ABORTED The function encountered an error. + +--*/ +{ + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; + EFI_FV_BLOCK_MAP_ENTRY BlockMap; + UINTN Signature[2]; + UINTN BytesRead; + UINT32 Size; + size_t ReadSize; + + BytesRead = 0; + Size = 0; + // + // Check input parameters + // + if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function"); + return EFI_INVALID_PARAMETER; + } + // + // Read the header + // + ReadSize = fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); + if (ReadSize != 1) { + return EFI_ABORTED; + } + BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY); + Signature[0] = VolumeHeader.Signature; + Signature[1] = 0; + + // + // Print FV header information + // + printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature); + printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes); + + if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) { + printf (" EFI_FVB2_READ_DISABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) { + printf (" EFI_FVB2_READ_ENABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) { + printf (" EFI_FVB2_READ_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) { + printf (" EFI_FVB2_WRITE_DISABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) { + printf (" EFI_FVB2_WRITE_ENABLED_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) { + printf (" EFI_FVB2_WRITE_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) { + printf (" EFI_FVB2_LOCK_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) { + printf (" EFI_FVB2_LOCK_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) { + printf (" EFI_FVB2_STICKY_WRITE\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) { + printf (" EFI_FVB2_MEMORY_MAPPED\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) { + printf (" EFI_FVB2_ERASE_POLARITY\n"); + *ErasePolarity = TRUE; + } + +#if (PI_SPECIFICATION_VERSION < 0x00010000) + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) { + printf (" EFI_FVB2_ALIGNMENT\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) { + printf (" EFI_FVB2_ALIGNMENT_2\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) { + printf (" EFI_FVB2_ALIGNMENT_4\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) { + printf (" EFI_FVB2_ALIGNMENT_8\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) { + printf (" EFI_FVB2_ALIGNMENT_16\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) { + printf (" EFI_FVB2_ALIGNMENT_32\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) { + printf (" EFI_FVB2_ALIGNMENT_64\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) { + printf (" EFI_FVB2_ALIGNMENT_128\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) { + printf (" EFI_FVB2_ALIGNMENT_256\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) { + printf (" EFI_FVB2_ALIGNMENT_512\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) { + printf (" EFI_FVB2_ALIGNMENT_1K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) { + printf (" EFI_FVB2_ALIGNMENT_2K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) { + printf (" EFI_FVB2_ALIGNMENT_4K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) { + printf (" EFI_FVB2_ALIGNMENT_8K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) { + printf (" EFI_FVB2_ALIGNMENT_16K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) { + printf (" EFI_FVB2_ALIGNMENT_32K\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) { + printf (" EFI_FVB2_ALIGNMENT_64K\n"); + } + +#else + + if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) { + printf (" EFI_FVB2_READ_LOCK_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) { + printf (" EFI_FVB2_READ_LOCK_STATUS\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) { + printf (" EFI_FVB2_WRITE_LOCK_CAP\n"); + } + + if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) { + printf (" EFI_FVB2_WRITE_LOCK_STATUS\n"); + } + + switch (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) { + case EFI_FVB2_ALIGNMENT_1: + printf (" EFI_FVB2_ALIGNMENT_1\n"); + break; + + case EFI_FVB2_ALIGNMENT_2: + printf (" EFI_FVB2_ALIGNMENT_2\n"); + break; + + case EFI_FVB2_ALIGNMENT_4: + printf (" EFI_FVB2_ALIGNMENT_4\n"); + break; + + case EFI_FVB2_ALIGNMENT_8: + printf (" EFI_FVB2_ALIGNMENT_8\n"); + break; + + case EFI_FVB2_ALIGNMENT_16: + printf (" EFI_FVB2_ALIGNMENT_16\n"); + break; + + case EFI_FVB2_ALIGNMENT_32: + printf (" EFI_FVB2_ALIGNMENT_32\n"); + break; + + case EFI_FVB2_ALIGNMENT_64: + printf (" EFI_FVB2_ALIGNMENT_64\n"); + break; + + case EFI_FVB2_ALIGNMENT_128: + printf (" EFI_FVB2_ALIGNMENT_128\n"); + break; + + case EFI_FVB2_ALIGNMENT_256: + printf (" EFI_FVB2_ALIGNMENT_256\n"); + break; + + case EFI_FVB2_ALIGNMENT_512: + printf (" EFI_FVB2_ALIGNMENT_512\n"); + break; + + case EFI_FVB2_ALIGNMENT_1K: + printf (" EFI_FVB2_ALIGNMENT_1K\n"); + break; + + case EFI_FVB2_ALIGNMENT_2K: + printf (" EFI_FVB2_ALIGNMENT_2K\n"); + break; + + case EFI_FVB2_ALIGNMENT_4K: + printf (" EFI_FVB2_ALIGNMENT_4K\n"); + break; + + case EFI_FVB2_ALIGNMENT_8K: + printf (" EFI_FVB2_ALIGNMENT_8K\n"); + break; + + case EFI_FVB2_ALIGNMENT_16K: + printf (" EFI_FVB2_ALIGNMENT_16K\n"); + break; + + case EFI_FVB2_ALIGNMENT_32K: + printf (" EFI_FVB2_ALIGNMENT_32K\n"); + break; + + case EFI_FVB2_ALIGNMENT_64K: + printf (" EFI_FVB2_ALIGNMENT_64K\n"); + break; + + case EFI_FVB2_ALIGNMENT_128K: + printf (" EFI_FVB2_ALIGNMENT_128K\n"); + break; + + case EFI_FVB2_ALIGNMENT_256K: + printf (" EFI_FVB2_ALIGNMENT_256K\n"); + break; + + case EFI_FVB2_ALIGNMENT_512K: + printf (" EFI_FVB2_ALIGNMENT_512K\n"); + break; + + case EFI_FVB2_ALIGNMENT_1M: + printf (" EFI_FVB2_ALIGNMENT_1M\n"); + break; + + case EFI_FVB2_ALIGNMENT_2M: + printf (" EFI_FVB2_ALIGNMENT_2M\n"); + break; + + case EFI_FVB2_ALIGNMENT_4M: + printf (" EFI_FVB2_ALIGNMENT_4M\n"); + break; + + case EFI_FVB2_ALIGNMENT_8M: + printf (" EFI_FVB2_ALIGNMENT_8M\n"); + break; + + case EFI_FVB2_ALIGNMENT_16M: + printf (" EFI_FVB2_ALIGNMENT_16M\n"); + break; + + case EFI_FVB2_ALIGNMENT_32M: + printf (" EFI_FVB2_ALIGNMENT_32M\n"); + break; + + case EFI_FVB2_ALIGNMENT_64M: + printf (" EFI_FVB2_ALIGNMENT_64M\n"); + break; + + case EFI_FVB2_ALIGNMENT_128M: + printf (" EFI_FVB2_ALIGNMENT_128M\n"); + break; + + case EFI_FVB2_ALIGNMENT_256M: + printf (" EFI_FVB2_ALIGNMENT_256M\n"); + break; + + case EFI_FVB2_ALIGNMENT_512M: + printf (" EFI_FVB2_ALIGNMENT_512M\n"); + break; + + case EFI_FVB2_ALIGNMENT_1G: + printf (" EFI_FVB2_ALIGNMENT_1G\n"); + break; + + case EFI_FVB2_ALIGNMENT_2G: + printf (" EFI_FVB2_ALIGNMENT_2G\n"); + break; + } + +#endif + printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength); + printf ("File System ID: "); + PrintGuid (&VolumeHeader.FileSystemGuid); + // + // printf ("\n"); + // + printf ("Revision: 0x%04X\n", VolumeHeader.Revision); + + do { + ReadSize = fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); + if (ReadSize != 1) { + return EFI_ABORTED; + } + BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY); + + if (BlockMap.NumBlocks != 0) { + printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks); + printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length); + Size += BlockMap.NumBlocks * BlockMap.Length; + } + + } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0)); + + if (BytesRead != VolumeHeader.HeaderLength) { + printf ("ERROR: Header length not consistent with Block Maps!\n"); + return EFI_ABORTED; + } + + if (VolumeHeader.FvLength != Size) { + printf ("ERROR: Volume Size not consistent with Block Maps!\n"); + return EFI_ABORTED; + } + + printf ("Total Volume Size: 0x%08X\n", (unsigned) Size); + + *FvSize = Size; + + // + // rewind (InputFile); + // + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +PrintAprioriFile ( + EFI_FFS_FILE_HEADER *FileHeader + ) +/*++ + +Routine Description: + + Print GUIDs from the APRIORI file + +Arguments: + + FileHeader - The file header + +Returns: + + EFI_SUCCESS - The APRIORI file was parsed correctly + EFI_SECTION_ERROR - Problem with file parsing + +--*/ +{ + UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE]; + UINT32 HeaderSize; + + HeaderSize = FvBufGetFfsHeaderSize (FileHeader); + + if (FileHeader->Type != EFI_FV_FILETYPE_FREEFORM) + return EFI_SECTION_ERROR; + + EFI_COMMON_SECTION_HEADER* SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) FileHeader + HeaderSize); + if (SectionHeader->Type != EFI_SECTION_RAW) + return EFI_SECTION_ERROR; + + UINT32 SectionLength = GetSectionFileLength (SectionHeader); + EFI_GUID* FileName = (EFI_GUID *) ((UINT8 *) SectionHeader + sizeof (EFI_COMMON_SECTION_HEADER)); + while (((UINT8 *) FileName) < ((UINT8 *) SectionHeader + SectionLength)) { + PrintGuidToBuffer (FileName, GuidBuffer, sizeof (GuidBuffer), TRUE); + printf ("%s ", GuidBuffer); + PrintGuidName (GuidBuffer); + printf ("\n"); + FileName++; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +PrintFileInfo ( + EFI_FIRMWARE_VOLUME_HEADER *FvImage, + EFI_FFS_FILE_HEADER *FileHeader, + BOOLEAN ErasePolarity + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FvImage - GC_TODO: add argument description + FileHeader - GC_TODO: add argument description + ErasePolarity - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + EFI_ABORTED - GC_TODO: Add description for return value + +--*/ +{ + UINT32 FileLength; + UINT8 FileState; + UINT8 Checksum; + EFI_FFS_FILE_HEADER2 BlankHeader; + EFI_STATUS Status; + UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE]; + UINT32 HeaderSize; +#if (PI_SPECIFICATION_VERSION < 0x00010000) + UINT16 *Tail; +#endif + // + // Check if we have free space + // + HeaderSize = FvBufGetFfsHeaderSize(FileHeader); + if (ErasePolarity) { + memset (&BlankHeader, -1, HeaderSize); + } else { + memset (&BlankHeader, 0, HeaderSize); + } + + if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) { + return EFI_SUCCESS; + } + // + // Print file information. + // + printf ("============================================================\n"); + + printf ("File Name: "); + PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE); + printf ("%s ", GuidBuffer); + PrintGuidName (GuidBuffer); + printf ("\n"); + + // + // PrintGuid (&FileHeader->Name); + // printf ("\n"); + // + FileLength = FvBufGetFfsFileSize (FileHeader); + printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage)); + printf ("File Length: 0x%08X\n", (unsigned) FileLength); + printf ("File Attributes: 0x%02X\n", FileHeader->Attributes); + printf ("File State: 0x%02X\n", FileHeader->State); + + // + // Print file state + // + FileState = GetFileState (ErasePolarity, FileHeader); + + switch (FileState) { + + case EFI_FILE_HEADER_CONSTRUCTION: + printf (" EFI_FILE_HEADER_CONSTRUCTION\n"); + return EFI_SUCCESS; + + case EFI_FILE_HEADER_INVALID: + printf (" EFI_FILE_HEADER_INVALID\n"); + return EFI_SUCCESS; + + case EFI_FILE_HEADER_VALID: + printf (" EFI_FILE_HEADER_VALID\n"); + Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize); + Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + printf ("ERROR: Header checksum invalid.\n"); + return EFI_ABORTED; + } + + return EFI_SUCCESS; + + case EFI_FILE_DELETED: + printf (" EFI_FILE_DELETED\n"); + + case EFI_FILE_MARKED_FOR_UPDATE: + printf (" EFI_FILE_MARKED_FOR_UPDATE\n"); + + case EFI_FILE_DATA_VALID: + printf (" EFI_FILE_DATA_VALID\n"); + + // + // Calculate header checksum + // + Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize); + Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File); + Checksum = (UINT8) (Checksum - FileHeader->State); + if (Checksum != 0) { + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer); + return EFI_ABORTED; + } + + FileLength = FvBufGetFfsFileSize (FileHeader); + + if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { + // + // Calculate file checksum + // + Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize); + Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File; + if (Checksum != 0) { + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer); + return EFI_ABORTED; + } + } else { + if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum -- not set to fixed value of 0xAA", GuidBuffer); + return EFI_ABORTED; + } + } +#if (PI_SPECIFICATION_VERSION < 0x00010000) + // + // Verify tail if present + // + if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + // + // Verify tail is complement of integrity check field in the header. + // + Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK)); + if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) { + Error (NULL, 0, 0003, "error parsing FFS file", \ + "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer); + return EFI_ABORTED; + } + } + #endif + break; + + default: + Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer); + return EFI_ABORTED; + } + + printf ("File Type: 0x%02X ", FileHeader->Type); + + switch (FileHeader->Type) { + + case EFI_FV_FILETYPE_RAW: + printf ("EFI_FV_FILETYPE_RAW\n"); + break; + + case EFI_FV_FILETYPE_FREEFORM: + printf ("EFI_FV_FILETYPE_FREEFORM\n"); + break; + + case EFI_FV_FILETYPE_SECURITY_CORE: + printf ("EFI_FV_FILETYPE_SECURITY_CORE\n"); + break; + + case EFI_FV_FILETYPE_PEI_CORE: + printf ("EFI_FV_FILETYPE_PEI_CORE\n"); + break; + + case EFI_FV_FILETYPE_DXE_CORE: + printf ("EFI_FV_FILETYPE_DXE_CORE\n"); + break; + + case EFI_FV_FILETYPE_PEIM: + printf ("EFI_FV_FILETYPE_PEIM\n"); + break; + + case EFI_FV_FILETYPE_DRIVER: + printf ("EFI_FV_FILETYPE_DRIVER\n"); + break; + + case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: + printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n"); + break; + + case EFI_FV_FILETYPE_APPLICATION: + printf ("EFI_FV_FILETYPE_APPLICATION\n"); + break; + + case EFI_FV_FILETYPE_SMM: + printf ("EFI_FV_FILETYPE_MM\n"); + break; + + case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: + printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n"); + break; + + case EFI_FV_FILETYPE_COMBINED_SMM_DXE: + printf ("EFI_FV_FILETYPE_COMBINED_MM_DXE\n"); + break; + + case EFI_FV_FILETYPE_SMM_CORE: + printf ("EFI_FV_FILETYPE_MM_CORE\n"); + break; + + case EFI_FV_FILETYPE_MM_STANDALONE: + printf ("EFI_FV_FILETYPE_MM_STANDALONE\n"); + break; + + case EFI_FV_FILETYPE_MM_CORE_STANDALONE: + printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n"); + break; + + case EFI_FV_FILETYPE_FFS_PAD: + printf ("EFI_FV_FILETYPE_FFS_PAD\n"); + break; + + default: + printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type); + return EFI_ABORTED; + break; + } + + switch (FileHeader->Type) { + + case EFI_FV_FILETYPE_ALL: + case EFI_FV_FILETYPE_RAW: + case EFI_FV_FILETYPE_FFS_PAD: + break; + + default: + // + // All other files have sections + // + Status = ParseSection ( + (UINT8 *) ((UINTN) FileHeader + HeaderSize), + FvBufGetFfsFileSize (FileHeader) - HeaderSize + ); + if (EFI_ERROR (Status)) { + // + // printf ("ERROR: Parsing the FFS file.\n"); + // + return EFI_ABORTED; + } + break; + } + + if (!CompareGuid ( + &FileHeader->Name, + &gPeiAprioriFileNameGuid + )) + { + printf("\n"); + printf("PEI APRIORI FILE:\n"); + return PrintAprioriFile (FileHeader); + } + if (!CompareGuid ( + &FileHeader->Name, + &gAprioriGuid + )) + { + printf("\n"); + printf("DXE APRIORI FILE:\n"); + return PrintAprioriFile (FileHeader); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +RebaseImageRead ( + 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 +SetAddressToSectionHeader ( + IN CHAR8 *FileName, + IN OUT UINT8 *FileBuffer, + IN UINT64 NewPe32BaseAddress + ) +/*++ + +Routine Description: + + Set new base address into the section header of PeImage + +Arguments: + + FileName - Name of file + FileBuffer - Pointer to PeImage. + NewPe32BaseAddress - New Base Address for PE image. + +Returns: + + EFI_SUCCESS Set new base address into this image successfully. + +--*/ +{ + EFI_STATUS Status; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINTN Index; + EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; + EFI_IMAGE_SECTION_HEADER *SectionHeader; + + // + // Initialize context + // + memset (&ImageContext, 0, sizeof (ImageContext)); + ImageContext.Handle = (VOID *) FileBuffer; + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); + return Status; + } + + if (ImageContext.RelocationsStripped) { + Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); + return Status; + } + + // + // Get PeHeader pointer + // + ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); + + // + // Get section header list + // + SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( + (UINTN) ImgHdr + + sizeof (UINT32) + + sizeof (EFI_IMAGE_FILE_HEADER) + + ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader + ); + + // + // Set base address into the first section header that doesn't point to code section. + // + for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { + if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { + *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress; + break; + } + } + + // + // BaseAddress is set to section header. + // + return EFI_SUCCESS; +} + +EFI_STATUS +RebaseImage ( + IN CHAR8 *FileName, + IN OUT UINT8 *FileBuffer, + IN UINT64 NewPe32BaseAddress + ) +/*++ + +Routine Description: + + Set new base address into PeImage, and fix up PeImage based on new address. + +Arguments: + + FileName - Name of file + FileBuffer - Pointer to PeImage. + NewPe32BaseAddress - New Base Address for PE image. + +Returns: + + EFI_INVALID_PARAMETER - BaseAddress is not valid. + EFI_SUCCESS - Update PeImage is correctly. + +--*/ +{ + EFI_STATUS Status; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINTN Index; + EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; + UINT8 *MemoryImagePointer; + EFI_IMAGE_SECTION_HEADER *SectionHeader; + + // + // Initialize context + // + memset (&ImageContext, 0, sizeof (ImageContext)); + ImageContext.Handle = (VOID *) FileBuffer; + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); + return Status; + } + + if (ImageContext.RelocationsStripped) { + Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); + return Status; + } + + // + // Get PeHeader pointer + // + ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); + + // + // 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) & (~((INT64)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 ( + FileBuffer + SectionHeader->PointerToRawData, + (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), + SectionHeader->SizeOfRawData + ); + } + + free ((VOID *) MemoryImagePointer); + + // + // 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; + } + + // + // Set new base address into section header + // + Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress); + + return Status; +} + +EFI_STATUS +CombinePath ( + IN CHAR8* DefaultPath, + IN CHAR8* AppendPath, + OUT CHAR8* NewPath +) +{ + UINT32 DefaultPathLen; + UINT64 Index; + CHAR8 QuotesStr[] = "\""; + strcpy(NewPath, QuotesStr); + DefaultPathLen = strlen(DefaultPath); + strcat(NewPath, DefaultPath); + Index = 0; + for (; Index < DefaultPathLen + 1; Index ++) { + if (NewPath[Index] == '\\' || NewPath[Index] == '/') { + if (NewPath[Index + 1] != '\0') { + NewPath[Index] = '/'; + } + } + } + if (NewPath[Index -1] != '/') { + NewPath[Index] = '/'; + NewPath[Index + 1] = '\0'; + } + strcat(NewPath, AppendPath); + strcat(NewPath, QuotesStr); + return EFI_SUCCESS; +} + +EFI_STATUS +ParseSection ( + IN UINT8 *SectionBuffer, + IN UINT32 BufferLength + ) +/*++ + +Routine Description: + + Parses EFI Sections + +Arguments: + + SectionBuffer - Buffer containing the section to parse. + BufferLength - Length of SectionBuffer + +Returns: + + EFI_SECTION_ERROR - Problem with section parsing. + (a) compression errors + (b) unrecognized section + EFI_UNSUPPORTED - Do not know how to parse the section. + EFI_SUCCESS - Section successfully parsed. + EFI_OUT_OF_RESOURCES - Memory allocation failed. + +--*/ +{ + EFI_SECTION_TYPE Type; + UINT8 *Ptr; + UINT32 SectionLength; + UINT32 SectionHeaderLen; + CHAR8 *SectionName; + EFI_STATUS Status; + UINT32 ParsedLength; + UINT8 *CompressedBuffer; + UINT32 CompressedLength; + UINT8 *UncompressedBuffer; + UINT32 UncompressedLength; + UINT8 *ToolOutputBuffer; + UINT32 ToolOutputLength; + UINT8 CompressionType; + UINT32 DstSize; + UINT32 ScratchSize; + UINT8 *ScratchBuffer; + DECOMPRESS_FUNCTION DecompressFunction; + GETINFO_FUNCTION GetInfoFunction; + // CHAR16 *name; + CHAR8 *ExtractionTool; + CHAR8 *ToolInputFile; + CHAR8 *ToolOutputFile; + CHAR8 *SystemCommand; + EFI_GUID *EfiGuid; + UINT16 DataOffset; + UINT16 Attributes; + UINT32 RealHdrLen; + CHAR8 *ToolInputFileName; + CHAR8 *ToolOutputFileName; + CHAR8 *UIFileName; + CHAR8 *VersionString; + + ParsedLength = 0; + ToolInputFileName = NULL; + ToolOutputFileName = NULL; + + while (ParsedLength < BufferLength) { + Ptr = SectionBuffer + ParsedLength; + + SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size); + Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type; + + // + // This is sort of an odd check, but is necessary because FFS files are + // padded to a QWORD boundary, meaning there is potentially a whole section + // header worth of 0xFF bytes. + // + if (SectionLength == 0xffffff && Type == 0xff) { + ParsedLength += 4; + continue; + } + + // + // Get real section file size + // + SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr); + SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr); + + SectionName = SectionNameToStr (Type); + if (SectionName != NULL) { + printf ("------------------------------------------------------------\n"); + printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength); + free (SectionName); + } + + switch (Type) { + case EFI_SECTION_RAW: + case EFI_SECTION_PIC: + case EFI_SECTION_TE: + // default is no more information + break; + + case EFI_SECTION_PE32: + if (EnableHash) { + ToolInputFileName = "edk2Temp_InputEfi.tmp"; + ToolOutputFileName = "edk2Temp_OutputHash.tmp"; + RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0); + PutFileImage ( + ToolInputFileName, + (CHAR8*)Ptr + SectionHeaderLen, + SectionLength - SectionHeaderLen + ); + + SystemCommand = malloc ( + strlen (OPENSSL_COMMAND_FORMAT_STRING) + + strlen (OpenSslPath) + + strlen (ToolInputFileName) + + strlen (ToolOutputFileName) + + 1 + ); + if (SystemCommand == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + sprintf ( + SystemCommand, + OPENSSL_COMMAND_FORMAT_STRING, + OpenSslPath, + ToolOutputFileName, + ToolInputFileName + ); + + if (system (SystemCommand) != EFI_SUCCESS) { + Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL); + } + else { + FILE *fp; + CHAR8 *StrLine; + CHAR8 *NewStr; + UINT32 nFileLen; + if((fp = fopen(ToolOutputFileName,"r")) == NULL) { + Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL); + } + else { + fseek(fp,0,SEEK_SET); + fseek(fp,0,SEEK_END); + nFileLen = ftell(fp); + fseek(fp,0,SEEK_SET); + StrLine = malloc(nFileLen); + if (StrLine == NULL) { + fclose(fp); + free (SystemCommand); + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + fgets(StrLine, nFileLen, fp); + NewStr = strrchr (StrLine, '='); + printf (" SHA1: %s\n", NewStr + 1); + free (StrLine); + fclose(fp); + } + } + remove(ToolInputFileName); + remove(ToolOutputFileName); + free (SystemCommand); + } + break; + + case EFI_SECTION_USER_INTERFACE: + UIFileName = (CHAR8 *) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString) + 1); + if (UIFileName == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString, UIFileName); + printf (" String: %s\n", UIFileName); + free (UIFileName); + break; + + case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: + printf ("/------------ Firmware Volume section start ---------------\\\n"); + Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "printing of FV section contents failed", NULL); + return EFI_SECTION_ERROR; + } + printf ("\\------------ Firmware Volume section end -----------------/\n"); + break; + + case EFI_SECTION_COMPATIBILITY16: + // + // Section does not contain any further header information. + // + break; + + case EFI_SECTION_FREEFORM_SUBTYPE_GUID: + printf (" Guid: "); + if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) + PrintGuid (&((EFI_FREEFORM_SUBTYPE_GUID_SECTION *)Ptr)->SubTypeGuid); + else + PrintGuid (&((EFI_FREEFORM_SUBTYPE_GUID_SECTION2 *)Ptr)->SubTypeGuid); + printf ("\n"); + break; + + case EFI_SECTION_PEI_DEPEX: + case EFI_SECTION_DXE_DEPEX: + case EFI_SECTION_SMM_DEPEX: + DumpDepexSection (Ptr, SectionLength); + break; + + case EFI_SECTION_VERSION: + printf (" Build Number: 0x%04X\n", *(UINT16 *)(Ptr + SectionHeaderLen)); + VersionString = (CHAR8 *) malloc (UnicodeStrLen (((EFI_VERSION_SECTION *) Ptr)->VersionString) + 1); + if (VersionString == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + Unicode2AsciiString (((EFI_VERSION_SECTION *) Ptr)->VersionString, VersionString); + printf (" Version String: %s\n", VersionString); + break; + + case EFI_SECTION_COMPRESSION: + UncompressedBuffer = NULL; + if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) { + RealHdrLen = sizeof(EFI_COMPRESSION_SECTION); + UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength; + CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType; + } else { + RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2); + UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength; + CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType; + } + CompressedLength = SectionLength - RealHdrLen; + printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength); + + if (CompressionType == EFI_NOT_COMPRESSED) { + printf (" Compression Type: EFI_NOT_COMPRESSED\n"); + if (CompressedLength != UncompressedLength) { + Error ( + NULL, + 0, + 0, + "file is not compressed, but the compressed length does not match the uncompressed length", + NULL + ); + return EFI_SECTION_ERROR; + } + + UncompressedBuffer = Ptr + RealHdrLen; + } else if (CompressionType == EFI_STANDARD_COMPRESSION) { + GetInfoFunction = EfiGetInfo; + DecompressFunction = EfiDecompress; + printf (" Compression Type: EFI_STANDARD_COMPRESSION\n"); + + CompressedBuffer = Ptr + RealHdrLen; + + Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "error getting compression info from compression section", NULL); + return EFI_SECTION_ERROR; + } + + if (DstSize != UncompressedLength) { + Error (NULL, 0, 0003, "compression error in the compression section", NULL); + return EFI_SECTION_ERROR; + } + + ScratchBuffer = malloc (ScratchSize); + if (ScratchBuffer == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + UncompressedBuffer = malloc (UncompressedLength); + if (UncompressedBuffer == NULL) { + free (ScratchBuffer); + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + Status = DecompressFunction ( + CompressedBuffer, + CompressedLength, + UncompressedBuffer, + UncompressedLength, + ScratchBuffer, + ScratchSize + ); + free (ScratchBuffer); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "decompress failed", NULL); + free (UncompressedBuffer); + return EFI_SECTION_ERROR; + } + } else { + Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType); + return EFI_SECTION_ERROR; + } + + printf ("/------------ Encapsulation section start -----------------\\\n"); + Status = ParseSection (UncompressedBuffer, UncompressedLength); + printf ("\\------------ Encapsulation section end -------------------/\n"); + + if (CompressionType == EFI_STANDARD_COMPRESSION) { + // + // We need to deallocate Buffer + // + free (UncompressedBuffer); + } + + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "failed to parse section", NULL); + return EFI_SECTION_ERROR; + } + break; + + case EFI_SECTION_GUID_DEFINED: + if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) { + EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid; + DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset; + Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes; + } else { + EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid; + DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset; + Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes; + } + printf (" SectionDefinitionGuid: "); + PrintGuid (EfiGuid); + printf ("\n"); + printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset); + printf (" Attributes: 0x%04X\n", (unsigned) Attributes); + + ExtractionTool = + LookupGuidedSectionToolPath ( + mParsedGuidedSectionTools, + EfiGuid + ); + + if (ExtractionTool != NULL) { + #ifndef __GNUC__ + ToolInputFile = CloneString (tmpnam (NULL)); + ToolOutputFile = CloneString (tmpnam (NULL)); + #else + char tmp1[] = "/tmp/fileXXXXXX"; + char tmp2[] = "/tmp/fileXXXXXX"; + int fd1; + int fd2; + fd1 = mkstemp(tmp1); + fd2 = mkstemp(tmp2); + ToolInputFile = CloneString(tmp1); + ToolOutputFile = CloneString(tmp2); + close(fd1); + close(fd2); + #endif + + if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) { + if (ToolInputFile != NULL) { + free (ToolInputFile); + } + if (ToolOutputFile != NULL) { + free (ToolOutputFile); + } + free (ExtractionTool); + + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + + // + // Construction 'system' command string + // + SystemCommand = malloc ( + strlen (EXTRACT_COMMAND_FORMAT_STRING) + + strlen (ExtractionTool) + + strlen (ToolInputFile) + + strlen (ToolOutputFile) + + 1 + ); + if (SystemCommand == NULL) { + free (ToolInputFile); + free (ToolOutputFile); + free (ExtractionTool); + + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + return EFI_OUT_OF_RESOURCES; + } + sprintf ( + SystemCommand, + EXTRACT_COMMAND_FORMAT_STRING, + ExtractionTool, + ToolOutputFile, + ToolInputFile + ); + free (ExtractionTool); + + if (!CompareGuid ( + EfiGuid, + &gEfiCrc32GuidedSectionExtractionProtocolGuid + ) + ) { + DataOffset -= 4; + } + Status = + PutFileImage ( + ToolInputFile, + (CHAR8*)Ptr + DataOffset, + SectionLength - DataOffset + ); + + system (SystemCommand); + remove (ToolInputFile); + free (ToolInputFile); + + Status = + GetFileImage ( + ToolOutputFile, + (CHAR8 **)&ToolOutputBuffer, + &ToolOutputLength + ); + remove (ToolOutputFile); + free (ToolOutputFile); + free (SystemCommand); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL); + return EFI_SECTION_ERROR; + } + + printf ("/------------ Encapsulation section start -----------------\\\n"); + Status = ParseSection ( + ToolOutputBuffer, + ToolOutputLength + ); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL); + return EFI_SECTION_ERROR; + } + printf ("\\------------ Encapsulation section end -------------------/\n"); + + // + // Check for CRC32 sections which we can handle internally if needed. + // + } else if (!CompareGuid ( + EfiGuid, + &gEfiCrc32GuidedSectionExtractionProtocolGuid + ) + ) { + // + // CRC32 guided section + // + printf ("/------------ Encapsulation section start -----------------\\\n"); + Status = ParseSection ( + Ptr + DataOffset, + SectionLength - DataOffset + ); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL); + return EFI_SECTION_ERROR; + } + printf ("\\------------ Encapsulation section end -------------------/\n"); + } else { + // + // We don't know how to parse it now. + // + Error (NULL, 0, 0003, "Error parsing section", \ + "EFI_SECTION_GUID_DEFINED cannot be parsed at this time. Tool to decode this section should have been defined in GuidedSectionTools.txt (built in the FV directory)."); + return EFI_UNSUPPORTED; + } + break; + + default: + // + // Unknown section, return error + // + Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type); + return EFI_SECTION_ERROR; + } + + ParsedLength += SectionLength; + // + // We make then next section begin on a 4-byte boundary + // + ParsedLength = GetOccupiedSize (ParsedLength, 4); + } + + if (ParsedLength < BufferLength) { + Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL); + return EFI_SECTION_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +DumpDepexSection ( + IN UINT8 *Ptr, + IN UINT32 SectionLength + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Ptr - GC_TODO: add argument description + SectionLength - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE]; + + // + // Need at least a section header + data + // + if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) { + return EFI_SUCCESS; + } + + Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr); + SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr); + while (SectionLength > 0) { + printf (" "); + switch (*Ptr) { + case EFI_DEP_BEFORE: + printf ("BEFORE\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_AFTER: + printf ("AFTER\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_PUSH: + printf ("PUSH\n "); + PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE); + printf ("%s ", GuidBuffer); + PrintGuidName (GuidBuffer); + printf ("\n"); + // + // PrintGuid ((EFI_GUID *)(Ptr + 1)); + // + Ptr += 17; + SectionLength -= 17; + break; + + case EFI_DEP_AND: + printf ("AND\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_OR: + printf ("OR\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_NOT: + printf ("NOT\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_TRUE: + printf ("TRUE\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_FALSE: + printf ("FALSE\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_END: + printf ("END DEPEX\n"); + Ptr++; + SectionLength--; + break; + + case EFI_DEP_SOR: + printf ("SOR\n"); + Ptr++; + SectionLength--; + break; + + default: + printf ("Unrecognized byte in depex: 0x%X\n", *Ptr); + return EFI_SUCCESS; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PrintGuidName ( + IN UINT8 *GuidStr + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + GuidStr - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + EFI_INVALID_PARAMETER - GC_TODO: Add description for return value + +--*/ +{ + GUID_TO_BASENAME *GPtr; + // + // If we have a list of guid-to-basenames, then go through the list to + // look for a guid string match. If found, print the basename to stdout, + // otherwise return a failure. + // + GPtr = mGuidBaseNameList; + while (GPtr != NULL) { + if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) { + printf ("%s", GPtr->BaseName); + return EFI_SUCCESS; + } + + GPtr = GPtr->Next; + } + + return EFI_INVALID_PARAMETER; +} + +EFI_STATUS +ParseGuidBaseNameFile ( + CHAR8 *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + +Returns: + + EFI_DEVICE_ERROR - GC_TODO: Add description for return value + EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + FILE *Fptr; + CHAR8 Line[MAX_LINE_LEN]; + CHAR8 FormatString[MAX_LINE_LEN]; + GUID_TO_BASENAME *GPtr; + + if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) { + printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName); + return EFI_DEVICE_ERROR; + } + + // + // Generate the format string for fscanf + // + sprintf ( + FormatString, + "%%%us %%%us", + (unsigned) sizeof (GPtr->Guid) - 1, + (unsigned) sizeof (GPtr->BaseName) - 1 + ); + + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + // + // Allocate space for another guid/basename element + // + GPtr = malloc (sizeof (GUID_TO_BASENAME)); + if (GPtr == NULL) { + fclose (Fptr); + return EFI_OUT_OF_RESOURCES; + } + + memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME)); + if (sscanf (Line, FormatString, GPtr->Guid, GPtr->BaseName) == 2) { + GPtr->Next = mGuidBaseNameList; + mGuidBaseNameList = GPtr; + } else { + // + // Some sort of error. Just continue. + // + free (GPtr); + } + } + + fclose (Fptr); + return EFI_SUCCESS; +} + +EFI_STATUS +FreeGuidBaseNameList ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + GUID_TO_BASENAME *Next; + + while (mGuidBaseNameList != NULL) { + Next = mGuidBaseNameList->Next; + free (mGuidBaseNameList); + mGuidBaseNameList = Next; + } + + return EFI_SUCCESS; +} + + +static +VOID +LoadGuidedSectionToolsTxt ( + IN CHAR8* FirmwareVolumeFilename + ) +{ + CHAR8* PeerFilename; + CHAR8* Places[] = { + NULL, + //NULL, + }; + UINTN Index; + + Places[0] = FirmwareVolumeFilename; + //Places[1] = mUtilityFilename; + + mParsedGuidedSectionTools = NULL; + + for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) { + PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt"); + //printf("Loading %s...\n", PeerFilename); + if (OsPathExists (PeerFilename)) { + mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename); + } + free (PeerFilename); + if (mParsedGuidedSectionTools != NULL) { + return; + } + } +} + + +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + // + // Summary usage + // + fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME); + + // + // Copyright declaration + // + fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n"); + fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n"); + + // + // Details Option + // + fprintf (stdout, "optional arguments:\n"); + fprintf (stdout, " -h, --help\n\ + Show this help message and exit\n"); + fprintf (stdout, " --version\n\ + Show program's version number and exit\n"); + fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\ + Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n"); + fprintf (stdout, " -v, --verbose\n\ + Print informational statements\n"); + fprintf (stdout, " -q, --quiet\n\ + Returns the exit code, error messages will be displayed\n"); + fprintf (stdout, " -s, --silent\n\ + Returns only the exit code; informational and error\n\ + messages are not displayed\n"); + fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\ + Parse the basename to file-guid cross reference file(s)\n"); + fprintf (stdout, " -f OFFSET, --offset OFFSET\n\ + The offset from the start of the input file to start \n\ + processing an FV\n"); + fprintf (stdout, " --hash\n\ + Generate HASH value of the entire PE image\n"); + fprintf (stdout, " --sfo\n\ + Reserved for future use\n"); +} + diff --git a/BaseTools/Source/C/VolInfo/VolInfo.h b/BaseTools/Source/C/VolInfo/VolInfo.h index 377cde80f7..ab2346b784 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.h +++ b/BaseTools/Source/C/VolInfo/VolInfo.h @@ -1,31 +1,31 @@ -/** @file
-Local Definitions for the VolInfo utility
-
-Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _VOLINFO_H_
-#define _VOLINFO_H_ 1
-
-#define PI_SPECIFICATION_VERSION 0x00010000
-
-#define EFI_DEP_BEFORE 0x00
-#define EFI_DEP_AFTER 0x01
-#define EFI_DEP_PUSH 0x02
-#define EFI_DEP_AND 0x03
-#define EFI_DEP_OR 0x04
-#define EFI_DEP_NOT 0x05
-#define EFI_DEP_TRUE 0x06
-#define EFI_DEP_FALSE 0x07
-#define EFI_DEP_END 0x08
-#define EFI_DEP_SOR 0x09
-
-#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1C
-#define EFI_SECTION_LAST_SECTION_TYPE 0x1C
-
-#define OPENSSL_COMMAND_FORMAT_STRING "%s sha1 -out %s %s"
-#define EXTRACT_COMMAND_FORMAT_STRING "%s -d -o %s %s"
-
-#endif
+/** @file +Local Definitions for the VolInfo utility + +Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VOLINFO_H_ +#define _VOLINFO_H_ 1 + +#define PI_SPECIFICATION_VERSION 0x00010000 + +#define EFI_DEP_BEFORE 0x00 +#define EFI_DEP_AFTER 0x01 +#define EFI_DEP_PUSH 0x02 +#define EFI_DEP_AND 0x03 +#define EFI_DEP_OR 0x04 +#define EFI_DEP_NOT 0x05 +#define EFI_DEP_TRUE 0x06 +#define EFI_DEP_FALSE 0x07 +#define EFI_DEP_END 0x08 +#define EFI_DEP_SOR 0x09 + +#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1C +#define EFI_SECTION_LAST_SECTION_TYPE 0x1C + +#define OPENSSL_COMMAND_FORMAT_STRING "%s sha1 -out %s %s" +#define EXTRACT_COMMAND_FORMAT_STRING "%s -d -o %s %s" + +#endif |
