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
;
46 EFI_GUID gPeiAprioriFileNameGuid
= { 0x1b45cc0a, 0x156a, 0x428a, { 0XAF, 0x62, 0x49, 0x86, 0x4d, 0xa0, 0xe6, 0xe6 }};
47 EFI_GUID gAprioriGuid
= { 0xFC510EE7, 0xFFDC, 0x11D4, { 0xBD, 0x41, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 }};
49 #define UTILITY_MAJOR_VERSION 1
50 #define UTILITY_MINOR_VERSION 0
52 #define UTILITY_NAME "VolInfo"
54 #define EFI_SECTION_ERROR EFIERR (100)
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_LINE_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_FFS_FILE_HEADER
*FileHeader
121 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
122 EFI_FFS_FILE_HEADER
*FileHeader
,
123 BOOLEAN ErasePolarity
135 LoadGuidedSectionToolsTxt (
136 IN CHAR8
* FirmwareVolumeFilename
141 IN CHAR8
* DefaultPath
,
142 IN CHAR8
* AppendPath
,
159 Returns the length of a null-terminated unicode string.
163 String - The pointer to a null-terminated unicode string.
173 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
180 Unicode2AsciiString (
182 OUT CHAR8
*Destination
188 Convert a null-terminated unicode string to a null-terminated ascii string.
192 Source - The pointer to the null-terminated input unicode string.
193 Destination - The pointer to the null-terminated output ascii string.
201 while (*Source
!= '\0') {
202 *(Destination
++) = (CHAR8
) *(Source
++);
205 // End the ascii with a NULL.
219 GC_TODO: Add function description
223 argc - GC_TODO: add argument description
224 ] - GC_TODO: add argument description
228 GC_TODO: add return values
234 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
;
238 BOOLEAN ErasePolarity
;
241 CHAR8
*OpenSslCommand
;
243 SetUtilityName (UTILITY_NAME
);
245 // Print utility header
247 printf ("%s Version %d.%d Build %s\n",
249 UTILITY_MAJOR_VERSION
,
250 UTILITY_MINOR_VERSION
,
265 // Look for help options
267 if ((strcmp(argv
[0], "-h") == 0) || (strcmp(argv
[0], "--help") == 0) ||
268 (strcmp(argv
[0], "-?") == 0) || (strcmp(argv
[0], "/?") == 0)) {
270 return STATUS_SUCCESS
;
273 // Version has already be printed, so just return success
275 if (strcmp(argv
[0], "--version") == 0) {
276 return STATUS_SUCCESS
;
280 // If they specified -x xref guid/basename cross-reference files, process it.
281 // This will print the basename beside each file guid. To use it, specify
282 // -x xref_filename to processdsc, then use xref_filename as a parameter
286 if ((strcmp(argv
[0], "-x") == 0) || (strcmp(argv
[0], "--xref") == 0)) {
287 ParseGuidBaseNameFile (argv
[1]);
288 printf("ParseGuidBaseNameFile: %s\n", argv
[1]);
293 if (strcmp(argv
[0], "--offset") == 0) {
297 if ((argv
[1][0] == '0') && (tolower ((int)argv
[1][1]) == 'x')) {
298 if (sscanf (argv
[1], "%x", &Offset
) != 1) {
299 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
300 return GetUtilityStatus ();
303 if (sscanf (argv
[1], "%d", &Offset
) != 1) {
304 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
305 return GetUtilityStatus ();
308 // See if they said something like "64K"
310 if (tolower ((int)argv
[1][strlen (argv
[1]) - 1]) == 'k') {
319 if ((stricmp (argv
[0], "--hash") == 0)) {
320 if (EnableHash
== TRUE
) {
322 // --hash already given in the option, ignore this one
329 OpenSslCommand
= "openssl";
330 OpenSslEnv
= getenv("OPENSSL_PATH");
331 if (OpenSslEnv
== NULL
) {
332 OpenSslPath
= OpenSslCommand
;
335 // We add quotes to the Openssl Path in case it has space characters
337 OpenSslPath
= malloc(2+strlen(OpenSslEnv
)+strlen(OpenSslCommand
)+1);
338 if (OpenSslPath
== NULL
) {
339 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
340 return GetUtilityStatus ();
342 CombinePath(OpenSslEnv
, OpenSslCommand
, OpenSslPath
);
344 if (OpenSslPath
== NULL
){
345 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
346 return GetUtilityStatus ();
353 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
354 SetPrintLevel (VERBOSE_LOG_LEVEL
);
360 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
361 SetPrintLevel (KEY_LOG_LEVEL
);
367 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
368 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
369 if (EFI_ERROR (Status
)) {
370 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
374 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel
);
377 SetPrintLevel (LogLevel
);
378 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
384 mUtilityFilename
= argv
[0];
390 // Open the file containing the FV
392 if (mUtilityFilename
== NULL
) {
393 Error (NULL
, 0, 1001, "Missing option", "Input files are not specified");
394 return GetUtilityStatus ();
396 InputFile
= fopen (LongFilePath (mUtilityFilename
), "rb");
397 if (InputFile
== NULL
) {
398 Error (NULL
, 0, 0001, "Error opening the input file", mUtilityFilename
);
399 return GetUtilityStatus ();
402 // Skip over pad bytes if specified. This is used if they prepend 0xff
403 // data to the FV image binary.
406 fseek (InputFile
, Offset
, SEEK_SET
);
409 // Determine size of FV
411 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
412 if (EFI_ERROR (Status
)) {
413 Error (NULL
, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename
);
415 return GetUtilityStatus ();
418 // Allocate a buffer for the FV image
420 FvImage
= malloc (FvSize
);
421 if (FvImage
== NULL
) {
422 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
424 return GetUtilityStatus ();
427 // Seek to the start of the image, then read the entire FV to the buffer
429 fseek (InputFile
, Offset
, SEEK_SET
);
430 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
432 if ((unsigned int) BytesRead
!= FvSize
) {
433 Error (NULL
, 0, 0004, "error reading FvImage from", mUtilityFilename
);
435 return GetUtilityStatus ();
438 LoadGuidedSectionToolsTxt (mUtilityFilename
);
440 PrintFvInfo (FvImage
, FALSE
);
446 FreeGuidBaseNameList ();
447 return GetUtilityStatus ();
461 GC_TODO: Add function description
465 Fv - Firmware Volume to print information about
466 IsChildFv - Flag specifies whether the input FV is a child FV.
476 BOOLEAN ErasePolarity
;
478 EFI_FFS_FILE_HEADER
*CurrentFile
;
481 Status
= FvBufGetSize (Fv
, &FvSize
);
485 (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) ?
489 // Get the first file
492 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
493 if (EFI_ERROR (Status
)) {
494 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
495 return GetUtilityStatus ();
498 // Display information about files found
500 while (CurrentFile
!= NULL
) {
502 // Increment the number of files counter
507 // Display info about this file
509 Status
= PrintFileInfo (Fv
, CurrentFile
, ErasePolarity
);
510 if (EFI_ERROR (Status
)) {
511 Error (NULL
, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
512 return GetUtilityStatus ();
517 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
518 if (Status
== EFI_NOT_FOUND
) {
520 } else if (EFI_ERROR (Status
)) {
521 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
522 return GetUtilityStatus ();
527 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles
);
529 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles
);
537 IN UINT32 ActualSize
,
544 This function returns the next larger size that meets the alignment
545 requirement specified.
550 Alignment The desired alignment.
554 EFI_SUCCESS Function completed successfully.
555 EFI_ABORTED The function encountered an error.
561 OccupiedSize
= ActualSize
;
562 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
572 IN EFI_SECTION_TYPE Type
578 Converts EFI Section names to Strings
582 Type - The EFI Section type
586 CHAR8* - Pointer to the String containing the section name.
591 CHAR8
*SectionTypeStringTable
[] = {
599 "EFI_SECTION_COMPRESSION",
603 "EFI_SECTION_GUID_DEFINED",
607 "Unknown section type - Reserved 0x03",
611 "Unknown section type - Reserved 0x04",
615 "Unknown section type - Reserved 0x05",
619 "Unknown section type - Reserved 0x06",
623 "Unknown section type - Reserved 0x07",
627 "Unknown section type - Reserved 0x08",
631 "Unknown section type - Reserved 0x09",
635 "Unknown section type - Reserved 0x0A",
639 "Unknown section type - Reserved 0x0B",
643 "Unknown section type - Reserved 0x0C",
647 "Unknown section type - Reserved 0x0D",
651 "Unknown section type - Reserved 0x0E",
655 "Unknown section type - Reserved 0x0E",
671 "EFI_SECTION_DXE_DEPEX",
675 "EFI_SECTION_VERSION",
679 "EFI_SECTION_USER_INTERFACE",
683 "EFI_SECTION_COMPATIBILITY16",
687 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
691 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
699 "Unknown section type - 0x1A",
703 "EFI_SECTION_PEI_DEPEX",
707 "EFI_SECTION_SMM_DEPEX",
711 "Unknown section type - Reserved - beyond last defined section"
714 if (Type
> EFI_SECTION_LAST_SECTION_TYPE
) {
715 Type
= EFI_SECTION_LAST_SECTION_TYPE
+ 1;
718 SectionStr
= malloc (100);
719 if (SectionStr
== NULL
) {
720 printf ("Error: Out of memory resources.\n");
723 strcpy (SectionStr
, SectionTypeStringTable
[Type
]);
732 OUT BOOLEAN
*ErasePolarity
738 This function determines the size of the FV and the erase polarity. The
739 erase polarity is the FALSE value for file state.
743 InputFile The file that contains the FV image.
744 FvSize The size of the FV.
745 ErasePolarity The FV erase polarity.
749 EFI_SUCCESS Function completed successfully.
750 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
751 EFI_ABORTED The function encountered an error.
755 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
756 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
765 // Check input parameters
767 if (InputFile
== NULL
|| FvSize
== NULL
|| ErasePolarity
== NULL
) {
768 Error (__FILE__
, __LINE__
, 0, "application error", "invalid parameter to function");
769 return EFI_INVALID_PARAMETER
;
774 ReadSize
= fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
778 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
779 Signature
[0] = VolumeHeader
.Signature
;
783 // Print FV header information
785 printf ("Signature: %s (%X)\n", (char *) Signature
, (unsigned) VolumeHeader
.Signature
);
786 printf ("Attributes: %X\n", (unsigned) VolumeHeader
.Attributes
);
788 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_DISABLED_CAP
) {
789 printf (" EFI_FVB2_READ_DISABLED_CAP\n");
792 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_ENABLED_CAP
) {
793 printf (" EFI_FVB2_READ_ENABLED_CAP\n");
796 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_STATUS
) {
797 printf (" EFI_FVB2_READ_STATUS\n");
800 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_DISABLED_CAP
) {
801 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
804 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_ENABLED_CAP
) {
805 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
808 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_STATUS
) {
809 printf (" EFI_FVB2_WRITE_STATUS\n");
812 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_CAP
) {
813 printf (" EFI_FVB2_LOCK_CAP\n");
816 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_STATUS
) {
817 printf (" EFI_FVB2_LOCK_STATUS\n");
820 if (VolumeHeader
.Attributes
& EFI_FVB2_STICKY_WRITE
) {
821 printf (" EFI_FVB2_STICKY_WRITE\n");
824 if (VolumeHeader
.Attributes
& EFI_FVB2_MEMORY_MAPPED
) {
825 printf (" EFI_FVB2_MEMORY_MAPPED\n");
828 if (VolumeHeader
.Attributes
& EFI_FVB2_ERASE_POLARITY
) {
829 printf (" EFI_FVB2_ERASE_POLARITY\n");
830 *ErasePolarity
= TRUE
;
833 #if (PI_SPECIFICATION_VERSION < 0x00010000)
834 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
835 printf (" EFI_FVB2_ALIGNMENT\n");
838 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
839 printf (" EFI_FVB2_ALIGNMENT_2\n");
842 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
843 printf (" EFI_FVB2_ALIGNMENT_4\n");
846 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
847 printf (" EFI_FVB2_ALIGNMENT_8\n");
850 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
851 printf (" EFI_FVB2_ALIGNMENT_16\n");
854 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
855 printf (" EFI_FVB2_ALIGNMENT_32\n");
858 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
859 printf (" EFI_FVB2_ALIGNMENT_64\n");
862 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
863 printf (" EFI_FVB2_ALIGNMENT_128\n");
866 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
867 printf (" EFI_FVB2_ALIGNMENT_256\n");
870 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
871 printf (" EFI_FVB2_ALIGNMENT_512\n");
874 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
875 printf (" EFI_FVB2_ALIGNMENT_1K\n");
878 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
879 printf (" EFI_FVB2_ALIGNMENT_2K\n");
882 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
883 printf (" EFI_FVB2_ALIGNMENT_4K\n");
886 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
887 printf (" EFI_FVB2_ALIGNMENT_8K\n");
890 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
891 printf (" EFI_FVB2_ALIGNMENT_16K\n");
894 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
895 printf (" EFI_FVB2_ALIGNMENT_32K\n");
898 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
899 printf (" EFI_FVB2_ALIGNMENT_64K\n");
904 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_CAP
) {
905 printf (" EFI_FVB2_READ_LOCK_CAP\n");
908 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_STATUS
) {
909 printf (" EFI_FVB2_READ_LOCK_STATUS\n");
912 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_CAP
) {
913 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
916 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_STATUS
) {
917 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
920 switch (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
921 case EFI_FVB2_ALIGNMENT_1
:
922 printf (" EFI_FVB2_ALIGNMENT_1\n");
925 case EFI_FVB2_ALIGNMENT_2
:
926 printf (" EFI_FVB2_ALIGNMENT_2\n");
929 case EFI_FVB2_ALIGNMENT_4
:
930 printf (" EFI_FVB2_ALIGNMENT_4\n");
933 case EFI_FVB2_ALIGNMENT_8
:
934 printf (" EFI_FVB2_ALIGNMENT_8\n");
937 case EFI_FVB2_ALIGNMENT_16
:
938 printf (" EFI_FVB2_ALIGNMENT_16\n");
941 case EFI_FVB2_ALIGNMENT_32
:
942 printf (" EFI_FVB2_ALIGNMENT_32\n");
945 case EFI_FVB2_ALIGNMENT_64
:
946 printf (" EFI_FVB2_ALIGNMENT_64\n");
949 case EFI_FVB2_ALIGNMENT_128
:
950 printf (" EFI_FVB2_ALIGNMENT_128\n");
953 case EFI_FVB2_ALIGNMENT_256
:
954 printf (" EFI_FVB2_ALIGNMENT_256\n");
957 case EFI_FVB2_ALIGNMENT_512
:
958 printf (" EFI_FVB2_ALIGNMENT_512\n");
961 case EFI_FVB2_ALIGNMENT_1K
:
962 printf (" EFI_FVB2_ALIGNMENT_1K\n");
965 case EFI_FVB2_ALIGNMENT_2K
:
966 printf (" EFI_FVB2_ALIGNMENT_2K\n");
969 case EFI_FVB2_ALIGNMENT_4K
:
970 printf (" EFI_FVB2_ALIGNMENT_4K\n");
973 case EFI_FVB2_ALIGNMENT_8K
:
974 printf (" EFI_FVB2_ALIGNMENT_8K\n");
977 case EFI_FVB2_ALIGNMENT_16K
:
978 printf (" EFI_FVB2_ALIGNMENT_16K\n");
981 case EFI_FVB2_ALIGNMENT_32K
:
982 printf (" EFI_FVB2_ALIGNMENT_32K\n");
985 case EFI_FVB2_ALIGNMENT_64K
:
986 printf (" EFI_FVB2_ALIGNMENT_64K\n");
989 case EFI_FVB2_ALIGNMENT_128K
:
990 printf (" EFI_FVB2_ALIGNMENT_128K\n");
993 case EFI_FVB2_ALIGNMENT_256K
:
994 printf (" EFI_FVB2_ALIGNMENT_256K\n");
997 case EFI_FVB2_ALIGNMENT_512K
:
998 printf (" EFI_FVB2_ALIGNMENT_512K\n");
1001 case EFI_FVB2_ALIGNMENT_1M
:
1002 printf (" EFI_FVB2_ALIGNMENT_1M\n");
1005 case EFI_FVB2_ALIGNMENT_2M
:
1006 printf (" EFI_FVB2_ALIGNMENT_2M\n");
1009 case EFI_FVB2_ALIGNMENT_4M
:
1010 printf (" EFI_FVB2_ALIGNMENT_4M\n");
1013 case EFI_FVB2_ALIGNMENT_8M
:
1014 printf (" EFI_FVB2_ALIGNMENT_8M\n");
1017 case EFI_FVB2_ALIGNMENT_16M
:
1018 printf (" EFI_FVB2_ALIGNMENT_16M\n");
1021 case EFI_FVB2_ALIGNMENT_32M
:
1022 printf (" EFI_FVB2_ALIGNMENT_32M\n");
1025 case EFI_FVB2_ALIGNMENT_64M
:
1026 printf (" EFI_FVB2_ALIGNMENT_64M\n");
1029 case EFI_FVB2_ALIGNMENT_128M
:
1030 printf (" EFI_FVB2_ALIGNMENT_128M\n");
1033 case EFI_FVB2_ALIGNMENT_256M
:
1034 printf (" EFI_FVB2_ALIGNMENT_256M\n");
1037 case EFI_FVB2_ALIGNMENT_512M
:
1038 printf (" EFI_FVB2_ALIGNMENT_512M\n");
1041 case EFI_FVB2_ALIGNMENT_1G
:
1042 printf (" EFI_FVB2_ALIGNMENT_1G\n");
1045 case EFI_FVB2_ALIGNMENT_2G
:
1046 printf (" EFI_FVB2_ALIGNMENT_2G\n");
1051 printf ("Header Length: 0x%08X\n", VolumeHeader
.HeaderLength
);
1052 printf ("File System ID: ");
1053 PrintGuid (&VolumeHeader
.FileSystemGuid
);
1057 printf ("Revision: 0x%04X\n", VolumeHeader
.Revision
);
1060 ReadSize
= fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
1061 if (ReadSize
!= 1) {
1064 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
1066 if (BlockMap
.NumBlocks
!= 0) {
1067 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap
.NumBlocks
);
1068 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap
.Length
);
1069 Size
+= BlockMap
.NumBlocks
* BlockMap
.Length
;
1072 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.Length
== 0));
1074 if (BytesRead
!= VolumeHeader
.HeaderLength
) {
1075 printf ("ERROR: Header length not consistent with Block Maps!\n");
1079 if (VolumeHeader
.FvLength
!= Size
) {
1080 printf ("ERROR: Volume Size not consistent with Block Maps!\n");
1084 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size
);
1089 // rewind (InputFile);
1097 EFI_FFS_FILE_HEADER
*FileHeader
1101 Routine Description:
1103 Print GUIDs from the APRIORI file
1107 FileHeader - The file header
1111 EFI_SUCCESS - The APRIORI file was parsed correctly
1112 EFI_SECTION_ERROR - Problem with file parsing
1116 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1119 HeaderSize
= FvBufGetFfsHeaderSize (FileHeader
);
1121 if (FileHeader
->Type
!= EFI_FV_FILETYPE_FREEFORM
)
1122 return EFI_SECTION_ERROR
;
1124 EFI_COMMON_SECTION_HEADER
* SectionHeader
= (EFI_COMMON_SECTION_HEADER
*) ((UINTN
) FileHeader
+ HeaderSize
);
1125 if (SectionHeader
->Type
!= EFI_SECTION_RAW
)
1126 return EFI_SECTION_ERROR
;
1128 UINT32 SectionLength
= GetSectionFileLength (SectionHeader
);
1129 EFI_GUID
* FileName
= (EFI_GUID
*) ((UINT8
*) SectionHeader
+ sizeof (EFI_COMMON_SECTION_HEADER
));
1130 while (((UINT8
*) FileName
) < ((UINT8
*) SectionHeader
+ SectionLength
)) {
1131 PrintGuidToBuffer (FileName
, GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
1132 printf ("%s ", GuidBuffer
);
1133 PrintGuidName (GuidBuffer
);
1144 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
1145 EFI_FFS_FILE_HEADER
*FileHeader
,
1146 BOOLEAN ErasePolarity
1150 Routine Description:
1152 GC_TODO: Add function description
1156 FvImage - GC_TODO: add argument description
1157 FileHeader - GC_TODO: add argument description
1158 ErasePolarity - GC_TODO: add argument description
1162 EFI_SUCCESS - GC_TODO: Add description for return value
1163 EFI_ABORTED - GC_TODO: Add description for return value
1170 EFI_FFS_FILE_HEADER2 BlankHeader
;
1172 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1174 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1178 // Check if we have free space
1180 HeaderSize
= FvBufGetFfsHeaderSize(FileHeader
);
1181 if (ErasePolarity
) {
1182 memset (&BlankHeader
, -1, HeaderSize
);
1184 memset (&BlankHeader
, 0, HeaderSize
);
1187 if (memcmp (&BlankHeader
, FileHeader
, HeaderSize
) == 0) {
1191 // Print file information.
1193 printf ("============================================================\n");
1195 printf ("File Name: ");
1196 PrintGuidToBuffer (&FileHeader
->Name
, GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
1197 printf ("%s ", GuidBuffer
);
1198 PrintGuidName (GuidBuffer
);
1202 // PrintGuid (&FileHeader->Name);
1205 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1206 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN
) FileHeader
- (UINTN
) FvImage
));
1207 printf ("File Length: 0x%08X\n", (unsigned) FileLength
);
1208 printf ("File Attributes: 0x%02X\n", FileHeader
->Attributes
);
1209 printf ("File State: 0x%02X\n", FileHeader
->State
);
1214 FileState
= GetFileState (ErasePolarity
, FileHeader
);
1216 switch (FileState
) {
1218 case EFI_FILE_HEADER_CONSTRUCTION
:
1219 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
1222 case EFI_FILE_HEADER_INVALID
:
1223 printf (" EFI_FILE_HEADER_INVALID\n");
1226 case EFI_FILE_HEADER_VALID
:
1227 printf (" EFI_FILE_HEADER_VALID\n");
1228 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1229 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1230 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1231 if (Checksum
!= 0) {
1232 printf ("ERROR: Header checksum invalid.\n");
1238 case EFI_FILE_DELETED
:
1239 printf (" EFI_FILE_DELETED\n");
1241 case EFI_FILE_MARKED_FOR_UPDATE
:
1242 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
1244 case EFI_FILE_DATA_VALID
:
1245 printf (" EFI_FILE_DATA_VALID\n");
1248 // Calculate header checksum
1250 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1251 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1252 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1253 if (Checksum
!= 0) {
1254 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer
);
1258 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1260 if (FileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
1262 // Calculate file checksum
1264 Checksum
= CalculateSum8 ((UINT8
*)FileHeader
+ HeaderSize
, FileLength
- HeaderSize
);
1265 Checksum
= Checksum
+ FileHeader
->IntegrityCheck
.Checksum
.File
;
1266 if (Checksum
!= 0) {
1267 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer
);
1271 if (FileHeader
->IntegrityCheck
.Checksum
.File
!= FFS_FIXED_CHECKSUM
) {
1272 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
);
1276 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1278 // Verify tail if present
1280 if (FileHeader
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
1282 // Verify tail is complement of integrity check field in the header.
1284 Tail
= (UINT16
*) ((UINTN
) FileHeader
+ GetLength (FileHeader
->Size
) - sizeof (EFI_FFS_INTEGRITY_CHECK
));
1285 if (FileHeader
->IntegrityCheck
.TailReference
!= (UINT16
)~(*Tail
)) {
1286 Error (NULL
, 0, 0003, "error parsing FFS file", \
1287 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer
);
1295 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer
);
1299 printf ("File Type: 0x%02X ", FileHeader
->Type
);
1301 switch (FileHeader
->Type
) {
1303 case EFI_FV_FILETYPE_RAW
:
1304 printf ("EFI_FV_FILETYPE_RAW\n");
1307 case EFI_FV_FILETYPE_FREEFORM
:
1308 printf ("EFI_FV_FILETYPE_FREEFORM\n");
1311 case EFI_FV_FILETYPE_SECURITY_CORE
:
1312 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
1315 case EFI_FV_FILETYPE_PEI_CORE
:
1316 printf ("EFI_FV_FILETYPE_PEI_CORE\n");
1319 case EFI_FV_FILETYPE_DXE_CORE
:
1320 printf ("EFI_FV_FILETYPE_DXE_CORE\n");
1323 case EFI_FV_FILETYPE_PEIM
:
1324 printf ("EFI_FV_FILETYPE_PEIM\n");
1327 case EFI_FV_FILETYPE_DRIVER
:
1328 printf ("EFI_FV_FILETYPE_DRIVER\n");
1331 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
1332 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
1335 case EFI_FV_FILETYPE_APPLICATION
:
1336 printf ("EFI_FV_FILETYPE_APPLICATION\n");
1339 case EFI_FV_FILETYPE_SMM
:
1340 printf ("EFI_FV_FILETYPE_SMM\n");
1343 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
:
1344 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1347 case EFI_FV_FILETYPE_COMBINED_SMM_DXE
:
1348 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
1351 case EFI_FV_FILETYPE_SMM_CORE
:
1352 printf ("EFI_FV_FILETYPE_SMM_CORE\n");
1355 case EFI_FV_FILETYPE_MM_STANDALONE
:
1356 printf ("EFI_FV_FILETYPE_MM_STANDALONE\n");
1359 case EFI_FV_FILETYPE_MM_CORE_STANDALONE
:
1360 printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n");
1363 case EFI_FV_FILETYPE_FFS_PAD
:
1364 printf ("EFI_FV_FILETYPE_FFS_PAD\n");
1368 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader
->Type
);
1373 switch (FileHeader
->Type
) {
1375 case EFI_FV_FILETYPE_ALL
:
1376 case EFI_FV_FILETYPE_RAW
:
1377 case EFI_FV_FILETYPE_FFS_PAD
:
1382 // All other files have sections
1384 Status
= ParseSection (
1385 (UINT8
*) ((UINTN
) FileHeader
+ HeaderSize
),
1386 FvBufGetFfsFileSize (FileHeader
) - HeaderSize
1388 if (EFI_ERROR (Status
)) {
1390 // printf ("ERROR: Parsing the FFS file.\n");
1399 &gPeiAprioriFileNameGuid
1403 printf("PEI APRIORI FILE:\n");
1404 return PrintAprioriFile (FileHeader
);
1412 printf("DXE APRIORI FILE:\n");
1413 return PrintAprioriFile (FileHeader
);
1421 IN VOID
*FileHandle
,
1422 IN UINTN FileOffset
,
1423 IN OUT UINT32
*ReadSize
,
1428 Routine Description:
1430 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
1434 FileHandle - The handle to the PE/COFF file
1436 FileOffset - The offset, in bytes, into the file to read
1438 ReadSize - The number of bytes to read from the file starting at FileOffset
1440 Buffer - A pointer to the buffer to read the data into.
1444 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1448 CHAR8
*Destination8
;
1452 Destination8
= Buffer
;
1453 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
1456 *(Destination8
++) = *(Source8
++);
1463 SetAddressToSectionHeader (
1465 IN OUT UINT8
*FileBuffer
,
1466 IN UINT64 NewPe32BaseAddress
1470 Routine Description:
1472 Set new base address into the section header of PeImage
1476 FileName - Name of file
1477 FileBuffer - Pointer to PeImage.
1478 NewPe32BaseAddress - New Base Address for PE image.
1482 EFI_SUCCESS Set new base address into this image successfully.
1487 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1489 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1490 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1493 // Initialize context
1495 memset (&ImageContext
, 0, sizeof (ImageContext
));
1496 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1497 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1498 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1499 if (EFI_ERROR (Status
)) {
1500 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1504 if (ImageContext
.RelocationsStripped
) {
1505 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1510 // Get PeHeader pointer
1512 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1515 // Get section header list
1517 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1520 sizeof (EFI_IMAGE_FILE_HEADER
) +
1521 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1525 // Set base address into the first section header that doesn't point to code section.
1527 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1528 if ((SectionHeader
->Characteristics
& EFI_IMAGE_SCN_CNT_CODE
) == 0) {
1529 *(UINT64
*) &SectionHeader
->PointerToRelocations
= NewPe32BaseAddress
;
1535 // BaseAddress is set to section header.
1543 IN OUT UINT8
*FileBuffer
,
1544 IN UINT64 NewPe32BaseAddress
1548 Routine Description:
1550 Set new base address into PeImage, and fix up PeImage based on new address.
1554 FileName - Name of file
1555 FileBuffer - Pointer to PeImage.
1556 NewPe32BaseAddress - New Base Address for PE image.
1560 EFI_INVALID_PARAMETER - BaseAddress is not valid.
1561 EFI_SUCCESS - Update PeImage is correctly.
1566 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1568 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1569 UINT8
*MemoryImagePointer
;
1570 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1573 // Initialize context
1575 memset (&ImageContext
, 0, sizeof (ImageContext
));
1576 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1577 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1578 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1579 if (EFI_ERROR (Status
)) {
1580 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1584 if (ImageContext
.RelocationsStripped
) {
1585 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1590 // Get PeHeader pointer
1592 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1595 // Load and Relocate Image Data
1597 MemoryImagePointer
= (UINT8
*) malloc ((UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1598 if (MemoryImagePointer
== NULL
) {
1599 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName
);
1600 return EFI_OUT_OF_RESOURCES
;
1602 memset ((VOID
*) MemoryImagePointer
, 0, (UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1603 ImageContext
.ImageAddress
= ((UINTN
) MemoryImagePointer
+ ImageContext
.SectionAlignment
- 1) & (~((INT64
)ImageContext
.SectionAlignment
- 1));
1605 Status
= PeCoffLoaderLoadImage (&ImageContext
);
1606 if (EFI_ERROR (Status
)) {
1607 Error (NULL
, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName
);
1608 free ((VOID
*) MemoryImagePointer
);
1612 ImageContext
.DestinationAddress
= NewPe32BaseAddress
;
1613 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
1614 if (EFI_ERROR (Status
)) {
1615 Error (NULL
, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName
);
1616 free ((VOID
*) MemoryImagePointer
);
1621 // Copy Relocated data to raw image file.
1623 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1626 sizeof (EFI_IMAGE_FILE_HEADER
) +
1627 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1630 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1632 FileBuffer
+ SectionHeader
->PointerToRawData
,
1633 (VOID
*) (UINTN
) (ImageContext
.ImageAddress
+ SectionHeader
->VirtualAddress
),
1634 SectionHeader
->SizeOfRawData
1638 free ((VOID
*) MemoryImagePointer
);
1641 // Update Image Base Address
1643 if (ImgHdr
->Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1644 ImgHdr
->Pe32
.OptionalHeader
.ImageBase
= (UINT32
) NewPe32BaseAddress
;
1645 } else if (ImgHdr
->Pe32Plus
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
1646 ImgHdr
->Pe32Plus
.OptionalHeader
.ImageBase
= NewPe32BaseAddress
;
1648 Error (NULL
, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
1649 ImgHdr
->Pe32
.OptionalHeader
.Magic
,
1656 // Set new base address into section header
1658 Status
= SetAddressToSectionHeader (FileName
, FileBuffer
, NewPe32BaseAddress
);
1665 IN CHAR8
* DefaultPath
,
1666 IN CHAR8
* AppendPath
,
1670 UINT32 DefaultPathLen
;
1672 CHAR8 QuotesStr
[] = "\"";
1673 strcpy(NewPath
, QuotesStr
);
1674 DefaultPathLen
= strlen(DefaultPath
);
1675 strcat(NewPath
, DefaultPath
);
1677 for (; Index
< DefaultPathLen
+ 1; Index
++) {
1678 if (NewPath
[Index
] == '\\' || NewPath
[Index
] == '/') {
1679 if (NewPath
[Index
+ 1] != '\0') {
1680 NewPath
[Index
] = '/';
1684 if (NewPath
[Index
-1] != '/') {
1685 NewPath
[Index
] = '/';
1686 NewPath
[Index
+ 1] = '\0';
1688 strcat(NewPath
, AppendPath
);
1689 strcat(NewPath
, QuotesStr
);
1695 IN UINT8
*SectionBuffer
,
1696 IN UINT32 BufferLength
1700 Routine Description:
1706 SectionBuffer - Buffer containing the section to parse.
1707 BufferLength - Length of SectionBuffer
1711 EFI_SECTION_ERROR - Problem with section parsing.
1712 (a) compression errors
1713 (b) unrecognized section
1714 EFI_UNSUPPORTED - Do not know how to parse the section.
1715 EFI_SUCCESS - Section successfully parsed.
1716 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1720 EFI_SECTION_TYPE Type
;
1722 UINT32 SectionLength
;
1723 UINT32 SectionHeaderLen
;
1726 UINT32 ParsedLength
;
1727 UINT8
*CompressedBuffer
;
1728 UINT32 CompressedLength
;
1729 UINT8
*UncompressedBuffer
;
1730 UINT32 UncompressedLength
;
1731 UINT8
*ToolOutputBuffer
;
1732 UINT32 ToolOutputLength
;
1733 UINT8 CompressionType
;
1736 UINT8
*ScratchBuffer
;
1737 DECOMPRESS_FUNCTION DecompressFunction
;
1738 GETINFO_FUNCTION GetInfoFunction
;
1740 CHAR8
*ExtractionTool
;
1741 CHAR8
*ToolInputFile
;
1742 CHAR8
*ToolOutputFile
;
1743 CHAR8
*SystemCommand
;
1748 CHAR8
*ToolInputFileName
;
1749 CHAR8
*ToolOutputFileName
;
1751 CHAR8
*VersionString
;
1754 ToolInputFileName
= NULL
;
1755 ToolOutputFileName
= NULL
;
1757 while (ParsedLength
< BufferLength
) {
1758 Ptr
= SectionBuffer
+ ParsedLength
;
1760 SectionLength
= GetLength (((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Size
);
1761 Type
= ((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Type
;
1764 // This is sort of an odd check, but is necessary because FFS files are
1765 // padded to a QWORD boundary, meaning there is potentially a whole section
1766 // header worth of 0xFF bytes.
1768 if (SectionLength
== 0xffffff && Type
== 0xff) {
1774 // Get real section file size
1776 SectionLength
= GetSectionFileLength ((EFI_COMMON_SECTION_HEADER
*) Ptr
);
1777 SectionHeaderLen
= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
1779 SectionName
= SectionNameToStr (Type
);
1780 if (SectionName
!= NULL
) {
1781 printf ("------------------------------------------------------------\n");
1782 printf (" Type: %s\n Size: 0x%08X\n", SectionName
, (unsigned) SectionLength
);
1787 case EFI_SECTION_RAW
:
1788 case EFI_SECTION_PIC
:
1789 case EFI_SECTION_TE
:
1790 // default is no more information
1793 case EFI_SECTION_PE32
:
1795 ToolInputFileName
= "edk2Temp_InputEfi.tmp";
1796 ToolOutputFileName
= "edk2Temp_OutputHash.tmp";
1797 RebaseImage(ToolInputFileName
, (UINT8
*)Ptr
+ SectionHeaderLen
, 0);
1800 (CHAR8
*)Ptr
+ SectionHeaderLen
,
1801 SectionLength
- SectionHeaderLen
1804 SystemCommand
= malloc (
1805 strlen (OPENSSL_COMMAND_FORMAT_STRING
) +
1806 strlen (OpenSslPath
) +
1807 strlen (ToolInputFileName
) +
1808 strlen (ToolOutputFileName
) +
1811 if (SystemCommand
== NULL
) {
1812 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1813 return EFI_OUT_OF_RESOURCES
;
1817 OPENSSL_COMMAND_FORMAT_STRING
,
1823 if (system (SystemCommand
) != EFI_SUCCESS
) {
1824 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
1831 if((fp
= fopen(ToolOutputFileName
,"r")) == NULL
) {
1832 Error (NULL
, 0, 0004, "Hash the PE32 image failed.", NULL
);
1835 fseek(fp
,0,SEEK_SET
);
1836 fseek(fp
,0,SEEK_END
);
1837 nFileLen
= ftell(fp
);
1838 fseek(fp
,0,SEEK_SET
);
1839 StrLine
= malloc(nFileLen
);
1840 if (StrLine
== NULL
) {
1842 free (SystemCommand
);
1843 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1844 return EFI_OUT_OF_RESOURCES
;
1846 fgets(StrLine
, nFileLen
, fp
);
1847 NewStr
= strrchr (StrLine
, '=');
1848 printf (" SHA1: %s\n", NewStr
+ 1);
1853 remove(ToolInputFileName
);
1854 remove(ToolOutputFileName
);
1855 free (SystemCommand
);
1859 case EFI_SECTION_USER_INTERFACE
:
1860 UIFileName
= (CHAR8
*) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
) + 1);
1861 if (UIFileName
== NULL
) {
1862 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1863 return EFI_OUT_OF_RESOURCES
;
1865 Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
, UIFileName
);
1866 printf (" String: %s\n", UIFileName
);
1870 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
1871 printf ("/------------ Firmware Volume section start ---------------\\\n");
1872 Status
= PrintFvInfo (Ptr
+ SectionHeaderLen
, TRUE
);
1873 if (EFI_ERROR (Status
)) {
1874 Error (NULL
, 0, 0003, "printing of FV section contents failed", NULL
);
1875 return EFI_SECTION_ERROR
;
1877 printf ("\\------------ Firmware Volume section end -----------------/\n");
1880 case EFI_SECTION_COMPATIBILITY16
:
1882 // Section does not contain any further header information.
1886 case EFI_SECTION_FREEFORM_SUBTYPE_GUID
:
1888 if (SectionHeaderLen
== sizeof (EFI_COMMON_SECTION_HEADER
))
1889 PrintGuid (&((EFI_FREEFORM_SUBTYPE_GUID_SECTION
*)Ptr
)->SubTypeGuid
);
1891 PrintGuid (&((EFI_FREEFORM_SUBTYPE_GUID_SECTION2
*)Ptr
)->SubTypeGuid
);
1895 case EFI_SECTION_PEI_DEPEX
:
1896 case EFI_SECTION_DXE_DEPEX
:
1897 case EFI_SECTION_SMM_DEPEX
:
1898 DumpDepexSection (Ptr
, SectionLength
);
1901 case EFI_SECTION_VERSION
:
1902 printf (" Build Number: 0x%04X\n", *(UINT16
*)(Ptr
+ SectionHeaderLen
));
1903 VersionString
= (CHAR8
*) malloc (UnicodeStrLen (((EFI_VERSION_SECTION
*) Ptr
)->VersionString
) + 1);
1904 if (VersionString
== NULL
) {
1905 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1906 return EFI_OUT_OF_RESOURCES
;
1908 Unicode2AsciiString (((EFI_VERSION_SECTION
*) Ptr
)->VersionString
, VersionString
);
1909 printf (" Version String: %s\n", VersionString
);
1912 case EFI_SECTION_COMPRESSION
:
1913 UncompressedBuffer
= NULL
;
1914 if (SectionHeaderLen
== sizeof (EFI_COMMON_SECTION_HEADER
)) {
1915 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION
);
1916 UncompressedLength
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->UncompressedLength
;
1917 CompressionType
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->CompressionType
;
1919 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION2
);
1920 UncompressedLength
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->UncompressedLength
;
1921 CompressionType
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->CompressionType
;
1923 CompressedLength
= SectionLength
- RealHdrLen
;
1924 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength
);
1926 if (CompressionType
== EFI_NOT_COMPRESSED
) {
1927 printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1928 if (CompressedLength
!= UncompressedLength
) {
1933 "file is not compressed, but the compressed length does not match the uncompressed length",
1936 return EFI_SECTION_ERROR
;
1939 UncompressedBuffer
= Ptr
+ RealHdrLen
;
1940 } else if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1941 GetInfoFunction
= EfiGetInfo
;
1942 DecompressFunction
= EfiDecompress
;
1943 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
1945 CompressedBuffer
= Ptr
+ RealHdrLen
;
1947 Status
= GetInfoFunction (CompressedBuffer
, CompressedLength
, &DstSize
, &ScratchSize
);
1948 if (EFI_ERROR (Status
)) {
1949 Error (NULL
, 0, 0003, "error getting compression info from compression section", NULL
);
1950 return EFI_SECTION_ERROR
;
1953 if (DstSize
!= UncompressedLength
) {
1954 Error (NULL
, 0, 0003, "compression error in the compression section", NULL
);
1955 return EFI_SECTION_ERROR
;
1958 ScratchBuffer
= malloc (ScratchSize
);
1959 if (ScratchBuffer
== NULL
) {
1960 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1961 return EFI_OUT_OF_RESOURCES
;
1963 UncompressedBuffer
= malloc (UncompressedLength
);
1964 if (UncompressedBuffer
== NULL
) {
1965 free (ScratchBuffer
);
1966 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1967 return EFI_OUT_OF_RESOURCES
;
1969 Status
= DecompressFunction (
1977 free (ScratchBuffer
);
1978 if (EFI_ERROR (Status
)) {
1979 Error (NULL
, 0, 0003, "decompress failed", NULL
);
1980 free (UncompressedBuffer
);
1981 return EFI_SECTION_ERROR
;
1984 Error (NULL
, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType
);
1985 return EFI_SECTION_ERROR
;
1988 printf ("/------------ Encapsulation section start -----------------\\\n");
1989 Status
= ParseSection (UncompressedBuffer
, UncompressedLength
);
1990 printf ("\\------------ Encapsulation section end -------------------/\n");
1992 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1994 // We need to deallocate Buffer
1996 free (UncompressedBuffer
);
1999 if (EFI_ERROR (Status
)) {
2000 Error (NULL
, 0, 0003, "failed to parse section", NULL
);
2001 return EFI_SECTION_ERROR
;
2005 case EFI_SECTION_GUID_DEFINED
:
2006 if (SectionHeaderLen
== sizeof(EFI_COMMON_SECTION_HEADER
)) {
2007 EfiGuid
= &((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
;
2008 DataOffset
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
;
2009 Attributes
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->Attributes
;
2011 EfiGuid
= &((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->SectionDefinitionGuid
;
2012 DataOffset
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->DataOffset
;
2013 Attributes
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->Attributes
;
2015 printf (" SectionDefinitionGuid: ");
2016 PrintGuid (EfiGuid
);
2018 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset
);
2019 printf (" Attributes: 0x%04X\n", (unsigned) Attributes
);
2022 LookupGuidedSectionToolPath (
2023 mParsedGuidedSectionTools
,
2027 if (ExtractionTool
!= NULL
) {
2029 ToolInputFile
= CloneString (tmpnam (NULL
));
2030 ToolOutputFile
= CloneString (tmpnam (NULL
));
2032 char tmp1
[] = "/tmp/fileXXXXXX";
2033 char tmp2
[] = "/tmp/fileXXXXXX";
2036 fd1
= mkstemp(tmp1
);
2037 fd2
= mkstemp(tmp2
);
2038 ToolInputFile
= CloneString(tmp1
);
2039 ToolOutputFile
= CloneString(tmp2
);
2044 if ((ToolInputFile
== NULL
) || (ToolOutputFile
== NULL
)) {
2045 if (ToolInputFile
!= NULL
) {
2046 free (ToolInputFile
);
2048 if (ToolOutputFile
!= NULL
) {
2049 free (ToolOutputFile
);
2051 free (ExtractionTool
);
2053 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
2054 return EFI_OUT_OF_RESOURCES
;
2058 // Construction 'system' command string
2060 SystemCommand
= malloc (
2061 strlen (EXTRACT_COMMAND_FORMAT_STRING
) +
2062 strlen (ExtractionTool
) +
2063 strlen (ToolInputFile
) +
2064 strlen (ToolOutputFile
) +
2067 if (SystemCommand
== NULL
) {
2068 free (ToolInputFile
);
2069 free (ToolOutputFile
);
2070 free (ExtractionTool
);
2072 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
2073 return EFI_OUT_OF_RESOURCES
;
2077 EXTRACT_COMMAND_FORMAT_STRING
,
2082 free (ExtractionTool
);
2086 &gEfiCrc32GuidedSectionExtractionProtocolGuid
2094 (CHAR8
*)Ptr
+ DataOffset
,
2095 SectionLength
- DataOffset
2098 system (SystemCommand
);
2099 remove (ToolInputFile
);
2100 free (ToolInputFile
);
2105 (CHAR8
**)&ToolOutputBuffer
,
2108 remove (ToolOutputFile
);
2109 free (ToolOutputFile
);
2110 free (SystemCommand
);
2111 if (EFI_ERROR (Status
)) {
2112 Error (NULL
, 0, 0004, "unable to read decoded GUIDED section", NULL
);
2113 return EFI_SECTION_ERROR
;
2116 printf ("/------------ Encapsulation section start -----------------\\\n");
2117 Status
= ParseSection (
2121 if (EFI_ERROR (Status
)) {
2122 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
2123 return EFI_SECTION_ERROR
;
2125 printf ("\\------------ Encapsulation section end -------------------/\n");
2128 // Check for CRC32 sections which we can handle internally if needed.
2130 } else if (!CompareGuid (
2132 &gEfiCrc32GuidedSectionExtractionProtocolGuid
2136 // CRC32 guided section
2138 printf ("/------------ Encapsulation section start -----------------\\\n");
2139 Status
= ParseSection (
2141 SectionLength
- DataOffset
2143 if (EFI_ERROR (Status
)) {
2144 Error (NULL
, 0, 0003, "parse of CRC32 GUIDED section failed", NULL
);
2145 return EFI_SECTION_ERROR
;
2147 printf ("\\------------ Encapsulation section end -------------------/\n");
2150 // We don't know how to parse it now.
2152 Error (NULL
, 0, 0003, "Error parsing section", \
2153 "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).");
2154 return EFI_UNSUPPORTED
;
2160 // Unknown section, return error
2162 Error (NULL
, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type
);
2163 return EFI_SECTION_ERROR
;
2166 ParsedLength
+= SectionLength
;
2168 // We make then next section begin on a 4-byte boundary
2170 ParsedLength
= GetOccupiedSize (ParsedLength
, 4);
2173 if (ParsedLength
< BufferLength
) {
2174 Error (NULL
, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL
);
2175 return EFI_SECTION_ERROR
;
2184 IN UINT32 SectionLength
2188 Routine Description:
2190 GC_TODO: Add function description
2194 Ptr - GC_TODO: add argument description
2195 SectionLength - GC_TODO: add argument description
2199 EFI_SUCCESS - GC_TODO: Add description for return value
2203 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
2206 // Need at least a section header + data
2208 if (SectionLength
<= sizeof (EFI_COMMON_SECTION_HEADER
)) {
2212 Ptr
+= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2213 SectionLength
-= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2214 while (SectionLength
> 0) {
2217 case EFI_DEP_BEFORE
:
2218 printf ("BEFORE\n");
2231 PrintGuidToBuffer ((EFI_GUID
*) (Ptr
+ 1), GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
2232 printf ("%s ", GuidBuffer
);
2233 PrintGuidName (GuidBuffer
);
2236 // PrintGuid ((EFI_GUID *)(Ptr + 1));
2239 SectionLength
-= 17;
2273 printf ("END DEPEX\n");
2285 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr
);
2299 Routine Description:
2301 GC_TODO: Add function description
2305 GuidStr - GC_TODO: add argument description
2309 EFI_SUCCESS - GC_TODO: Add description for return value
2310 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
2314 GUID_TO_BASENAME
*GPtr
;
2316 // If we have a list of guid-to-basenames, then go through the list to
2317 // look for a guid string match. If found, print the basename to stdout,
2318 // otherwise return a failure.
2320 GPtr
= mGuidBaseNameList
;
2321 while (GPtr
!= NULL
) {
2322 if (_stricmp ((CHAR8
*) GuidStr
, (CHAR8
*) GPtr
->Guid
) == 0) {
2323 printf ("%s", GPtr
->BaseName
);
2330 return EFI_INVALID_PARAMETER
;
2334 ParseGuidBaseNameFile (
2339 Routine Description:
2341 GC_TODO: Add function description
2345 FileName - GC_TODO: add argument description
2349 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
2350 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
2351 EFI_SUCCESS - GC_TODO: Add description for return value
2356 CHAR8 Line
[MAX_LINE_LEN
];
2357 CHAR8 FormatString
[MAX_LINE_LEN
];
2358 GUID_TO_BASENAME
*GPtr
;
2360 if ((Fptr
= fopen (LongFilePath (FileName
), "r")) == NULL
) {
2361 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName
);
2362 return EFI_DEVICE_ERROR
;
2366 // Generate the format string for fscanf
2371 (unsigned) sizeof (GPtr
->Guid
) - 1,
2372 (unsigned) sizeof (GPtr
->BaseName
) - 1
2375 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
2377 // Allocate space for another guid/basename element
2379 GPtr
= malloc (sizeof (GUID_TO_BASENAME
));
2382 return EFI_OUT_OF_RESOURCES
;
2385 memset ((char *) GPtr
, 0, sizeof (GUID_TO_BASENAME
));
2386 if (sscanf (Line
, FormatString
, GPtr
->Guid
, GPtr
->BaseName
) == 2) {
2387 GPtr
->Next
= mGuidBaseNameList
;
2388 mGuidBaseNameList
= GPtr
;
2391 // Some sort of error. Just continue.
2402 FreeGuidBaseNameList (
2407 Routine Description:
2409 GC_TODO: Add function description
2417 EFI_SUCCESS - GC_TODO: Add description for return value
2421 GUID_TO_BASENAME
*Next
;
2423 while (mGuidBaseNameList
!= NULL
) {
2424 Next
= mGuidBaseNameList
->Next
;
2425 free (mGuidBaseNameList
);
2426 mGuidBaseNameList
= Next
;
2435 LoadGuidedSectionToolsTxt (
2436 IN CHAR8
* FirmwareVolumeFilename
2439 CHAR8
* PeerFilename
;
2446 Places
[0] = FirmwareVolumeFilename
;
2447 //Places[1] = mUtilityFilename;
2449 mParsedGuidedSectionTools
= NULL
;
2451 for (Index
= 0; Index
< (sizeof(Places
)/sizeof(Places
[0])); Index
++) {
2452 PeerFilename
= OsPathPeerFilePath (Places
[Index
], "GuidedSectionTools.txt");
2453 //printf("Loading %s...\n", PeerFilename);
2454 if (OsPathExists (PeerFilename
)) {
2455 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (PeerFilename
);
2457 free (PeerFilename
);
2458 if (mParsedGuidedSectionTools
!= NULL
) {
2471 Routine Description:
2473 GC_TODO: Add function description
2481 GC_TODO: add return values
2488 fprintf (stdout
, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME
);
2491 // Copyright declaration
2493 fprintf (stdout
, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
2494 fprintf (stdout
, " Display Tiano Firmware Volume FFS image information\n\n");
2499 fprintf (stdout
, "optional arguments:\n");
2500 fprintf (stdout
, " -h, --help\n\
2501 Show this help message and exit\n");
2502 fprintf (stdout
, " --version\n\
2503 Show program's version number and exit\n");
2504 fprintf (stdout
, " -d [DEBUG], --debug [DEBUG]\n\
2505 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
2506 fprintf (stdout
, " -v, --verbose\n\
2507 Print informational statements\n");
2508 fprintf (stdout
, " -q, --quiet\n\
2509 Returns the exit code, error messages will be displayed\n");
2510 fprintf (stdout
, " -s, --silent\n\
2511 Returns only the exit code; informational and error\n\
2512 messages are not displayed\n");
2513 fprintf (stdout
, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
2514 Parse the basename to file-guid cross reference file(s)\n");
2515 fprintf (stdout
, " -f OFFSET, --offset OFFSET\n\
2516 The offset from the start of the input file to start \n\
2517 processing an FV\n");
2518 fprintf (stdout
, " --hash\n\
2519 Generate HASH value of the entire PE image\n");
2520 fprintf (stdout
, " --sfo\n\
2521 Reserved for future use\n");