2014-01-27 06:23:15 +01:00
/** @file
2014-08-28 15:53:34 +02:00
The tool dumps the contents of a firmware volume
2014-01-27 06:23:15 +01:00
2014-07-01 09:10:10 +02:00
Copyright ( c ) 1999 - 2014 , Intel Corporation . All rights reserved . < BR >
2014-01-27 06:23:15 +01:00
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution . The full text of the license may be found at
http : //opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN " AS IS " BASIS ,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND , EITHER EXPRESS OR IMPLIED .
* */
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <assert.h>
# 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"
//
// Utility global variables
//
EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID ;
# define UTILITY_MAJOR_VERSION 0
2014-08-27 18:14:42 +02:00
# define UTILITY_MINOR_VERSION 83
2014-01-27 06:23:15 +01:00
# define UTILITY_NAME "VolInfo"
# define EFI_SECTION_ERROR EFIERR (100)
# define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable
//
// 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_BASENAME_LEN ] ;
} GUID_TO_BASENAME ;
static GUID_TO_BASENAME * mGuidBaseNameList = NULL ;
//
// Store GUIDed Section guid->tool mapping
//
EFI_HANDLE mParsedGuidedSectionTools = NULL ;
CHAR8 * mUtilityFilename = 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
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
) ;
void
Usage (
VOID
) ;
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 ;
SetUtilityName ( UTILITY_NAME ) ;
//
// Print utility header
//
2014-08-27 18:14:42 +02:00
printf ( " %s Version %d.%d %s, %s \n " ,
2014-01-27 06:23:15 +01:00
UTILITY_NAME ,
UTILITY_MAJOR_VERSION ,
UTILITY_MINOR_VERSION ,
__BUILD_VERSION ,
__DATE__
) ;
//
// Save, and then skip filename arg
//
mUtilityFilename = argv [ 0 ] ;
argc - - ;
argv + + ;
Offset = 0 ;
//
// 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 > 2 ) {
if ( ( strcmp ( argv [ 0 ] , " -x " ) = = 0 ) | | ( strcmp ( argv [ 0 ] , " --xref " ) = = 0 ) ) {
ParseGuidBaseNameFile ( argv [ 1 ] ) ;
printf ( " ParseGuidBaseNameFile: %s \n " , argv [ 1 ] ) ;
argc - = 2 ;
argv + = 2 ;
} else 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 ;
} else {
Usage ( ) ;
return - 1 ;
}
}
//
// Check for proper number of arguments
//
if ( argc ! = 1 ) {
Usage ( ) ;
return - 1 ;
}
//
// 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_ERROR ;
}
//
// Open the file containing the FV
//
2014-08-15 05:06:48 +02:00
InputFile = fopen ( LongFilePath ( argv [ 0 ] ) , " rb " ) ;
2014-01-27 06:23:15 +01:00
if ( InputFile = = NULL ) {
Error ( NULL , 0 , 0001 , " Error opening the input file " , argv [ 0 ] ) ;
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 " , argv [ 0 ] ) ;
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 " , argv [ 0 ] ) ;
free ( FvImage ) ;
return GetUtilityStatus ( ) ;
}
LoadGuidedSectionToolsTxt ( argv [ 0 ] ) ;
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_SMM_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 ;
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
//
fread ( & VolumeHeader , sizeof ( EFI_FIRMWARE_VOLUME_HEADER ) - sizeof ( EFI_FV_BLOCK_MAP_ENTRY ) , 1 , InputFile ) ;
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 " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_1 ) {
printf ( " EFI_FVB2_ALIGNMENT_1 \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 " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_128K ) {
printf ( " EFI_FVB2_ALIGNMENT_128K \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_256K ) {
printf ( " EFI_FVB2_ALIGNMENT_256K \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_512K ) {
printf ( " EFI_FVB2_ALIGNMENT_512K \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_1M ) {
printf ( " EFI_FVB2_ALIGNMENT_1M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_2M ) {
printf ( " EFI_FVB2_ALIGNMENT_2M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_4M ) {
printf ( " EFI_FVB2_ALIGNMENT_4M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_8M ) {
printf ( " EFI_FVB2_ALIGNMENT_8M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_16M ) {
printf ( " EFI_FVB2_ALIGNMENT_16M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_32M ) {
printf ( " EFI_FVB2_ALIGNMENT_32M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_64M ) {
printf ( " EFI_FVB2_ALIGNMENT_64M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_128M ) {
printf ( " EFI_FVB2_ALIGNMENT_128M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_64M ) {
printf ( " EFI_FVB2_ALIGNMENT_64M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_128M ) {
printf ( " EFI_FVB2_ALIGNMENT_128M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_256M ) {
printf ( " EFI_FVB2_ALIGNMENT_256M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_512M ) {
printf ( " EFI_FVB2_ALIGNMENT_512M \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_1G ) {
printf ( " EFI_FVB2_ALIGNMENT_1G \n " ) ;
}
if ( VolumeHeader . Attributes & EFI_FVB2_ALIGNMENT_2G ) {
printf ( " EFI_FVB2_ALIGNMENT_2G \n " ) ;
}
# 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 {
fread ( & BlockMap , sizeof ( EFI_FV_BLOCK_MAP_ENTRY ) , 1 , InputFile ) ;
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 consistant 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
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 ;
2014-07-01 09:10:10 +02:00
EFI_FFS_FILE_HEADER2 BlankHeader ;
2014-01-27 06:23:15 +01:00
EFI_STATUS Status ;
UINT8 GuidBuffer [ PRINTED_GUID_BUFFER_SIZE ] ;
2014-07-01 09:10:10 +02:00
UINT32 HeaderSize ;
2014-01-27 06:23:15 +01:00
# if (PI_SPECIFICATION_VERSION < 0x00010000)
UINT16 * Tail ;
# endif
//
// Check if we have free space
//
2014-07-01 09:10:10 +02:00
HeaderSize = FvBufGetFfsHeaderSize ( FileHeader ) ;
2014-01-27 06:23:15 +01:00
if ( ErasePolarity ) {
2014-07-01 09:10:10 +02:00
memset ( & BlankHeader , - 1 , HeaderSize ) ;
2014-01-27 06:23:15 +01:00
} else {
2014-07-01 09:10:10 +02:00
memset ( & BlankHeader , 0 , HeaderSize ) ;
2014-01-27 06:23:15 +01:00
}
2014-07-01 09:10:10 +02:00
if ( memcmp ( & BlankHeader , FileHeader , HeaderSize ) = = 0 ) {
2014-01-27 06:23:15 +01:00
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");
//
2014-07-01 09:10:10 +02:00
FileLength = FvBufGetFfsFileSize ( FileHeader ) ;
2014-01-27 06:23:15 +01:00
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 " ) ;
2014-07-01 09:10:10 +02:00
Checksum = CalculateSum8 ( ( UINT8 * ) FileHeader , HeaderSize ) ;
2014-01-27 06:23:15 +01:00
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
//
2014-07-01 09:10:10 +02:00
Checksum = CalculateSum8 ( ( UINT8 * ) FileHeader , HeaderSize ) ;
2014-01-27 06:23:15 +01:00
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 ;
}
2014-07-01 09:10:10 +02:00
FileLength = FvBufGetFfsFileSize ( FileHeader ) ;
2014-01-27 06:23:15 +01:00
if ( FileHeader - > Attributes & FFS_ATTRIB_CHECKSUM ) {
//
// Calculate file checksum
//
2014-07-01 09:10:10 +02:00
Checksum = CalculateSum8 ( ( UINT8 * ) FileHeader + HeaderSize , FileLength - HeaderSize ) ;
2014-01-27 06:23:15 +01:00
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_SMM \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_SMM_DXE \n " ) ;
break ;
case EFI_FV_FILETYPE_SMM_CORE :
printf ( " EFI_FV_FILETYPE_SMM_CORE \n " ) ;
break ;
case EFI_FV_FILETYPE_FFS_PAD :
printf ( " EFI_FV_FILETYPE_FFS_PAD \n " ) ;
break ;
default :
printf ( " \n ERROR: 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 (
2014-07-01 09:10:10 +02:00
( UINT8 * ) ( ( UINTN ) FileHeader + HeaderSize ) ,
FvBufGetFfsFileSize ( FileHeader ) - HeaderSize
2014-01-27 06:23:15 +01:00
) ;
if ( EFI_ERROR ( Status ) ) {
//
// printf ("ERROR: Parsing the FFS file.\n");
//
return EFI_ABORTED ;
}
break ;
}
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 ;
2014-07-01 09:10:10 +02:00
UINT32 SectionHeaderLen ;
2014-01-27 06:23:15 +01:00
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 * SystemCommandFormatString ;
CHAR8 * SystemCommand ;
2014-07-01 09:10:10 +02:00
EFI_GUID * EfiGuid ;
UINT16 DataOffset ;
UINT16 Attributes ;
UINT32 RealHdrLen ;
2014-01-27 06:23:15 +01:00
ParsedLength = 0 ;
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 ;
}
2014-07-01 09:10:10 +02:00
//
// Get real section file size
//
SectionLength = GetSectionFileLength ( ( EFI_COMMON_SECTION_HEADER * ) Ptr ) ;
SectionHeaderLen = GetSectionHeaderLength ( ( EFI_COMMON_SECTION_HEADER * ) Ptr ) ;
2014-01-27 06:23:15 +01:00
SectionName = SectionNameToStr ( Type ) ;
printf ( " ------------------------------------------------------------ \n " ) ;
printf ( " Type: %s \n Size: 0x%08X \n " , SectionName , ( unsigned ) SectionLength ) ;
free ( SectionName ) ;
switch ( Type ) {
case EFI_SECTION_RAW :
case EFI_SECTION_PE32 :
case EFI_SECTION_PIC :
case EFI_SECTION_TE :
// default is no more information
break ;
case EFI_SECTION_USER_INTERFACE :
// name = &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString;
// printf (" String: %s\n", &name);
break ;
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE :
2014-07-01 09:10:10 +02:00
Status = PrintFvInfo ( Ptr + SectionHeaderLen , TRUE ) ;
2014-01-27 06:23:15 +01:00
if ( EFI_ERROR ( Status ) ) {
Error ( NULL , 0 , 0003 , " printing of FV section contents failed " , NULL ) ;
return EFI_SECTION_ERROR ;
}
break ;
case EFI_SECTION_COMPATIBILITY16 :
case EFI_SECTION_FREEFORM_SUBTYPE_GUID :
//
// Section does not contain any further header information.
//
break ;
case EFI_SECTION_PEI_DEPEX :
case EFI_SECTION_DXE_DEPEX :
case EFI_SECTION_SMM_DEPEX :
DumpDepexSection ( Ptr , SectionLength ) ;
break ;
case EFI_SECTION_VERSION :
2014-07-01 09:10:10 +02:00
printf ( " Build Number: 0x%02X \n " , * ( UINT16 * ) ( Ptr + SectionHeaderLen ) ) ;
printf ( " Version Strg: %s \n " , ( char * ) ( Ptr + SectionHeaderLen + sizeof ( UINT16 ) ) ) ;
2014-01-27 06:23:15 +01:00
break ;
case EFI_SECTION_COMPRESSION :
UncompressedBuffer = NULL ;
2014-07-01 09:10:10 +02:00
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 ;
2014-01-27 06:23:15 +01:00
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 ;
}
2014-07-01 09:10:10 +02:00
UncompressedBuffer = Ptr + RealHdrLen ;
2014-01-27 06:23:15 +01:00
} else if ( CompressionType = = EFI_STANDARD_COMPRESSION ) {
GetInfoFunction = EfiGetInfo ;
DecompressFunction = EfiDecompress ;
printf ( " Compression Type: EFI_STANDARD_COMPRESSION \n " ) ;
2014-07-01 09:10:10 +02:00
CompressedBuffer = Ptr + RealHdrLen ;
2014-01-27 06:23:15 +01:00
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 ) ;
UncompressedBuffer = malloc ( UncompressedLength ) ;
if ( ( ScratchBuffer = = NULL ) | | ( UncompressedBuffer = = NULL ) ) {
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 ;
}
Status = ParseSection ( UncompressedBuffer , UncompressedLength ) ;
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 :
2014-07-01 09:10:10 +02:00
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 ;
}
2014-01-27 06:23:15 +01:00
printf ( " SectionDefinitionGuid: " ) ;
2014-07-01 09:10:10 +02:00
PrintGuid ( EfiGuid ) ;
2014-01-27 06:23:15 +01:00
printf ( " \n " ) ;
2014-07-01 09:10:10 +02:00
printf ( " DataOffset: 0x%04X \n " , ( unsigned ) DataOffset ) ;
printf ( " Attributes: 0x%04X \n " , ( unsigned ) Attributes ) ;
2014-01-27 06:23:15 +01:00
ExtractionTool =
LookupGuidedSectionToolPath (
mParsedGuidedSectionTools ,
2014-07-01 09:10:10 +02:00
EfiGuid
2014-01-27 06:23:15 +01:00
) ;
if ( ExtractionTool ! = NULL ) {
ToolInputFile = CloneString ( tmpnam ( NULL ) ) ;
ToolOutputFile = CloneString ( tmpnam ( NULL ) ) ;
//
// Construction 'system' command string
//
SystemCommandFormatString = " %s -d -o %s %s " ;
SystemCommand = malloc (
strlen ( SystemCommandFormatString ) +
strlen ( ExtractionTool ) +
strlen ( ToolInputFile ) +
strlen ( ToolOutputFile ) +
1
) ;
sprintf (
SystemCommand ,
SystemCommandFormatString ,
ExtractionTool ,
ToolOutputFile ,
ToolInputFile
) ;
free ( ExtractionTool ) ;
Status =
PutFileImage (
ToolInputFile ,
2014-07-01 09:10:10 +02:00
( CHAR8 * ) SectionBuffer + DataOffset ,
BufferLength - DataOffset
2014-01-27 06:23:15 +01:00
) ;
system ( SystemCommand ) ;
remove ( ToolInputFile ) ;
free ( ToolInputFile ) ;
Status =
GetFileImage (
ToolOutputFile ,
( CHAR8 * * ) & ToolOutputBuffer ,
& ToolOutputLength
) ;
remove ( ToolOutputFile ) ;
free ( ToolOutputFile ) ;
if ( EFI_ERROR ( Status ) ) {
Error ( NULL , 0 , 0004 , " unable to read decoded GUIDED section " , NULL ) ;
return EFI_SECTION_ERROR ;
}
Status = ParseSection (
ToolOutputBuffer ,
ToolOutputLength
) ;
if ( EFI_ERROR ( Status ) ) {
Error ( NULL , 0 , 0003 , " parse of decoded GUIDED section failed " , NULL ) ;
return EFI_SECTION_ERROR ;
}
//
// Check for CRC32 sections which we can handle internally if needed.
//
} else if ( ! CompareGuid (
2014-07-01 09:10:10 +02:00
EfiGuid ,
2014-01-27 06:23:15 +01:00
& gEfiCrc32GuidedSectionExtractionProtocolGuid
)
) {
//
// CRC32 guided section
//
Status = ParseSection (
2014-07-01 09:10:10 +02:00
SectionBuffer + DataOffset ,
BufferLength - DataOffset
2014-01-27 06:23:15 +01:00
) ;
if ( EFI_ERROR ( Status ) ) {
Error ( NULL , 0 , 0003 , " parse of CRC32 GUIDED section failed " , NULL ) ;
return EFI_SECTION_ERROR ;
}
} 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 ;
}
2014-07-01 09:10:10 +02:00
Ptr + = GetSectionHeaderLength ( ( EFI_COMMON_SECTION_HEADER * ) Ptr ) ;
SectionLength - = GetSectionHeaderLength ( ( EFI_COMMON_SECTION_HEADER * ) Ptr ) ;
2014-01-27 06:23:15 +01:00
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 ] ;
GUID_TO_BASENAME * GPtr ;
2014-08-28 15:53:34 +02:00
if ( ( Fptr = fopen ( LongFilePath ( FileName ) , " r " ) ) = = NULL ) {
2014-01-27 06:23:15 +01:00
printf ( " ERROR: Failed to open input cross-reference file '%s' \n " , FileName ) ;
return EFI_DEVICE_ERROR ;
}
while ( fgets ( Line , sizeof ( Line ) , Fptr ) ! = NULL ) {
//
// Allocate space for another guid/basename element
//
GPtr = malloc ( sizeof ( GUID_TO_BASENAME ) ) ;
if ( GPtr = = NULL ) {
return EFI_OUT_OF_RESOURCES ;
}
memset ( ( char * ) GPtr , 0 , sizeof ( GUID_TO_BASENAME ) ) ;
if ( sscanf ( Line , " %s %s " , 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
//
2014-07-01 09:10:10 +02:00
fprintf ( stdout , " Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved. \n \n " ) ;
2014-08-27 18:14:42 +02:00
fprintf ( stdout , " Display Tiano Firmware Volume FFS image information \n \n " ) ;
2014-01-27 06:23:15 +01:00
//
// Details Option
//
fprintf ( stdout , " Options: \n " ) ;
fprintf ( stdout , " -x xref, --xref xref \n \
Parse basename to file - guid cross reference file ( s ) . \ n " );
fprintf ( stdout , " --offset offset \n \
Offset of file to start processing FV at . \ n " );
fprintf ( stdout , " -h, --help \n \
Show this help message and exit . \ n " );
}