2 The tool dumps the contents of a firmware volume
4 Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
21 #include <Common/UefiBaseTypes.h>
22 #include <Common/UefiCapsule.h>
23 #include <Common/PiFirmwareFile.h>
24 #include <Common/PiFirmwareVolume.h>
25 #include <Guid/PiFirmwareFileSystem.h>
26 #include <IndustryStandard/PeImage.h>
27 #include <Protocol/GuidedSectionExtraction.h>
30 #include "Decompress.h"
32 #include "CommonLib.h"
33 #include "EfiUtilityMsgs.h"
34 #include "FirmwareVolumeBufferLib.h"
36 #include "ParseGuidedSectionTools.h"
37 #include "StringFuncs.h"
39 #include "PeCoffLib.h"
42 // Utility global variables
45 EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
47 #define UTILITY_MAJOR_VERSION 1
48 #define UTILITY_MINOR_VERSION 0
50 #define UTILITY_NAME "VolInfo"
52 #define EFI_SECTION_ERROR EFIERR (100)
54 #define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable
57 // Structure to keep a list of guid-to-basenames
59 typedef struct _GUID_TO_BASENAME
{
60 struct _GUID_TO_BASENAME
*Next
;
61 INT8 Guid
[PRINTED_GUID_BUFFER_SIZE
];
62 INT8 BaseName
[MAX_BASENAME_LEN
];
65 static GUID_TO_BASENAME
*mGuidBaseNameList
= NULL
;
68 // Store GUIDed Section guid->tool mapping
70 EFI_HANDLE mParsedGuidedSectionTools
= NULL
;
72 CHAR8
* mUtilityFilename
= NULL
;
74 BOOLEAN EnableHash
= FALSE
;
75 CHAR8
*OpenSslPath
= NULL
;
78 ParseGuidBaseNameFile (
83 FreeGuidBaseNameList (
94 IN UINT8
*SectionBuffer
,
95 IN UINT32 BufferLength
101 IN UINT32 SectionLength
109 OUT BOOLEAN
*ErasePolarity
115 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
116 EFI_FFS_FILE_HEADER
*FileHeader
,
117 BOOLEAN ErasePolarity
129 LoadGuidedSectionToolsTxt (
130 IN CHAR8
* FirmwareVolumeFilename
135 IN CHAR8
* DefaultPath
,
136 IN CHAR8
* AppendPath
,
153 Returns the length of a null-terminated unicode string.
157 String - The pointer to a null-terminated unicode string.
167 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
174 Unicode2AsciiString (
176 OUT CHAR8
*Destination
182 Convert a null-terminated unicode string to a null-terminated ascii string.
186 Source - The pointer to the null-terminated input unicode string.
187 Destination - The pointer to the null-terminated output ascii string.
195 while (*Source
!= '\0') {
196 *(Destination
++) = (CHAR8
) *(Source
++);
199 // End the ascii with a NULL.
213 GC_TODO: Add function description
217 argc - GC_TODO: add argument description
218 ] - GC_TODO: add argument description
222 GC_TODO: add return values
228 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
;
232 BOOLEAN ErasePolarity
;
235 CHAR8
*OpenSslCommand
;
237 SetUtilityName (UTILITY_NAME
);
239 // Print utility header
241 printf ("%s Version %d.%d Build %s\n",
243 UTILITY_MAJOR_VERSION
,
244 UTILITY_MINOR_VERSION
,
259 // Look for help options
261 if ((strcmp(argv
[0], "-h") == 0) || (strcmp(argv
[0], "--help") == 0) ||
262 (strcmp(argv
[0], "-?") == 0) || (strcmp(argv
[0], "/?") == 0)) {
264 return STATUS_SUCCESS
;
267 // Version has already be printed, so just return success
269 if (strcmp(argv
[0], "--version") == 0) {
270 return STATUS_SUCCESS
;
274 // If they specified -x xref guid/basename cross-reference files, process it.
275 // This will print the basename beside each file guid. To use it, specify
276 // -x xref_filename to processdsc, then use xref_filename as a parameter
280 if ((strcmp(argv
[0], "-x") == 0) || (strcmp(argv
[0], "--xref") == 0)) {
281 ParseGuidBaseNameFile (argv
[1]);
282 printf("ParseGuidBaseNameFile: %s\n", argv
[1]);
287 if (strcmp(argv
[0], "--offset") == 0) {
291 if ((argv
[1][0] == '0') && (tolower ((int)argv
[1][1]) == 'x')) {
292 if (sscanf (argv
[1], "%x", &Offset
) != 1) {
293 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
294 return GetUtilityStatus ();
297 if (sscanf (argv
[1], "%d", &Offset
) != 1) {
298 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
299 return GetUtilityStatus ();
302 // See if they said something like "64K"
304 if (tolower ((int)argv
[1][strlen (argv
[1]) - 1]) == 'k') {
313 if ((stricmp (argv
[0], "--hash") == 0)) {
314 if (EnableHash
== TRUE
) {
316 // --hash already given in the option, ignore this one
323 OpenSslCommand
= "openssl";
324 OpenSslEnv
= getenv("OPENSSL_PATH");
325 if (OpenSslEnv
== NULL
) {
326 OpenSslPath
= OpenSslCommand
;
329 // We add quotes to the Openssl Path in case it has space characters
331 OpenSslPath
= malloc(2+strlen(OpenSslEnv
)+strlen(OpenSslCommand
)+1);
332 if (OpenSslPath
== NULL
) {
333 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
334 return GetUtilityStatus ();
336 CombinePath(OpenSslEnv
, OpenSslCommand
, OpenSslPath
);
338 if (OpenSslPath
== NULL
){
339 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
340 return GetUtilityStatus ();
347 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
348 SetPrintLevel (VERBOSE_LOG_LEVEL
);
354 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
355 SetPrintLevel (KEY_LOG_LEVEL
);
361 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
362 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
363 if (EFI_ERROR (Status
)) {
364 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
368 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel
);
371 SetPrintLevel (LogLevel
);
372 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
378 mUtilityFilename
= argv
[0];
384 // Open the file containing the FV
386 if (mUtilityFilename
== NULL
) {
387 Error (NULL
, 0, 1001, "Missing option", "Input files are not specified");
388 return GetUtilityStatus ();
390 InputFile
= fopen (LongFilePath (mUtilityFilename
), "rb");
391 if (InputFile
== NULL
) {
392 Error (NULL
, 0, 0001, "Error opening the input file", mUtilityFilename
);
393 return GetUtilityStatus ();
396 // Skip over pad bytes if specified. This is used if they prepend 0xff
397 // data to the FV image binary.
400 fseek (InputFile
, Offset
, SEEK_SET
);
403 // Determine size of FV
405 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
406 if (EFI_ERROR (Status
)) {
407 Error (NULL
, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename
);
409 return GetUtilityStatus ();
412 // Allocate a buffer for the FV image
414 FvImage
= malloc (FvSize
);
415 if (FvImage
== NULL
) {
416 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
418 return GetUtilityStatus ();
421 // Seek to the start of the image, then read the entire FV to the buffer
423 fseek (InputFile
, Offset
, SEEK_SET
);
424 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
426 if ((unsigned int) BytesRead
!= FvSize
) {
427 Error (NULL
, 0, 0004, "error reading FvImage from", mUtilityFilename
);
429 return GetUtilityStatus ();
432 LoadGuidedSectionToolsTxt (mUtilityFilename
);
434 PrintFvInfo (FvImage
, FALSE
);
440 FreeGuidBaseNameList ();
441 return GetUtilityStatus ();
455 GC_TODO: Add function description
459 Fv - Firmware Volume to print information about
460 IsChildFv - Flag specifies whether the input FV is a child FV.
470 BOOLEAN ErasePolarity
;
472 EFI_FFS_FILE_HEADER
*CurrentFile
;
475 Status
= FvBufGetSize (Fv
, &FvSize
);
479 (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) ?
483 // Get the first file
486 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
487 if (EFI_ERROR (Status
)) {
488 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
489 return GetUtilityStatus ();
492 // Display information about files found
494 while (CurrentFile
!= NULL
) {
496 // Increment the number of files counter
501 // Display info about this file
503 Status
= PrintFileInfo (Fv
, CurrentFile
, ErasePolarity
);
504 if (EFI_ERROR (Status
)) {
505 Error (NULL
, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
506 return GetUtilityStatus ();
511 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
512 if (Status
== EFI_NOT_FOUND
) {
514 } else if (EFI_ERROR (Status
)) {
515 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
516 return GetUtilityStatus ();
521 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles
);
523 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles
);
531 IN UINT32 ActualSize
,
538 This function returns the next larger size that meets the alignment
539 requirement specified.
544 Alignment The desired alignment.
548 EFI_SUCCESS Function completed successfully.
549 EFI_ABORTED The function encountered an error.
555 OccupiedSize
= ActualSize
;
556 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
566 IN EFI_SECTION_TYPE Type
572 Converts EFI Section names to Strings
576 Type - The EFI Section type
580 CHAR8* - Pointer to the String containing the section name.
585 CHAR8
*SectionTypeStringTable
[] = {
593 "EFI_SECTION_COMPRESSION",
597 "EFI_SECTION_GUID_DEFINED",
601 "Unknown section type - Reserved 0x03",
605 "Unknown section type - Reserved 0x04",
609 "Unknown section type - Reserved 0x05",
613 "Unknown section type - Reserved 0x06",
617 "Unknown section type - Reserved 0x07",
621 "Unknown section type - Reserved 0x08",
625 "Unknown section type - Reserved 0x09",
629 "Unknown section type - Reserved 0x0A",
633 "Unknown section type - Reserved 0x0B",
637 "Unknown section type - Reserved 0x0C",
641 "Unknown section type - Reserved 0x0D",
645 "Unknown section type - Reserved 0x0E",
649 "Unknown section type - Reserved 0x0E",
665 "EFI_SECTION_DXE_DEPEX",
669 "EFI_SECTION_VERSION",
673 "EFI_SECTION_USER_INTERFACE",
677 "EFI_SECTION_COMPATIBILITY16",
681 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
685 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
693 "Unknown section type - 0x1A",
697 "EFI_SECTION_PEI_DEPEX",
701 "EFI_SECTION_SMM_DEPEX",
705 "Unknown section type - Reserved - beyond last defined section"
708 if (Type
> EFI_SECTION_LAST_SECTION_TYPE
) {
709 Type
= EFI_SECTION_LAST_SECTION_TYPE
+ 1;
712 SectionStr
= malloc (100);
713 if (SectionStr
== NULL
) {
714 printf ("Error: Out of memory resources.\n");
717 strcpy (SectionStr
, SectionTypeStringTable
[Type
]);
726 OUT BOOLEAN
*ErasePolarity
732 This function determines the size of the FV and the erase polarity. The
733 erase polarity is the FALSE value for file state.
737 InputFile The file that contains the FV image.
738 FvSize The size of the FV.
739 ErasePolarity The FV erase polarity.
743 EFI_SUCCESS Function completed successfully.
744 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
745 EFI_ABORTED The function encountered an error.
749 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
750 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
759 // Check input parameters
761 if (InputFile
== NULL
|| FvSize
== NULL
|| ErasePolarity
== NULL
) {
762 Error (__FILE__
, __LINE__
, 0, "application error", "invalid parameter to function");
763 return EFI_INVALID_PARAMETER
;
768 ReadSize
= fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
772 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
773 Signature
[0] = VolumeHeader
.Signature
;
777 // Print FV header information
779 printf ("Signature: %s (%X)\n", (char *) Signature
, (unsigned) VolumeHeader
.Signature
);
780 printf ("Attributes: %X\n", (unsigned) VolumeHeader
.Attributes
);
782 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_DISABLED_CAP
) {
783 printf (" EFI_FVB2_READ_DISABLED_CAP\n");
786 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_ENABLED_CAP
) {
787 printf (" EFI_FVB2_READ_ENABLED_CAP\n");
790 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_STATUS
) {
791 printf (" EFI_FVB2_READ_STATUS\n");
794 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_DISABLED_CAP
) {
795 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
798 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_ENABLED_CAP
) {
799 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
802 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_STATUS
) {
803 printf (" EFI_FVB2_WRITE_STATUS\n");
806 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_CAP
) {
807 printf (" EFI_FVB2_LOCK_CAP\n");
810 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_STATUS
) {
811 printf (" EFI_FVB2_LOCK_STATUS\n");
814 if (VolumeHeader
.Attributes
& EFI_FVB2_STICKY_WRITE
) {
815 printf (" EFI_FVB2_STICKY_WRITE\n");
818 if (VolumeHeader
.Attributes
& EFI_FVB2_MEMORY_MAPPED
) {
819 printf (" EFI_FVB2_MEMORY_MAPPED\n");
822 if (VolumeHeader
.Attributes
& EFI_FVB2_ERASE_POLARITY
) {
823 printf (" EFI_FVB2_ERASE_POLARITY\n");
824 *ErasePolarity
= TRUE
;
827 #if (PI_SPECIFICATION_VERSION < 0x00010000)
828 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
829 printf (" EFI_FVB2_ALIGNMENT\n");
832 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
833 printf (" EFI_FVB2_ALIGNMENT_2\n");
836 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
837 printf (" EFI_FVB2_ALIGNMENT_4\n");
840 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
841 printf (" EFI_FVB2_ALIGNMENT_8\n");
844 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
845 printf (" EFI_FVB2_ALIGNMENT_16\n");
848 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
849 printf (" EFI_FVB2_ALIGNMENT_32\n");
852 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
853 printf (" EFI_FVB2_ALIGNMENT_64\n");
856 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
857 printf (" EFI_FVB2_ALIGNMENT_128\n");
860 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
861 printf (" EFI_FVB2_ALIGNMENT_256\n");
864 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
865 printf (" EFI_FVB2_ALIGNMENT_512\n");
868 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
869 printf (" EFI_FVB2_ALIGNMENT_1K\n");
872 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
873 printf (" EFI_FVB2_ALIGNMENT_2K\n");
876 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
877 printf (" EFI_FVB2_ALIGNMENT_4K\n");
880 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
881 printf (" EFI_FVB2_ALIGNMENT_8K\n");
884 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
885 printf (" EFI_FVB2_ALIGNMENT_16K\n");
888 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
889 printf (" EFI_FVB2_ALIGNMENT_32K\n");
892 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
893 printf (" EFI_FVB2_ALIGNMENT_64K\n");
898 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_CAP
) {
899 printf (" EFI_FVB2_READ_LOCK_CAP\n");
902 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_STATUS
) {
903 printf (" EFI_FVB2_READ_LOCK_STATUS\n");
906 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_CAP
) {
907 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
910 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_STATUS
) {
911 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
914 switch (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
915 case EFI_FVB2_ALIGNMENT_1
:
916 printf (" EFI_FVB2_ALIGNMENT_1\n");
919 case EFI_FVB2_ALIGNMENT_2
:
920 printf (" EFI_FVB2_ALIGNMENT_2\n");
923 case EFI_FVB2_ALIGNMENT_4
:
924 printf (" EFI_FVB2_ALIGNMENT_4\n");
927 case EFI_FVB2_ALIGNMENT_8
:
928 printf (" EFI_FVB2_ALIGNMENT_8\n");
931 case EFI_FVB2_ALIGNMENT_16
:
932 printf (" EFI_FVB2_ALIGNMENT_16\n");
935 case EFI_FVB2_ALIGNMENT_32
:
936 printf (" EFI_FVB2_ALIGNMENT_32\n");
939 case EFI_FVB2_ALIGNMENT_64
:
940 printf (" EFI_FVB2_ALIGNMENT_64\n");
943 case EFI_FVB2_ALIGNMENT_128
:
944 printf (" EFI_FVB2_ALIGNMENT_128\n");
947 case EFI_FVB2_ALIGNMENT_256
:
948 printf (" EFI_FVB2_ALIGNMENT_256\n");
951 case EFI_FVB2_ALIGNMENT_512
:
952 printf (" EFI_FVB2_ALIGNMENT_512\n");
955 case EFI_FVB2_ALIGNMENT_1K
:
956 printf (" EFI_FVB2_ALIGNMENT_1K\n");
959 case EFI_FVB2_ALIGNMENT_2K
:
960 printf (" EFI_FVB2_ALIGNMENT_2K\n");
963 case EFI_FVB2_ALIGNMENT_4K
:
964 printf (" EFI_FVB2_ALIGNMENT_4K\n");
967 case EFI_FVB2_ALIGNMENT_8K
:
968 printf (" EFI_FVB2_ALIGNMENT_8K\n");
971 case EFI_FVB2_ALIGNMENT_16K
:
972 printf (" EFI_FVB2_ALIGNMENT_16K\n");
975 case EFI_FVB2_ALIGNMENT_32K
:
976 printf (" EFI_FVB2_ALIGNMENT_32K\n");
979 case EFI_FVB2_ALIGNMENT_64K
:
980 printf (" EFI_FVB2_ALIGNMENT_64K\n");
983 case EFI_FVB2_ALIGNMENT_128K
:
984 printf (" EFI_FVB2_ALIGNMENT_128K\n");
987 case EFI_FVB2_ALIGNMENT_256K
:
988 printf (" EFI_FVB2_ALIGNMENT_256K\n");
991 case EFI_FVB2_ALIGNMENT_512K
:
992 printf (" EFI_FVB2_ALIGNMENT_512K\n");
995 case EFI_FVB2_ALIGNMENT_1M
:
996 printf (" EFI_FVB2_ALIGNMENT_1M\n");
999 case EFI_FVB2_ALIGNMENT_2M
:
1000 printf (" EFI_FVB2_ALIGNMENT_2M\n");
1003 case EFI_FVB2_ALIGNMENT_4M
:
1004 printf (" EFI_FVB2_ALIGNMENT_4M\n");
1007 case EFI_FVB2_ALIGNMENT_8M
:
1008 printf (" EFI_FVB2_ALIGNMENT_8M\n");
1011 case EFI_FVB2_ALIGNMENT_16M
:
1012 printf (" EFI_FVB2_ALIGNMENT_16M\n");
1015 case EFI_FVB2_ALIGNMENT_32M
:
1016 printf (" EFI_FVB2_ALIGNMENT_32M\n");
1019 case EFI_FVB2_ALIGNMENT_64M
:
1020 printf (" EFI_FVB2_ALIGNMENT_64M\n");
1023 case EFI_FVB2_ALIGNMENT_128M
:
1024 printf (" EFI_FVB2_ALIGNMENT_128M\n");
1027 case EFI_FVB2_ALIGNMENT_256M
:
1028 printf (" EFI_FVB2_ALIGNMENT_256M\n");
1031 case EFI_FVB2_ALIGNMENT_512M
:
1032 printf (" EFI_FVB2_ALIGNMENT_512M\n");
1035 case EFI_FVB2_ALIGNMENT_1G
:
1036 printf (" EFI_FVB2_ALIGNMENT_1G\n");
1039 case EFI_FVB2_ALIGNMENT_2G
:
1040 printf (" EFI_FVB2_ALIGNMENT_2G\n");
1045 printf ("Header Length: 0x%08X\n", VolumeHeader
.HeaderLength
);
1046 printf ("File System ID: ");
1047 PrintGuid (&VolumeHeader
.FileSystemGuid
);
1051 printf ("Revision: 0x%04X\n", VolumeHeader
.Revision
);
1054 ReadSize
= fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
1055 if (ReadSize
!= 1) {
1058 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
1060 if (BlockMap
.NumBlocks
!= 0) {
1061 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap
.NumBlocks
);
1062 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap
.Length
);
1063 Size
+= BlockMap
.NumBlocks
* BlockMap
.Length
;
1066 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.Length
== 0));
1068 if (BytesRead
!= VolumeHeader
.HeaderLength
) {
1069 printf ("ERROR: Header length not consistent with Block Maps!\n");
1073 if (VolumeHeader
.FvLength
!= Size
) {
1074 printf ("ERROR: Volume Size not consistent with Block Maps!\n");
1078 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size
);
1083 // rewind (InputFile);
1091 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
1092 EFI_FFS_FILE_HEADER
*FileHeader
,
1093 BOOLEAN ErasePolarity
1097 Routine Description:
1099 GC_TODO: Add function description
1103 FvImage - GC_TODO: add argument description
1104 FileHeader - GC_TODO: add argument description
1105 ErasePolarity - GC_TODO: add argument description
1109 EFI_SUCCESS - GC_TODO: Add description for return value
1110 EFI_ABORTED - GC_TODO: Add description for return value
1117 EFI_FFS_FILE_HEADER2 BlankHeader
;
1119 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1121 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1125 // Check if we have free space
1127 HeaderSize
= FvBufGetFfsHeaderSize(FileHeader
);
1128 if (ErasePolarity
) {
1129 memset (&BlankHeader
, -1, HeaderSize
);
1131 memset (&BlankHeader
, 0, HeaderSize
);
1134 if (memcmp (&BlankHeader
, FileHeader
, HeaderSize
) == 0) {
1138 // Print file information.
1140 printf ("============================================================\n");
1142 printf ("File Name: ");
1143 PrintGuidToBuffer (&FileHeader
->Name
, GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
1144 printf ("%s ", GuidBuffer
);
1145 PrintGuidName (GuidBuffer
);
1149 // PrintGuid (&FileHeader->Name);
1152 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1153 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN
) FileHeader
- (UINTN
) FvImage
));
1154 printf ("File Length: 0x%08X\n", (unsigned) FileLength
);
1155 printf ("File Attributes: 0x%02X\n", FileHeader
->Attributes
);
1156 printf ("File State: 0x%02X\n", FileHeader
->State
);
1161 FileState
= GetFileState (ErasePolarity
, FileHeader
);
1163 switch (FileState
) {
1165 case EFI_FILE_HEADER_CONSTRUCTION
:
1166 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
1169 case EFI_FILE_HEADER_INVALID
:
1170 printf (" EFI_FILE_HEADER_INVALID\n");
1173 case EFI_FILE_HEADER_VALID
:
1174 printf (" EFI_FILE_HEADER_VALID\n");
1175 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1176 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1177 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1178 if (Checksum
!= 0) {
1179 printf ("ERROR: Header checksum invalid.\n");
1185 case EFI_FILE_DELETED
:
1186 printf (" EFI_FILE_DELETED\n");
1188 case EFI_FILE_MARKED_FOR_UPDATE
:
1189 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
1191 case EFI_FILE_DATA_VALID
:
1192 printf (" EFI_FILE_DATA_VALID\n");
1195 // Calculate header checksum
1197 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1198 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1199 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1200 if (Checksum
!= 0) {
1201 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer
);
1205 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1207 if (FileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
1209 // Calculate file checksum
1211 Checksum
= CalculateSum8 ((UINT8
*)FileHeader
+ HeaderSize
, FileLength
- HeaderSize
);
1212 Checksum
= Checksum
+ FileHeader
->IntegrityCheck
.Checksum
.File
;
1213 if (Checksum
!= 0) {
1214 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer
);
1218 if (FileHeader
->IntegrityCheck
.Checksum
.File
!= FFS_FIXED_CHECKSUM
) {
1219 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
);
1223 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1225 // Verify tail if present
1227 if (FileHeader
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
1229 // Verify tail is complement of integrity check field in the header.
1231 Tail
= (UINT16
*) ((UINTN
) FileHeader
+ GetLength (FileHeader
->Size
) - sizeof (EFI_FFS_INTEGRITY_CHECK
));
1232 if (FileHeader
->IntegrityCheck
.TailReference
!= (UINT16
)~(*Tail
)) {
1233 Error (NULL
, 0, 0003, "error parsing FFS file", \
1234 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer
);
1242 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer
);
1246 printf ("File Type: 0x%02X ", FileHeader
->Type
);
1248 switch (FileHeader
->Type
) {
1250 case EFI_FV_FILETYPE_RAW
:
1251 printf ("EFI_FV_FILETYPE_RAW\n");
1254 case EFI_FV_FILETYPE_FREEFORM
:
1255 printf ("EFI_FV_FILETYPE_FREEFORM\n");
1258 case EFI_FV_FILETYPE_SECURITY_CORE
:
1259 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
1262 case EFI_FV_FILETYPE_PEI_CORE
:
1263 printf ("EFI_FV_FILETYPE_PEI_CORE\n");
1266 case EFI_FV_FILETYPE_DXE_CORE
:
1267 printf ("EFI_FV_FILETYPE_DXE_CORE\n");
1270 case EFI_FV_FILETYPE_PEIM
:
1271 printf ("EFI_FV_FILETYPE_PEIM\n");
1274 case EFI_FV_FILETYPE_DRIVER
:
1275 printf ("EFI_FV_FILETYPE_DRIVER\n");
1278 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
1279 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
1282 case EFI_FV_FILETYPE_APPLICATION
:
1283 printf ("EFI_FV_FILETYPE_APPLICATION\n");
1286 case EFI_FV_FILETYPE_SMM
:
1287 printf ("EFI_FV_FILETYPE_SMM\n");
1290 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
:
1291 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1294 case EFI_FV_FILETYPE_COMBINED_SMM_DXE
:
1295 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
1298 case EFI_FV_FILETYPE_SMM_CORE
:
1299 printf ("EFI_FV_FILETYPE_SMM_CORE\n");
1302 case EFI_FV_FILETYPE_MM_STANDALONE
:
1303 printf ("EFI_FV_FILETYPE_MM_STANDALONE\n");
1306 case EFI_FV_FILETYPE_MM_CORE_STANDALONE
:
1307 printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n");
1310 case EFI_FV_FILETYPE_FFS_PAD
:
1311 printf ("EFI_FV_FILETYPE_FFS_PAD\n");
1315 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader
->Type
);
1320 switch (FileHeader
->Type
) {
1322 case EFI_FV_FILETYPE_ALL
:
1323 case EFI_FV_FILETYPE_RAW
:
1324 case EFI_FV_FILETYPE_FFS_PAD
:
1329 // All other files have sections
1331 Status
= ParseSection (
1332 (UINT8
*) ((UINTN
) FileHeader
+ HeaderSize
),
1333 FvBufGetFfsFileSize (FileHeader
) - HeaderSize
1335 if (EFI_ERROR (Status
)) {
1337 // printf ("ERROR: Parsing the FFS file.\n");
1349 IN VOID
*FileHandle
,
1350 IN UINTN FileOffset
,
1351 IN OUT UINT32
*ReadSize
,
1356 Routine Description:
1358 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
1362 FileHandle - The handle to the PE/COFF file
1364 FileOffset - The offset, in bytes, into the file to read
1366 ReadSize - The number of bytes to read from the file starting at FileOffset
1368 Buffer - A pointer to the buffer to read the data into.
1372 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1376 CHAR8
*Destination8
;
1380 Destination8
= Buffer
;
1381 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
1384 *(Destination8
++) = *(Source8
++);
1391 SetAddressToSectionHeader (
1393 IN OUT UINT8
*FileBuffer
,
1394 IN UINT64 NewPe32BaseAddress
1398 Routine Description:
1400 Set new base address into the section header of PeImage
1404 FileName - Name of file
1405 FileBuffer - Pointer to PeImage.
1406 NewPe32BaseAddress - New Base Address for PE image.
1410 EFI_SUCCESS Set new base address into this image successfully.
1415 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1417 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1418 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1421 // Initialize context
1423 memset (&ImageContext
, 0, sizeof (ImageContext
));
1424 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1425 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1426 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1427 if (EFI_ERROR (Status
)) {
1428 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1432 if (ImageContext
.RelocationsStripped
) {
1433 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1438 // Get PeHeader pointer
1440 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1443 // Get section header list
1445 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1448 sizeof (EFI_IMAGE_FILE_HEADER
) +
1449 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1453 // Set base address into the first section header that doesn't point to code section.
1455 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1456 if ((SectionHeader
->Characteristics
& EFI_IMAGE_SCN_CNT_CODE
) == 0) {
1457 *(UINT64
*) &SectionHeader
->PointerToRelocations
= NewPe32BaseAddress
;
1463 // BaseAddress is set to section header.
1471 IN OUT UINT8
*FileBuffer
,
1472 IN UINT64 NewPe32BaseAddress
1476 Routine Description:
1478 Set new base address into PeImage, and fix up PeImage based on new address.
1482 FileName - Name of file
1483 FileBuffer - Pointer to PeImage.
1484 NewPe32BaseAddress - New Base Address for PE image.
1488 EFI_INVALID_PARAMETER - BaseAddress is not valid.
1489 EFI_SUCCESS - Update PeImage is correctly.
1494 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1496 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1497 UINT8
*MemoryImagePointer
;
1498 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1501 // Initialize context
1503 memset (&ImageContext
, 0, sizeof (ImageContext
));
1504 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1505 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1506 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1507 if (EFI_ERROR (Status
)) {
1508 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1512 if (ImageContext
.RelocationsStripped
) {
1513 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1518 // Get PeHeader pointer
1520 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1523 // Load and Relocate Image Data
1525 MemoryImagePointer
= (UINT8
*) malloc ((UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1526 if (MemoryImagePointer
== NULL
) {
1527 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName
);
1528 return EFI_OUT_OF_RESOURCES
;
1530 memset ((VOID
*) MemoryImagePointer
, 0, (UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1531 ImageContext
.ImageAddress
= ((UINTN
) MemoryImagePointer
+ ImageContext
.SectionAlignment
- 1) & (~((INT64
)ImageContext
.SectionAlignment
- 1));
1533 Status
= PeCoffLoaderLoadImage (&ImageContext
);
1534 if (EFI_ERROR (Status
)) {
1535 Error (NULL
, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName
);
1536 free ((VOID
*) MemoryImagePointer
);
1540 ImageContext
.DestinationAddress
= NewPe32BaseAddress
;
1541 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
1542 if (EFI_ERROR (Status
)) {
1543 Error (NULL
, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName
);
1544 free ((VOID
*) MemoryImagePointer
);
1549 // Copy Relocated data to raw image file.
1551 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1554 sizeof (EFI_IMAGE_FILE_HEADER
) +
1555 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1558 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1560 FileBuffer
+ SectionHeader
->PointerToRawData
,
1561 (VOID
*) (UINTN
) (ImageContext
.ImageAddress
+ SectionHeader
->VirtualAddress
),
1562 SectionHeader
->SizeOfRawData
1566 free ((VOID
*) MemoryImagePointer
);
1569 // Update Image Base Address
1571 if (ImgHdr
->Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1572 ImgHdr
->Pe32
.OptionalHeader
.ImageBase
= (UINT32
) NewPe32BaseAddress
;
1573 } else if (ImgHdr
->Pe32Plus
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
1574 ImgHdr
->Pe32Plus
.OptionalHeader
.ImageBase
= NewPe32BaseAddress
;
1576 Error (NULL
, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
1577 ImgHdr
->Pe32
.OptionalHeader
.Magic
,
1584 // Set new base address into section header
1586 Status
= SetAddressToSectionHeader (FileName
, FileBuffer
, NewPe32BaseAddress
);
1593 IN CHAR8
* DefaultPath
,
1594 IN CHAR8
* AppendPath
,
1598 UINT32 DefaultPathLen
;
1600 CHAR8 QuotesStr
[] = "\"";
1601 strcpy(NewPath
, QuotesStr
);
1602 DefaultPathLen
= strlen(DefaultPath
);
1603 strcat(NewPath
, DefaultPath
);
1605 for (; Index
< DefaultPathLen
+ 1; Index
++) {
1606 if (NewPath
[Index
] == '\\' || NewPath
[Index
] == '/') {
1607 if (NewPath
[Index
+ 1] != '\0') {
1608 NewPath
[Index
] = '/';
1612 if (NewPath
[Index
-1] != '/') {
1613 NewPath
[Index
] = '/';
1614 NewPath
[Index
+ 1] = '\0';
1616 strcat(NewPath
, AppendPath
);
1617 strcat(NewPath
, QuotesStr
);
1623 IN UINT8
*SectionBuffer
,
1624 IN UINT32 BufferLength
1628 Routine Description:
1634 SectionBuffer - Buffer containing the section to parse.
1635 BufferLength - Length of SectionBuffer
1639 EFI_SECTION_ERROR - Problem with section parsing.
1640 (a) compression errors
1641 (b) unrecognized section
1642 EFI_UNSUPPORTED - Do not know how to parse the section.
1643 EFI_SUCCESS - Section successfully parsed.
1644 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1648 EFI_SECTION_TYPE Type
;
1650 UINT32 SectionLength
;
1651 UINT32 SectionHeaderLen
;
1654 UINT32 ParsedLength
;
1655 UINT8
*CompressedBuffer
;
1656 UINT32 CompressedLength
;
1657 UINT8
*UncompressedBuffer
;
1658 UINT32 UncompressedLength
;
1659 UINT8
*ToolOutputBuffer
;
1660 UINT32 ToolOutputLength
;
1661 UINT8 CompressionType
;
1664 UINT8
*ScratchBuffer
;
1665 DECOMPRESS_FUNCTION DecompressFunction
;
1666 GETINFO_FUNCTION GetInfoFunction
;
1668 CHAR8
*ExtractionTool
;
1669 CHAR8
*ToolInputFile
;
1670 CHAR8
*ToolOutputFile
;
1671 CHAR8
*SystemCommand
;
1676 CHAR8
*ToolInputFileName
;
1677 CHAR8
*ToolOutputFileName
;
1679 CHAR8
*VersionString
;
1682 ToolInputFileName
= NULL
;
1683 ToolOutputFileName
= NULL
;
1685 while (ParsedLength
< BufferLength
) {
1686 Ptr
= SectionBuffer
+ ParsedLength
;
1688 SectionLength
= GetLength (((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Size
);
1689 Type
= ((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Type
;
1692 // This is sort of an odd check, but is necessary because FFS files are
1693 // padded to a QWORD boundary, meaning there is potentially a whole section
1694 // header worth of 0xFF bytes.
1696 if (SectionLength
== 0xffffff && Type
== 0xff) {
1702 // Get real section file size
1704 SectionLength
= GetSectionFileLength ((EFI_COMMON_SECTION_HEADER
*) Ptr
);
1705 SectionHeaderLen
= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
1707 SectionName
= SectionNameToStr (Type
);
1708 if (SectionName
!= NULL
) {
1709 printf ("------------------------------------------------------------\n");
1710 printf (" Type: %s\n Size: 0x%08X\n", SectionName
, (unsigned) SectionLength
);
1715 case EFI_SECTION_RAW
:
1716 case EFI_SECTION_PIC
:
1717 case EFI_SECTION_TE
:
1718 // default is no more information
1721 case EFI_SECTION_PE32
:
1723 ToolInputFileName
= "edk2Temp_InputEfi.tmp";
1724 ToolOutputFileName
= "edk2Temp_OutputHash.tmp";
1725 RebaseImage(ToolInputFileName
, (UINT8
*)Ptr
+ SectionHeaderLen
, 0);
1728 (CHAR8
*)Ptr
+ SectionHeaderLen
,
1729 SectionLength
- SectionHeaderLen
1732 SystemCommand
= malloc (
1733 strlen (OPENSSL_COMMAND_FORMAT_STRING
) +
1734 strlen (OpenSslPath
) +
1735 strlen (ToolInputFileName
) +
1736 strlen (ToolOutputFileName
) +
1739 if (SystemCommand
== NULL
) {
1740 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1741 return EFI_OUT_OF_RESOURCES
;
1745 OPENSSL_COMMAND_FORMAT_STRING
,
1751 if (system (SystemCommand
) != EFI_SUCCESS
) {
1752 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
1759 if((fp
= fopen(ToolOutputFileName
,"r")) == NULL
) {
1760 Error (NULL
, 0, 0004, "Hash the PE32 image failed.", NULL
);
1763 fseek(fp
,0,SEEK_SET
);
1764 fseek(fp
,0,SEEK_END
);
1765 nFileLen
= ftell(fp
);
1766 fseek(fp
,0,SEEK_SET
);
1767 StrLine
= malloc(nFileLen
);
1768 if (StrLine
== NULL
) {
1770 free (SystemCommand
);
1771 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1772 return EFI_OUT_OF_RESOURCES
;
1774 fgets(StrLine
, nFileLen
, fp
);
1775 NewStr
= strrchr (StrLine
, '=');
1776 printf (" SHA1: %s\n", NewStr
+ 1);
1781 remove(ToolInputFileName
);
1782 remove(ToolOutputFileName
);
1783 free (SystemCommand
);
1787 case EFI_SECTION_USER_INTERFACE
:
1788 UIFileName
= (CHAR8
*) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
) + 1);
1789 if (UIFileName
== NULL
) {
1790 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1791 return EFI_OUT_OF_RESOURCES
;
1793 Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
, UIFileName
);
1794 printf (" String: %s\n", UIFileName
);
1798 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
1799 Status
= PrintFvInfo (Ptr
+ SectionHeaderLen
, TRUE
);
1800 if (EFI_ERROR (Status
)) {
1801 Error (NULL
, 0, 0003, "printing of FV section contents failed", NULL
);
1802 return EFI_SECTION_ERROR
;
1806 case EFI_SECTION_COMPATIBILITY16
:
1807 case EFI_SECTION_FREEFORM_SUBTYPE_GUID
:
1809 // Section does not contain any further header information.
1813 case EFI_SECTION_PEI_DEPEX
:
1814 case EFI_SECTION_DXE_DEPEX
:
1815 case EFI_SECTION_SMM_DEPEX
:
1816 DumpDepexSection (Ptr
, SectionLength
);
1819 case EFI_SECTION_VERSION
:
1820 printf (" Build Number: 0x%04X\n", *(UINT16
*)(Ptr
+ SectionHeaderLen
));
1821 VersionString
= (CHAR8
*) malloc (UnicodeStrLen (((EFI_VERSION_SECTION
*) Ptr
)->VersionString
) + 1);
1822 if (VersionString
== NULL
) {
1823 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1824 return EFI_OUT_OF_RESOURCES
;
1826 Unicode2AsciiString (((EFI_VERSION_SECTION
*) Ptr
)->VersionString
, VersionString
);
1827 printf (" Version String: %s\n", VersionString
);
1830 case EFI_SECTION_COMPRESSION
:
1831 UncompressedBuffer
= NULL
;
1832 if (SectionHeaderLen
== sizeof (EFI_COMMON_SECTION_HEADER
)) {
1833 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION
);
1834 UncompressedLength
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->UncompressedLength
;
1835 CompressionType
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->CompressionType
;
1837 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION2
);
1838 UncompressedLength
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->UncompressedLength
;
1839 CompressionType
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->CompressionType
;
1841 CompressedLength
= SectionLength
- RealHdrLen
;
1842 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength
);
1844 if (CompressionType
== EFI_NOT_COMPRESSED
) {
1845 printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1846 if (CompressedLength
!= UncompressedLength
) {
1851 "file is not compressed, but the compressed length does not match the uncompressed length",
1854 return EFI_SECTION_ERROR
;
1857 UncompressedBuffer
= Ptr
+ RealHdrLen
;
1858 } else if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1859 GetInfoFunction
= EfiGetInfo
;
1860 DecompressFunction
= EfiDecompress
;
1861 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
1863 CompressedBuffer
= Ptr
+ RealHdrLen
;
1865 Status
= GetInfoFunction (CompressedBuffer
, CompressedLength
, &DstSize
, &ScratchSize
);
1866 if (EFI_ERROR (Status
)) {
1867 Error (NULL
, 0, 0003, "error getting compression info from compression section", NULL
);
1868 return EFI_SECTION_ERROR
;
1871 if (DstSize
!= UncompressedLength
) {
1872 Error (NULL
, 0, 0003, "compression error in the compression section", NULL
);
1873 return EFI_SECTION_ERROR
;
1876 ScratchBuffer
= malloc (ScratchSize
);
1877 if (ScratchBuffer
== NULL
) {
1878 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1879 return EFI_OUT_OF_RESOURCES
;
1881 UncompressedBuffer
= malloc (UncompressedLength
);
1882 if (UncompressedBuffer
== NULL
) {
1883 free (ScratchBuffer
);
1884 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1885 return EFI_OUT_OF_RESOURCES
;
1887 Status
= DecompressFunction (
1895 free (ScratchBuffer
);
1896 if (EFI_ERROR (Status
)) {
1897 Error (NULL
, 0, 0003, "decompress failed", NULL
);
1898 free (UncompressedBuffer
);
1899 return EFI_SECTION_ERROR
;
1902 Error (NULL
, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType
);
1903 return EFI_SECTION_ERROR
;
1906 printf ("/------------ Encapsulation section start -----------------\\\n");
1907 Status
= ParseSection (UncompressedBuffer
, UncompressedLength
);
1908 printf ("\\------------ Encapsulation section end -------------------/\n");
1910 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1912 // We need to deallocate Buffer
1914 free (UncompressedBuffer
);
1917 if (EFI_ERROR (Status
)) {
1918 Error (NULL
, 0, 0003, "failed to parse section", NULL
);
1919 return EFI_SECTION_ERROR
;
1923 case EFI_SECTION_GUID_DEFINED
:
1924 if (SectionHeaderLen
== sizeof(EFI_COMMON_SECTION_HEADER
)) {
1925 EfiGuid
= &((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
;
1926 DataOffset
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
;
1927 Attributes
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->Attributes
;
1929 EfiGuid
= &((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->SectionDefinitionGuid
;
1930 DataOffset
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->DataOffset
;
1931 Attributes
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->Attributes
;
1933 printf (" SectionDefinitionGuid: ");
1934 PrintGuid (EfiGuid
);
1936 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset
);
1937 printf (" Attributes: 0x%04X\n", (unsigned) Attributes
);
1940 LookupGuidedSectionToolPath (
1941 mParsedGuidedSectionTools
,
1945 if (ExtractionTool
!= NULL
) {
1947 ToolInputFile
= CloneString (tmpnam (NULL
));
1948 ToolOutputFile
= CloneString (tmpnam (NULL
));
1950 char tmp1
[] = "/tmp/fileXXXXXX";
1951 char tmp2
[] = "/tmp/fileXXXXXX";
1954 fd1
= mkstemp(tmp1
);
1955 fd2
= mkstemp(tmp2
);
1956 ToolInputFile
= CloneString(tmp1
);
1957 ToolOutputFile
= CloneString(tmp2
);
1962 if ((ToolInputFile
== NULL
) || (ToolOutputFile
== NULL
)) {
1963 if (ToolInputFile
!= NULL
) {
1964 free (ToolInputFile
);
1966 if (ToolOutputFile
!= NULL
) {
1967 free (ToolOutputFile
);
1969 free (ExtractionTool
);
1971 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1972 return EFI_OUT_OF_RESOURCES
;
1976 // Construction 'system' command string
1978 SystemCommand
= malloc (
1979 strlen (EXTRACT_COMMAND_FORMAT_STRING
) +
1980 strlen (ExtractionTool
) +
1981 strlen (ToolInputFile
) +
1982 strlen (ToolOutputFile
) +
1985 if (SystemCommand
== NULL
) {
1986 free (ToolInputFile
);
1987 free (ToolOutputFile
);
1988 free (ExtractionTool
);
1990 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1991 return EFI_OUT_OF_RESOURCES
;
1995 EXTRACT_COMMAND_FORMAT_STRING
,
2000 free (ExtractionTool
);
2005 (CHAR8
*) SectionBuffer
+ DataOffset
,
2006 BufferLength
- DataOffset
2009 system (SystemCommand
);
2010 remove (ToolInputFile
);
2011 free (ToolInputFile
);
2016 (CHAR8
**)&ToolOutputBuffer
,
2019 remove (ToolOutputFile
);
2020 free (ToolOutputFile
);
2021 free (SystemCommand
);
2022 if (EFI_ERROR (Status
)) {
2023 Error (NULL
, 0, 0004, "unable to read decoded GUIDED section", NULL
);
2024 return EFI_SECTION_ERROR
;
2027 printf ("/------------ Encapsulation section start -----------------\\\n");
2028 Status
= ParseSection (
2032 if (EFI_ERROR (Status
)) {
2033 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
2034 return EFI_SECTION_ERROR
;
2036 printf ("\\------------ Encapsulation section end -------------------/\n");
2039 // Check for CRC32 sections which we can handle internally if needed.
2041 } else if (!CompareGuid (
2043 &gEfiCrc32GuidedSectionExtractionProtocolGuid
2047 // CRC32 guided section
2049 printf ("/------------ Encapsulation section start -----------------\\\n");
2050 Status
= ParseSection (
2051 SectionBuffer
+ DataOffset
,
2052 BufferLength
- DataOffset
2054 if (EFI_ERROR (Status
)) {
2055 Error (NULL
, 0, 0003, "parse of CRC32 GUIDED section failed", NULL
);
2056 return EFI_SECTION_ERROR
;
2058 printf ("\\------------ Encapsulation section end -------------------/\n");
2061 // We don't know how to parse it now.
2063 Error (NULL
, 0, 0003, "Error parsing section", \
2064 "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).");
2065 return EFI_UNSUPPORTED
;
2071 // Unknown section, return error
2073 Error (NULL
, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type
);
2074 return EFI_SECTION_ERROR
;
2077 ParsedLength
+= SectionLength
;
2079 // We make then next section begin on a 4-byte boundary
2081 ParsedLength
= GetOccupiedSize (ParsedLength
, 4);
2084 if (ParsedLength
< BufferLength
) {
2085 Error (NULL
, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL
);
2086 return EFI_SECTION_ERROR
;
2095 IN UINT32 SectionLength
2099 Routine Description:
2101 GC_TODO: Add function description
2105 Ptr - GC_TODO: add argument description
2106 SectionLength - GC_TODO: add argument description
2110 EFI_SUCCESS - GC_TODO: Add description for return value
2114 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
2117 // Need at least a section header + data
2119 if (SectionLength
<= sizeof (EFI_COMMON_SECTION_HEADER
)) {
2123 Ptr
+= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2124 SectionLength
-= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2125 while (SectionLength
> 0) {
2128 case EFI_DEP_BEFORE
:
2129 printf ("BEFORE\n");
2142 PrintGuidToBuffer ((EFI_GUID
*) (Ptr
+ 1), GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
2143 printf ("%s ", GuidBuffer
);
2144 PrintGuidName (GuidBuffer
);
2147 // PrintGuid ((EFI_GUID *)(Ptr + 1));
2150 SectionLength
-= 17;
2184 printf ("END DEPEX\n");
2196 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr
);
2210 Routine Description:
2212 GC_TODO: Add function description
2216 GuidStr - GC_TODO: add argument description
2220 EFI_SUCCESS - GC_TODO: Add description for return value
2221 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
2225 GUID_TO_BASENAME
*GPtr
;
2227 // If we have a list of guid-to-basenames, then go through the list to
2228 // look for a guid string match. If found, print the basename to stdout,
2229 // otherwise return a failure.
2231 GPtr
= mGuidBaseNameList
;
2232 while (GPtr
!= NULL
) {
2233 if (_stricmp ((CHAR8
*) GuidStr
, (CHAR8
*) GPtr
->Guid
) == 0) {
2234 printf ("%s", GPtr
->BaseName
);
2241 return EFI_INVALID_PARAMETER
;
2245 ParseGuidBaseNameFile (
2250 Routine Description:
2252 GC_TODO: Add function description
2256 FileName - GC_TODO: add argument description
2260 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
2261 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
2262 EFI_SUCCESS - GC_TODO: Add description for return value
2267 CHAR8 Line
[MAX_LINE_LEN
];
2268 CHAR8 FormatString
[MAX_LINE_LEN
];
2269 GUID_TO_BASENAME
*GPtr
;
2271 if ((Fptr
= fopen (LongFilePath (FileName
), "r")) == NULL
) {
2272 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName
);
2273 return EFI_DEVICE_ERROR
;
2277 // Generate the format string for fscanf
2282 (unsigned) sizeof (GPtr
->Guid
) - 1,
2283 (unsigned) sizeof (GPtr
->BaseName
) - 1
2286 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
2288 // Allocate space for another guid/basename element
2290 GPtr
= malloc (sizeof (GUID_TO_BASENAME
));
2293 return EFI_OUT_OF_RESOURCES
;
2296 memset ((char *) GPtr
, 0, sizeof (GUID_TO_BASENAME
));
2297 if (sscanf (Line
, FormatString
, GPtr
->Guid
, GPtr
->BaseName
) == 2) {
2298 GPtr
->Next
= mGuidBaseNameList
;
2299 mGuidBaseNameList
= GPtr
;
2302 // Some sort of error. Just continue.
2313 FreeGuidBaseNameList (
2318 Routine Description:
2320 GC_TODO: Add function description
2328 EFI_SUCCESS - GC_TODO: Add description for return value
2332 GUID_TO_BASENAME
*Next
;
2334 while (mGuidBaseNameList
!= NULL
) {
2335 Next
= mGuidBaseNameList
->Next
;
2336 free (mGuidBaseNameList
);
2337 mGuidBaseNameList
= Next
;
2346 LoadGuidedSectionToolsTxt (
2347 IN CHAR8
* FirmwareVolumeFilename
2350 CHAR8
* PeerFilename
;
2357 Places
[0] = FirmwareVolumeFilename
;
2358 //Places[1] = mUtilityFilename;
2360 mParsedGuidedSectionTools
= NULL
;
2362 for (Index
= 0; Index
< (sizeof(Places
)/sizeof(Places
[0])); Index
++) {
2363 PeerFilename
= OsPathPeerFilePath (Places
[Index
], "GuidedSectionTools.txt");
2364 //printf("Loading %s...\n", PeerFilename);
2365 if (OsPathExists (PeerFilename
)) {
2366 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (PeerFilename
);
2368 free (PeerFilename
);
2369 if (mParsedGuidedSectionTools
!= NULL
) {
2382 Routine Description:
2384 GC_TODO: Add function description
2392 GC_TODO: add return values
2399 fprintf (stdout
, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME
);
2402 // Copyright declaration
2404 fprintf (stdout
, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
2405 fprintf (stdout
, " Display Tiano Firmware Volume FFS image information\n\n");
2410 fprintf (stdout
, "optional arguments:\n");
2411 fprintf (stdout
, " -h, --help\n\
2412 Show this help message and exit\n");
2413 fprintf (stdout
, " --version\n\
2414 Show program's version number and exit\n");
2415 fprintf (stdout
, " -d [DEBUG], --debug [DEBUG]\n\
2416 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
2417 fprintf (stdout
, " -v, --verbose\n\
2418 Print informational statements\n");
2419 fprintf (stdout
, " -q, --quiet\n\
2420 Returns the exit code, error messages will be displayed\n");
2421 fprintf (stdout
, " -s, --silent\n\
2422 Returns only the exit code; informational and error\n\
2423 messages are not displayed\n");
2424 fprintf (stdout
, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
2425 Parse the basename to file-guid cross reference file(s)\n");
2426 fprintf (stdout
, " -f OFFSET, --offset OFFSET\n\
2427 The offset from the start of the input file to start \n\
2428 processing an FV\n");
2429 fprintf (stdout
, " --hash\n\
2430 Generate HASH value of the entire PE image\n");
2431 fprintf (stdout
, " --sfo\n\
2432 Reserved for future use\n");