2 The tool dumps the contents of a firmware volume
4 Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 #include <Common/UefiBaseTypes.h>
28 #include <Common/UefiCapsule.h>
29 #include <Common/PiFirmwareFile.h>
30 #include <Common/PiFirmwareVolume.h>
31 #include <Guid/PiFirmwareFileSystem.h>
32 #include <IndustryStandard/PeImage.h>
33 #include <Protocol/GuidedSectionExtraction.h>
36 #include "Decompress.h"
38 #include "CommonLib.h"
39 #include "EfiUtilityMsgs.h"
40 #include "FirmwareVolumeBufferLib.h"
42 #include "ParseGuidedSectionTools.h"
43 #include "StringFuncs.h"
45 #include "PeCoffLib.h"
48 // Utility global variables
51 EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
53 #define UTILITY_MAJOR_VERSION 1
54 #define UTILITY_MINOR_VERSION 0
56 #define UTILITY_NAME "VolInfo"
58 #define EFI_SECTION_ERROR EFIERR (100)
60 #define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable
63 // Structure to keep a list of guid-to-basenames
65 typedef struct _GUID_TO_BASENAME
{
66 struct _GUID_TO_BASENAME
*Next
;
67 INT8 Guid
[PRINTED_GUID_BUFFER_SIZE
];
68 INT8 BaseName
[MAX_BASENAME_LEN
];
71 static GUID_TO_BASENAME
*mGuidBaseNameList
= NULL
;
74 // Store GUIDed Section guid->tool mapping
76 EFI_HANDLE mParsedGuidedSectionTools
= NULL
;
78 CHAR8
* mUtilityFilename
= NULL
;
80 BOOLEAN EnableHash
= FALSE
;
81 CHAR8
*OpenSslPath
= NULL
;
84 ParseGuidBaseNameFile (
89 FreeGuidBaseNameList (
100 IN UINT8
*SectionBuffer
,
101 IN UINT32 BufferLength
107 IN UINT32 SectionLength
115 OUT BOOLEAN
*ErasePolarity
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
,
160 GC_TODO: Add function description
164 argc - GC_TODO: add argument description
165 ] - GC_TODO: add argument description
169 GC_TODO: add return values
175 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
;
179 BOOLEAN ErasePolarity
;
182 CHAR8
*OpenSslCommand
;
184 SetUtilityName (UTILITY_NAME
);
186 // Print utility header
188 printf ("%s Version %d.%d Build %s\n",
190 UTILITY_MAJOR_VERSION
,
191 UTILITY_MINOR_VERSION
,
206 // Look for help options
208 if ((strcmp(argv
[0], "-h") == 0) || (strcmp(argv
[0], "--help") == 0) ||
209 (strcmp(argv
[0], "-?") == 0) || (strcmp(argv
[0], "/?") == 0)) {
211 return STATUS_SUCCESS
;
214 // Version has already be printed, so just return success
216 if (strcmp(argv
[0], "--version") == 0) {
217 return STATUS_SUCCESS
;
221 // If they specified -x xref guid/basename cross-reference files, process it.
222 // This will print the basename beside each file guid. To use it, specify
223 // -x xref_filename to processdsc, then use xref_filename as a parameter
227 if ((strcmp(argv
[0], "-x") == 0) || (strcmp(argv
[0], "--xref") == 0)) {
228 ParseGuidBaseNameFile (argv
[1]);
229 printf("ParseGuidBaseNameFile: %s\n", argv
[1]);
234 if (strcmp(argv
[0], "--offset") == 0) {
238 if ((argv
[1][0] == '0') && (tolower ((int)argv
[1][1]) == 'x')) {
239 if (sscanf (argv
[1], "%x", &Offset
) != 1) {
240 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
241 return GetUtilityStatus ();
244 if (sscanf (argv
[1], "%d", &Offset
) != 1) {
245 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
246 return GetUtilityStatus ();
249 // See if they said something like "64K"
251 if (tolower ((int)argv
[1][strlen (argv
[1]) - 1]) == 'k') {
260 if ((stricmp (argv
[0], "--hash") == 0)) {
262 OpenSslCommand
= "openssl";
263 OpenSslEnv
= getenv("OPENSSL_PATH");
264 if (OpenSslEnv
== NULL
) {
265 OpenSslPath
= OpenSslCommand
;
267 OpenSslPath
= malloc(strlen(OpenSslEnv
)+strlen(OpenSslCommand
)+1);
268 CombinePath(OpenSslEnv
, OpenSslCommand
, OpenSslPath
);
270 if (OpenSslPath
== NULL
){
271 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
272 return GetUtilityStatus ();
279 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
280 SetPrintLevel (VERBOSE_LOG_LEVEL
);
286 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
287 SetPrintLevel (KEY_LOG_LEVEL
);
293 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
294 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
295 if (EFI_ERROR (Status
)) {
296 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
300 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel
);
303 SetPrintLevel (LogLevel
);
304 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
310 mUtilityFilename
= argv
[0];
316 // Open the file containing the FV
318 if (mUtilityFilename
== NULL
) {
319 Error (NULL
, 0, 1001, "Missing option", "Input files are not specified");
320 return GetUtilityStatus ();
322 InputFile
= fopen (LongFilePath (mUtilityFilename
), "rb");
323 if (InputFile
== NULL
) {
324 Error (NULL
, 0, 0001, "Error opening the input file", mUtilityFilename
);
325 return GetUtilityStatus ();
328 // Skip over pad bytes if specified. This is used if they prepend 0xff
329 // data to the FV image binary.
332 fseek (InputFile
, Offset
, SEEK_SET
);
335 // Determine size of FV
337 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
338 if (EFI_ERROR (Status
)) {
339 Error (NULL
, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename
);
341 return GetUtilityStatus ();
344 // Allocate a buffer for the FV image
346 FvImage
= malloc (FvSize
);
347 if (FvImage
== NULL
) {
348 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
350 return GetUtilityStatus ();
353 // Seek to the start of the image, then read the entire FV to the buffer
355 fseek (InputFile
, Offset
, SEEK_SET
);
356 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
358 if ((unsigned int) BytesRead
!= FvSize
) {
359 Error (NULL
, 0, 0004, "error reading FvImage from", mUtilityFilename
);
361 return GetUtilityStatus ();
364 LoadGuidedSectionToolsTxt (mUtilityFilename
);
366 PrintFvInfo (FvImage
, FALSE
);
372 FreeGuidBaseNameList ();
373 return GetUtilityStatus ();
387 GC_TODO: Add function description
391 Fv - Firmware Volume to print information about
392 IsChildFv - Flag specifies whether the input FV is a child FV.
402 BOOLEAN ErasePolarity
;
404 EFI_FFS_FILE_HEADER
*CurrentFile
;
407 Status
= FvBufGetSize (Fv
, &FvSize
);
411 (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) ?
415 // Get the first file
418 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
419 if (EFI_ERROR (Status
)) {
420 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
421 return GetUtilityStatus ();
424 // Display information about files found
426 while (CurrentFile
!= NULL
) {
428 // Increment the number of files counter
433 // Display info about this file
435 Status
= PrintFileInfo (Fv
, CurrentFile
, ErasePolarity
);
436 if (EFI_ERROR (Status
)) {
437 Error (NULL
, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
438 return GetUtilityStatus ();
443 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
444 if (Status
== EFI_NOT_FOUND
) {
446 } else if (EFI_ERROR (Status
)) {
447 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
448 return GetUtilityStatus ();
453 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles
);
455 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles
);
463 IN UINT32 ActualSize
,
470 This function returns the next larger size that meets the alignment
471 requirement specified.
476 Alignment The desired alignment.
480 EFI_SUCCESS Function completed successfully.
481 EFI_ABORTED The function encountered an error.
487 OccupiedSize
= ActualSize
;
488 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
498 IN EFI_SECTION_TYPE Type
504 Converts EFI Section names to Strings
508 Type - The EFI Section type
512 CHAR8* - Pointer to the String containing the section name.
517 CHAR8
*SectionTypeStringTable
[] = {
525 "EFI_SECTION_COMPRESSION",
529 "EFI_SECTION_GUID_DEFINED",
533 "Unknown section type - Reserved 0x03",
537 "Unknown section type - Reserved 0x04",
541 "Unknown section type - Reserved 0x05",
545 "Unknown section type - Reserved 0x06",
549 "Unknown section type - Reserved 0x07",
553 "Unknown section type - Reserved 0x08",
557 "Unknown section type - Reserved 0x09",
561 "Unknown section type - Reserved 0x0A",
565 "Unknown section type - Reserved 0x0B",
569 "Unknown section type - Reserved 0x0C",
573 "Unknown section type - Reserved 0x0D",
577 "Unknown section type - Reserved 0x0E",
581 "Unknown section type - Reserved 0x0E",
597 "EFI_SECTION_DXE_DEPEX",
601 "EFI_SECTION_VERSION",
605 "EFI_SECTION_USER_INTERFACE",
609 "EFI_SECTION_COMPATIBILITY16",
613 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
617 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
625 "Unknown section type - 0x1A",
629 "EFI_SECTION_PEI_DEPEX",
633 "EFI_SECTION_SMM_DEPEX",
637 "Unknown section type - Reserved - beyond last defined section"
640 if (Type
> EFI_SECTION_LAST_SECTION_TYPE
) {
641 Type
= EFI_SECTION_LAST_SECTION_TYPE
+ 1;
644 SectionStr
= malloc (100);
645 if (SectionStr
== NULL
) {
646 printf ("Error: Out of memory resources.\n");
649 strcpy (SectionStr
, SectionTypeStringTable
[Type
]);
658 OUT BOOLEAN
*ErasePolarity
664 This function determines the size of the FV and the erase polarity. The
665 erase polarity is the FALSE value for file state.
669 InputFile The file that contains the FV image.
670 FvSize The size of the FV.
671 ErasePolarity The FV erase polarity.
675 EFI_SUCCESS Function completed successfully.
676 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
677 EFI_ABORTED The function encountered an error.
681 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
682 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
690 // Check input parameters
692 if (InputFile
== NULL
|| FvSize
== NULL
|| ErasePolarity
== NULL
) {
693 Error (__FILE__
, __LINE__
, 0, "application error", "invalid parameter to function");
694 return EFI_INVALID_PARAMETER
;
699 fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
700 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
701 Signature
[0] = VolumeHeader
.Signature
;
705 // Print FV header information
707 printf ("Signature: %s (%X)\n", (char *) Signature
, (unsigned) VolumeHeader
.Signature
);
708 printf ("Attributes: %X\n", (unsigned) VolumeHeader
.Attributes
);
710 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_DISABLED_CAP
) {
711 printf (" EFI_FVB2_READ_DISABLED_CAP\n");
714 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_ENABLED_CAP
) {
715 printf (" EFI_FVB2_READ_ENABLED_CAP\n");
718 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_STATUS
) {
719 printf (" EFI_FVB2_READ_STATUS\n");
722 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_DISABLED_CAP
) {
723 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
726 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_ENABLED_CAP
) {
727 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
730 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_STATUS
) {
731 printf (" EFI_FVB2_WRITE_STATUS\n");
734 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_CAP
) {
735 printf (" EFI_FVB2_LOCK_CAP\n");
738 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_STATUS
) {
739 printf (" EFI_FVB2_LOCK_STATUS\n");
742 if (VolumeHeader
.Attributes
& EFI_FVB2_STICKY_WRITE
) {
743 printf (" EFI_FVB2_STICKY_WRITE\n");
746 if (VolumeHeader
.Attributes
& EFI_FVB2_MEMORY_MAPPED
) {
747 printf (" EFI_FVB2_MEMORY_MAPPED\n");
750 if (VolumeHeader
.Attributes
& EFI_FVB2_ERASE_POLARITY
) {
751 printf (" EFI_FVB2_ERASE_POLARITY\n");
752 *ErasePolarity
= TRUE
;
755 #if (PI_SPECIFICATION_VERSION < 0x00010000)
756 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
757 printf (" EFI_FVB2_ALIGNMENT\n");
760 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
761 printf (" EFI_FVB2_ALIGNMENT_2\n");
764 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
765 printf (" EFI_FVB2_ALIGNMENT_4\n");
768 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
769 printf (" EFI_FVB2_ALIGNMENT_8\n");
772 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
773 printf (" EFI_FVB2_ALIGNMENT_16\n");
776 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
777 printf (" EFI_FVB2_ALIGNMENT_32\n");
780 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
781 printf (" EFI_FVB2_ALIGNMENT_64\n");
784 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
785 printf (" EFI_FVB2_ALIGNMENT_128\n");
788 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
789 printf (" EFI_FVB2_ALIGNMENT_256\n");
792 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
793 printf (" EFI_FVB2_ALIGNMENT_512\n");
796 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
797 printf (" EFI_FVB2_ALIGNMENT_1K\n");
800 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
801 printf (" EFI_FVB2_ALIGNMENT_2K\n");
804 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
805 printf (" EFI_FVB2_ALIGNMENT_4K\n");
808 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
809 printf (" EFI_FVB2_ALIGNMENT_8K\n");
812 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
813 printf (" EFI_FVB2_ALIGNMENT_16K\n");
816 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
817 printf (" EFI_FVB2_ALIGNMENT_32K\n");
820 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
821 printf (" EFI_FVB2_ALIGNMENT_64K\n");
826 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_CAP
) {
827 printf (" EFI_FVB2_READ_LOCK_CAP\n");
830 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_STATUS
) {
831 printf (" EFI_FVB2_READ_LOCK_STATUS\n");
834 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_CAP
) {
835 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
838 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_STATUS
) {
839 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
842 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1
) {
843 printf (" EFI_FVB2_ALIGNMENT_1\n");
846 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
847 printf (" EFI_FVB2_ALIGNMENT_2\n");
850 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
851 printf (" EFI_FVB2_ALIGNMENT_4\n");
854 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
855 printf (" EFI_FVB2_ALIGNMENT_8\n");
858 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
859 printf (" EFI_FVB2_ALIGNMENT_16\n");
862 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
863 printf (" EFI_FVB2_ALIGNMENT_32\n");
866 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
867 printf (" EFI_FVB2_ALIGNMENT_64\n");
870 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
871 printf (" EFI_FVB2_ALIGNMENT_128\n");
874 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
875 printf (" EFI_FVB2_ALIGNMENT_256\n");
878 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
879 printf (" EFI_FVB2_ALIGNMENT_512\n");
882 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
883 printf (" EFI_FVB2_ALIGNMENT_1K\n");
886 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
887 printf (" EFI_FVB2_ALIGNMENT_2K\n");
890 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
891 printf (" EFI_FVB2_ALIGNMENT_4K\n");
894 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
895 printf (" EFI_FVB2_ALIGNMENT_8K\n");
898 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
899 printf (" EFI_FVB2_ALIGNMENT_16K\n");
902 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
903 printf (" EFI_FVB2_ALIGNMENT_32K\n");
906 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
907 printf (" EFI_FVB2_ALIGNMENT_64K\n");
910 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128K
) {
911 printf (" EFI_FVB2_ALIGNMENT_128K\n");
914 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256K
) {
915 printf (" EFI_FVB2_ALIGNMENT_256K\n");
918 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512K
) {
919 printf (" EFI_FVB2_ALIGNMENT_512K\n");
922 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1M
) {
923 printf (" EFI_FVB2_ALIGNMENT_1M\n");
926 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2M
) {
927 printf (" EFI_FVB2_ALIGNMENT_2M\n");
930 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4M
) {
931 printf (" EFI_FVB2_ALIGNMENT_4M\n");
934 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8M
) {
935 printf (" EFI_FVB2_ALIGNMENT_8M\n");
938 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16M
) {
939 printf (" EFI_FVB2_ALIGNMENT_16M\n");
942 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32M
) {
943 printf (" EFI_FVB2_ALIGNMENT_32M\n");
946 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
947 printf (" EFI_FVB2_ALIGNMENT_64M\n");
950 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
951 printf (" EFI_FVB2_ALIGNMENT_128M\n");
954 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
955 printf (" EFI_FVB2_ALIGNMENT_64M\n");
958 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
959 printf (" EFI_FVB2_ALIGNMENT_128M\n");
962 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256M
) {
963 printf (" EFI_FVB2_ALIGNMENT_256M\n");
966 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512M
) {
967 printf (" EFI_FVB2_ALIGNMENT_512M\n");
970 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1G
) {
971 printf (" EFI_FVB2_ALIGNMENT_1G\n");
974 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2G
) {
975 printf (" EFI_FVB2_ALIGNMENT_2G\n");
979 printf ("Header Length: 0x%08X\n", VolumeHeader
.HeaderLength
);
980 printf ("File System ID: ");
981 PrintGuid (&VolumeHeader
.FileSystemGuid
);
985 printf ("Revision: 0x%04X\n", VolumeHeader
.Revision
);
988 fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
989 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
991 if (BlockMap
.NumBlocks
!= 0) {
992 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap
.NumBlocks
);
993 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap
.Length
);
994 Size
+= BlockMap
.NumBlocks
* BlockMap
.Length
;
997 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.Length
== 0));
999 if (BytesRead
!= VolumeHeader
.HeaderLength
) {
1000 printf ("ERROR: Header length not consistent with Block Maps!\n");
1004 if (VolumeHeader
.FvLength
!= Size
) {
1005 printf ("ERROR: Volume Size not consistant with Block Maps!\n");
1009 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size
);
1014 // rewind (InputFile);
1022 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
1023 EFI_FFS_FILE_HEADER
*FileHeader
,
1024 BOOLEAN ErasePolarity
1028 Routine Description:
1030 GC_TODO: Add function description
1034 FvImage - GC_TODO: add argument description
1035 FileHeader - GC_TODO: add argument description
1036 ErasePolarity - GC_TODO: add argument description
1040 EFI_SUCCESS - GC_TODO: Add description for return value
1041 EFI_ABORTED - GC_TODO: Add description for return value
1048 EFI_FFS_FILE_HEADER2 BlankHeader
;
1050 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1052 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1056 // Check if we have free space
1058 HeaderSize
= FvBufGetFfsHeaderSize(FileHeader
);
1059 if (ErasePolarity
) {
1060 memset (&BlankHeader
, -1, HeaderSize
);
1062 memset (&BlankHeader
, 0, HeaderSize
);
1065 if (memcmp (&BlankHeader
, FileHeader
, HeaderSize
) == 0) {
1069 // Print file information.
1071 printf ("============================================================\n");
1073 printf ("File Name: ");
1074 PrintGuidToBuffer (&FileHeader
->Name
, GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
1075 printf ("%s ", GuidBuffer
);
1076 PrintGuidName (GuidBuffer
);
1080 // PrintGuid (&FileHeader->Name);
1083 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1084 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN
) FileHeader
- (UINTN
) FvImage
));
1085 printf ("File Length: 0x%08X\n", (unsigned) FileLength
);
1086 printf ("File Attributes: 0x%02X\n", FileHeader
->Attributes
);
1087 printf ("File State: 0x%02X\n", FileHeader
->State
);
1092 FileState
= GetFileState (ErasePolarity
, FileHeader
);
1094 switch (FileState
) {
1096 case EFI_FILE_HEADER_CONSTRUCTION
:
1097 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
1100 case EFI_FILE_HEADER_INVALID
:
1101 printf (" EFI_FILE_HEADER_INVALID\n");
1104 case EFI_FILE_HEADER_VALID
:
1105 printf (" EFI_FILE_HEADER_VALID\n");
1106 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1107 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1108 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1109 if (Checksum
!= 0) {
1110 printf ("ERROR: Header checksum invalid.\n");
1116 case EFI_FILE_DELETED
:
1117 printf (" EFI_FILE_DELETED\n");
1119 case EFI_FILE_MARKED_FOR_UPDATE
:
1120 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
1122 case EFI_FILE_DATA_VALID
:
1123 printf (" EFI_FILE_DATA_VALID\n");
1126 // Calculate header checksum
1128 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1129 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1130 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1131 if (Checksum
!= 0) {
1132 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer
);
1136 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1138 if (FileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
1140 // Calculate file checksum
1142 Checksum
= CalculateSum8 ((UINT8
*)FileHeader
+ HeaderSize
, FileLength
- HeaderSize
);
1143 Checksum
= Checksum
+ FileHeader
->IntegrityCheck
.Checksum
.File
;
1144 if (Checksum
!= 0) {
1145 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer
);
1149 if (FileHeader
->IntegrityCheck
.Checksum
.File
!= FFS_FIXED_CHECKSUM
) {
1150 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
);
1154 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1156 // Verify tail if present
1158 if (FileHeader
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
1160 // Verify tail is complement of integrity check field in the header.
1162 Tail
= (UINT16
*) ((UINTN
) FileHeader
+ GetLength (FileHeader
->Size
) - sizeof (EFI_FFS_INTEGRITY_CHECK
));
1163 if (FileHeader
->IntegrityCheck
.TailReference
!= (UINT16
)~(*Tail
)) {
1164 Error (NULL
, 0, 0003, "error parsing FFS file", \
1165 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer
);
1173 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer
);
1177 printf ("File Type: 0x%02X ", FileHeader
->Type
);
1179 switch (FileHeader
->Type
) {
1181 case EFI_FV_FILETYPE_RAW
:
1182 printf ("EFI_FV_FILETYPE_RAW\n");
1185 case EFI_FV_FILETYPE_FREEFORM
:
1186 printf ("EFI_FV_FILETYPE_FREEFORM\n");
1189 case EFI_FV_FILETYPE_SECURITY_CORE
:
1190 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
1193 case EFI_FV_FILETYPE_PEI_CORE
:
1194 printf ("EFI_FV_FILETYPE_PEI_CORE\n");
1197 case EFI_FV_FILETYPE_DXE_CORE
:
1198 printf ("EFI_FV_FILETYPE_DXE_CORE\n");
1201 case EFI_FV_FILETYPE_PEIM
:
1202 printf ("EFI_FV_FILETYPE_PEIM\n");
1205 case EFI_FV_FILETYPE_DRIVER
:
1206 printf ("EFI_FV_FILETYPE_DRIVER\n");
1209 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
1210 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
1213 case EFI_FV_FILETYPE_APPLICATION
:
1214 printf ("EFI_FV_FILETYPE_APPLICATION\n");
1217 case EFI_FV_FILETYPE_SMM
:
1218 printf ("EFI_FV_FILETYPE_SMM\n");
1221 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
:
1222 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1225 case EFI_FV_FILETYPE_COMBINED_SMM_DXE
:
1226 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
1229 case EFI_FV_FILETYPE_SMM_CORE
:
1230 printf ("EFI_FV_FILETYPE_SMM_CORE\n");
1233 case EFI_FV_FILETYPE_FFS_PAD
:
1234 printf ("EFI_FV_FILETYPE_FFS_PAD\n");
1238 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader
->Type
);
1243 switch (FileHeader
->Type
) {
1245 case EFI_FV_FILETYPE_ALL
:
1246 case EFI_FV_FILETYPE_RAW
:
1247 case EFI_FV_FILETYPE_FFS_PAD
:
1252 // All other files have sections
1254 Status
= ParseSection (
1255 (UINT8
*) ((UINTN
) FileHeader
+ HeaderSize
),
1256 FvBufGetFfsFileSize (FileHeader
) - HeaderSize
1258 if (EFI_ERROR (Status
)) {
1260 // printf ("ERROR: Parsing the FFS file.\n");
1272 IN VOID
*FileHandle
,
1273 IN UINTN FileOffset
,
1274 IN OUT UINT32
*ReadSize
,
1279 Routine Description:
1281 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
1285 FileHandle - The handle to the PE/COFF file
1287 FileOffset - The offset, in bytes, into the file to read
1289 ReadSize - The number of bytes to read from the file starting at FileOffset
1291 Buffer - A pointer to the buffer to read the data into.
1295 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1299 CHAR8
*Destination8
;
1303 Destination8
= Buffer
;
1304 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
1307 *(Destination8
++) = *(Source8
++);
1314 SetAddressToSectionHeader (
1316 IN OUT UINT8
*FileBuffer
,
1317 IN UINT64 NewPe32BaseAddress
1321 Routine Description:
1323 Set new base address into the section header of PeImage
1327 FileName - Name of file
1328 FileBuffer - Pointer to PeImage.
1329 NewPe32BaseAddress - New Base Address for PE image.
1333 EFI_SUCCESS Set new base address into this image successfully.
1338 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1340 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1341 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1344 // Initialize context
1346 memset (&ImageContext
, 0, sizeof (ImageContext
));
1347 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1348 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1349 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1350 if (EFI_ERROR (Status
)) {
1351 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1355 if (ImageContext
.RelocationsStripped
) {
1356 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1361 // Get PeHeader pointer
1363 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1366 // Get section header list
1368 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1371 sizeof (EFI_IMAGE_FILE_HEADER
) +
1372 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1376 // Set base address into the first section header that doesn't point to code section.
1378 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1379 if ((SectionHeader
->Characteristics
& EFI_IMAGE_SCN_CNT_CODE
) == 0) {
1380 *(UINT64
*) &SectionHeader
->PointerToRelocations
= NewPe32BaseAddress
;
1386 // BaseAddress is set to section header.
1394 IN OUT UINT8
*FileBuffer
,
1395 IN UINT64 NewPe32BaseAddress
1399 Routine Description:
1401 Set new base address into PeImage, and fix up PeImage based on new address.
1405 FileName - Name of file
1406 FileBuffer - Pointer to PeImage.
1407 NewPe32BaseAddress - New Base Address for PE image.
1411 EFI_INVALID_PARAMETER - BaseAddress is not valid.
1412 EFI_SUCCESS - Update PeImage is correctly.
1417 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1419 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1420 UINT8
*MemoryImagePointer
;
1421 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1424 // Initialize context
1426 memset (&ImageContext
, 0, sizeof (ImageContext
));
1427 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1428 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1429 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1430 if (EFI_ERROR (Status
)) {
1431 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1435 if (ImageContext
.RelocationsStripped
) {
1436 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1441 // Get PeHeader pointer
1443 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1446 // Load and Relocate Image Data
1448 MemoryImagePointer
= (UINT8
*) malloc ((UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1449 if (MemoryImagePointer
== NULL
) {
1450 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName
);
1451 return EFI_OUT_OF_RESOURCES
;
1453 memset ((VOID
*) MemoryImagePointer
, 0, (UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1454 ImageContext
.ImageAddress
= ((UINTN
) MemoryImagePointer
+ ImageContext
.SectionAlignment
- 1) & (~((INT64
)ImageContext
.SectionAlignment
- 1));
1456 Status
= PeCoffLoaderLoadImage (&ImageContext
);
1457 if (EFI_ERROR (Status
)) {
1458 Error (NULL
, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName
);
1459 free ((VOID
*) MemoryImagePointer
);
1463 ImageContext
.DestinationAddress
= NewPe32BaseAddress
;
1464 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
1465 if (EFI_ERROR (Status
)) {
1466 Error (NULL
, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName
);
1467 free ((VOID
*) MemoryImagePointer
);
1472 // Copy Relocated data to raw image file.
1474 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1477 sizeof (EFI_IMAGE_FILE_HEADER
) +
1478 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1481 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1483 FileBuffer
+ SectionHeader
->PointerToRawData
,
1484 (VOID
*) (UINTN
) (ImageContext
.ImageAddress
+ SectionHeader
->VirtualAddress
),
1485 SectionHeader
->SizeOfRawData
1489 free ((VOID
*) MemoryImagePointer
);
1492 // Update Image Base Address
1494 if ((ImgHdr
->Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) && (ImgHdr
->Pe32
.FileHeader
.Machine
!= IMAGE_FILE_MACHINE_IA64
)) {
1495 ImgHdr
->Pe32
.OptionalHeader
.ImageBase
= (UINT32
) NewPe32BaseAddress
;
1496 } else if (ImgHdr
->Pe32Plus
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
1497 ImgHdr
->Pe32Plus
.OptionalHeader
.ImageBase
= NewPe32BaseAddress
;
1499 Error (NULL
, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
1500 ImgHdr
->Pe32
.OptionalHeader
.Magic
,
1507 // Set new base address into section header
1509 Status
= SetAddressToSectionHeader (FileName
, FileBuffer
, NewPe32BaseAddress
);
1516 IN CHAR8
* DefaultPath
,
1517 IN CHAR8
* AppendPath
,
1521 UINT32 DefaultPathLen
;
1522 DefaultPathLen
= strlen(DefaultPath
);
1523 strcpy(NewPath
, DefaultPath
);
1525 for (; Index
< DefaultPathLen
; Index
++) {
1526 if (NewPath
[Index
] == '\\' || NewPath
[Index
] == '/') {
1527 if (NewPath
[Index
+ 1] != '\0') {
1528 NewPath
[Index
] = '/';
1532 if (NewPath
[Index
-1] != '/') {
1533 NewPath
[Index
] = '/';
1534 NewPath
[Index
+ 1] = '\0';
1536 strcat(NewPath
, AppendPath
);
1542 IN UINT8
*SectionBuffer
,
1543 IN UINT32 BufferLength
1547 Routine Description:
1553 SectionBuffer - Buffer containing the section to parse.
1554 BufferLength - Length of SectionBuffer
1558 EFI_SECTION_ERROR - Problem with section parsing.
1559 (a) compression errors
1560 (b) unrecognized section
1561 EFI_UNSUPPORTED - Do not know how to parse the section.
1562 EFI_SUCCESS - Section successfully parsed.
1563 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1567 EFI_SECTION_TYPE Type
;
1569 UINT32 SectionLength
;
1570 UINT32 SectionHeaderLen
;
1573 UINT32 ParsedLength
;
1574 UINT8
*CompressedBuffer
;
1575 UINT32 CompressedLength
;
1576 UINT8
*UncompressedBuffer
;
1577 UINT32 UncompressedLength
;
1578 UINT8
*ToolOutputBuffer
;
1579 UINT32 ToolOutputLength
;
1580 UINT8 CompressionType
;
1583 UINT8
*ScratchBuffer
;
1584 DECOMPRESS_FUNCTION DecompressFunction
;
1585 GETINFO_FUNCTION GetInfoFunction
;
1587 CHAR8
*ExtractionTool
;
1588 CHAR8
*ToolInputFile
;
1589 CHAR8
*ToolOutputFile
;
1590 CHAR8
*SystemCommandFormatString
;
1591 CHAR8
*SystemCommand
;
1596 CHAR8
*ToolInputFileName
;
1597 CHAR8
*ToolOutputFileName
;
1600 ToolInputFileName
= NULL
;
1601 ToolOutputFileName
= NULL
;
1603 while (ParsedLength
< BufferLength
) {
1604 Ptr
= SectionBuffer
+ ParsedLength
;
1606 SectionLength
= GetLength (((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Size
);
1607 Type
= ((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Type
;
1610 // This is sort of an odd check, but is necessary because FFS files are
1611 // padded to a QWORD boundary, meaning there is potentially a whole section
1612 // header worth of 0xFF bytes.
1614 if (SectionLength
== 0xffffff && Type
== 0xff) {
1620 // Get real section file size
1622 SectionLength
= GetSectionFileLength ((EFI_COMMON_SECTION_HEADER
*) Ptr
);
1623 SectionHeaderLen
= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
1625 SectionName
= SectionNameToStr (Type
);
1626 printf ("------------------------------------------------------------\n");
1627 printf (" Type: %s\n Size: 0x%08X\n", SectionName
, (unsigned) SectionLength
);
1631 case EFI_SECTION_RAW
:
1632 case EFI_SECTION_PIC
:
1633 case EFI_SECTION_TE
:
1634 // default is no more information
1637 case EFI_SECTION_PE32
:
1639 ToolInputFileName
= "edk2Temp_InputEfi.tmp";
1640 ToolOutputFileName
= "edk2Temp_OutputHash.tmp";
1641 RebaseImage(ToolInputFileName
, (UINT8
*)Ptr
+ SectionHeaderLen
, 0);
1644 (CHAR8
*)Ptr
+ SectionHeaderLen
,
1645 SectionLength
- SectionHeaderLen
1648 SystemCommandFormatString
= "%s sha1 -out %s %s";
1649 SystemCommand
= malloc (
1650 strlen (SystemCommandFormatString
) +
1651 strlen (OpenSslPath
) +
1652 strlen (ToolInputFileName
) +
1653 strlen (ToolOutputFileName
) +
1658 SystemCommandFormatString
,
1664 if (system (SystemCommand
) != EFI_SUCCESS
) {
1665 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
1672 if((fp
= fopen(ToolOutputFileName
,"r")) == NULL
) {
1673 Error (NULL
, 0, 0004, "Hash the PE32 image failed.", NULL
);
1676 fseek(fp
,0,SEEK_SET
);
1677 fseek(fp
,0,SEEK_END
);
1678 nFileLen
= ftell(fp
);
1679 fseek(fp
,0,SEEK_SET
);
1680 StrLine
= malloc(nFileLen
);
1681 fgets(StrLine
, nFileLen
, fp
);
1682 NewStr
= strrchr (StrLine
, '=');
1683 printf (" SHA1: %s\n", NewStr
+ 1);
1688 remove(ToolInputFileName
);
1689 remove(ToolOutputFileName
);
1690 free (SystemCommand
);
1694 case EFI_SECTION_USER_INTERFACE
:
1695 printf (" String: %ls\n", (CHAR16
*) &((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
);
1698 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
1699 Status
= PrintFvInfo (Ptr
+ SectionHeaderLen
, TRUE
);
1700 if (EFI_ERROR (Status
)) {
1701 Error (NULL
, 0, 0003, "printing of FV section contents failed", NULL
);
1702 return EFI_SECTION_ERROR
;
1706 case EFI_SECTION_COMPATIBILITY16
:
1707 case EFI_SECTION_FREEFORM_SUBTYPE_GUID
:
1709 // Section does not contain any further header information.
1713 case EFI_SECTION_PEI_DEPEX
:
1714 case EFI_SECTION_DXE_DEPEX
:
1715 case EFI_SECTION_SMM_DEPEX
:
1716 DumpDepexSection (Ptr
, SectionLength
);
1719 case EFI_SECTION_VERSION
:
1720 printf (" Build Number: 0x%02X\n", *(UINT16
*)(Ptr
+ SectionHeaderLen
));
1721 printf (" Version Strg: %s\n", (char*) (Ptr
+ SectionHeaderLen
+ sizeof (UINT16
)));
1724 case EFI_SECTION_COMPRESSION
:
1725 UncompressedBuffer
= NULL
;
1726 if (SectionHeaderLen
== sizeof (EFI_COMMON_SECTION_HEADER
)) {
1727 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION
);
1728 UncompressedLength
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->UncompressedLength
;
1729 CompressionType
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->CompressionType
;
1731 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION2
);
1732 UncompressedLength
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->UncompressedLength
;
1733 CompressionType
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->CompressionType
;
1735 CompressedLength
= SectionLength
- RealHdrLen
;
1736 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength
);
1738 if (CompressionType
== EFI_NOT_COMPRESSED
) {
1739 printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1740 if (CompressedLength
!= UncompressedLength
) {
1745 "file is not compressed, but the compressed length does not match the uncompressed length",
1748 return EFI_SECTION_ERROR
;
1751 UncompressedBuffer
= Ptr
+ RealHdrLen
;
1752 } else if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1753 GetInfoFunction
= EfiGetInfo
;
1754 DecompressFunction
= EfiDecompress
;
1755 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
1757 CompressedBuffer
= Ptr
+ RealHdrLen
;
1759 Status
= GetInfoFunction (CompressedBuffer
, CompressedLength
, &DstSize
, &ScratchSize
);
1760 if (EFI_ERROR (Status
)) {
1761 Error (NULL
, 0, 0003, "error getting compression info from compression section", NULL
);
1762 return EFI_SECTION_ERROR
;
1765 if (DstSize
!= UncompressedLength
) {
1766 Error (NULL
, 0, 0003, "compression error in the compression section", NULL
);
1767 return EFI_SECTION_ERROR
;
1770 ScratchBuffer
= malloc (ScratchSize
);
1771 UncompressedBuffer
= malloc (UncompressedLength
);
1772 if ((ScratchBuffer
== NULL
) || (UncompressedBuffer
== NULL
)) {
1773 return EFI_OUT_OF_RESOURCES
;
1775 Status
= DecompressFunction (
1783 free (ScratchBuffer
);
1784 if (EFI_ERROR (Status
)) {
1785 Error (NULL
, 0, 0003, "decompress failed", NULL
);
1786 free (UncompressedBuffer
);
1787 return EFI_SECTION_ERROR
;
1790 Error (NULL
, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType
);
1791 return EFI_SECTION_ERROR
;
1794 Status
= ParseSection (UncompressedBuffer
, UncompressedLength
);
1796 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1798 // We need to deallocate Buffer
1800 free (UncompressedBuffer
);
1803 if (EFI_ERROR (Status
)) {
1804 Error (NULL
, 0, 0003, "failed to parse section", NULL
);
1805 return EFI_SECTION_ERROR
;
1809 case EFI_SECTION_GUID_DEFINED
:
1810 if (SectionHeaderLen
== sizeof(EFI_COMMON_SECTION_HEADER
)) {
1811 EfiGuid
= &((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
;
1812 DataOffset
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
;
1813 Attributes
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->Attributes
;
1815 EfiGuid
= &((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->SectionDefinitionGuid
;
1816 DataOffset
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->DataOffset
;
1817 Attributes
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->Attributes
;
1819 printf (" SectionDefinitionGuid: ");
1820 PrintGuid (EfiGuid
);
1822 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset
);
1823 printf (" Attributes: 0x%04X\n", (unsigned) Attributes
);
1826 LookupGuidedSectionToolPath (
1827 mParsedGuidedSectionTools
,
1831 if (ExtractionTool
!= NULL
) {
1833 ToolInputFile
= CloneString (tmpnam (NULL
));
1834 ToolOutputFile
= CloneString (tmpnam (NULL
));
1836 char tmp1
[] = "/tmp/fileXXXXXX";
1837 char tmp2
[] = "/tmp/fileXXXXXX";
1840 fd1
= mkstemp(tmp1
);
1841 fd2
= mkstemp(tmp2
);
1842 ToolInputFile
= CloneString(tmp1
);
1843 ToolOutputFile
= CloneString(tmp2
);
1849 // Construction 'system' command string
1851 SystemCommandFormatString
= "%s -d -o %s %s";
1852 SystemCommand
= malloc (
1853 strlen (SystemCommandFormatString
) +
1854 strlen (ExtractionTool
) +
1855 strlen (ToolInputFile
) +
1856 strlen (ToolOutputFile
) +
1861 SystemCommandFormatString
,
1866 free (ExtractionTool
);
1871 (CHAR8
*) SectionBuffer
+ DataOffset
,
1872 BufferLength
- DataOffset
1875 system (SystemCommand
);
1876 remove (ToolInputFile
);
1877 free (ToolInputFile
);
1882 (CHAR8
**)&ToolOutputBuffer
,
1885 remove (ToolOutputFile
);
1886 free (ToolOutputFile
);
1887 if (EFI_ERROR (Status
)) {
1888 Error (NULL
, 0, 0004, "unable to read decoded GUIDED section", NULL
);
1889 return EFI_SECTION_ERROR
;
1892 Status
= ParseSection (
1896 if (EFI_ERROR (Status
)) {
1897 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
1898 return EFI_SECTION_ERROR
;
1902 // Check for CRC32 sections which we can handle internally if needed.
1904 } else if (!CompareGuid (
1906 &gEfiCrc32GuidedSectionExtractionProtocolGuid
1910 // CRC32 guided section
1912 Status
= ParseSection (
1913 SectionBuffer
+ DataOffset
,
1914 BufferLength
- DataOffset
1916 if (EFI_ERROR (Status
)) {
1917 Error (NULL
, 0, 0003, "parse of CRC32 GUIDED section failed", NULL
);
1918 return EFI_SECTION_ERROR
;
1922 // We don't know how to parse it now.
1924 Error (NULL
, 0, 0003, "Error parsing section", \
1925 "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).");
1926 return EFI_UNSUPPORTED
;
1932 // Unknown section, return error
1934 Error (NULL
, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type
);
1935 return EFI_SECTION_ERROR
;
1938 ParsedLength
+= SectionLength
;
1940 // We make then next section begin on a 4-byte boundary
1942 ParsedLength
= GetOccupiedSize (ParsedLength
, 4);
1945 if (ParsedLength
< BufferLength
) {
1946 Error (NULL
, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL
);
1947 return EFI_SECTION_ERROR
;
1956 IN UINT32 SectionLength
1960 Routine Description:
1962 GC_TODO: Add function description
1966 Ptr - GC_TODO: add argument description
1967 SectionLength - GC_TODO: add argument description
1971 EFI_SUCCESS - GC_TODO: Add description for return value
1975 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1978 // Need at least a section header + data
1980 if (SectionLength
<= sizeof (EFI_COMMON_SECTION_HEADER
)) {
1984 Ptr
+= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
1985 SectionLength
-= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
1986 while (SectionLength
> 0) {
1989 case EFI_DEP_BEFORE
:
1990 printf ("BEFORE\n");
2003 PrintGuidToBuffer ((EFI_GUID
*) (Ptr
+ 1), GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
2004 printf ("%s ", GuidBuffer
);
2005 PrintGuidName (GuidBuffer
);
2008 // PrintGuid ((EFI_GUID *)(Ptr + 1));
2011 SectionLength
-= 17;
2045 printf ("END DEPEX\n");
2057 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr
);
2071 Routine Description:
2073 GC_TODO: Add function description
2077 GuidStr - GC_TODO: add argument description
2081 EFI_SUCCESS - GC_TODO: Add description for return value
2082 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
2086 GUID_TO_BASENAME
*GPtr
;
2088 // If we have a list of guid-to-basenames, then go through the list to
2089 // look for a guid string match. If found, print the basename to stdout,
2090 // otherwise return a failure.
2092 GPtr
= mGuidBaseNameList
;
2093 while (GPtr
!= NULL
) {
2094 if (_stricmp ((CHAR8
*) GuidStr
, (CHAR8
*) GPtr
->Guid
) == 0) {
2095 printf ("%s", GPtr
->BaseName
);
2102 return EFI_INVALID_PARAMETER
;
2106 ParseGuidBaseNameFile (
2111 Routine Description:
2113 GC_TODO: Add function description
2117 FileName - GC_TODO: add argument description
2121 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
2122 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
2123 EFI_SUCCESS - GC_TODO: Add description for return value
2128 CHAR8 Line
[MAX_LINE_LEN
];
2129 GUID_TO_BASENAME
*GPtr
;
2131 if ((Fptr
= fopen (LongFilePath (FileName
), "r")) == NULL
) {
2132 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName
);
2133 return EFI_DEVICE_ERROR
;
2136 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
2138 // Allocate space for another guid/basename element
2140 GPtr
= malloc (sizeof (GUID_TO_BASENAME
));
2142 return EFI_OUT_OF_RESOURCES
;
2145 memset ((char *) GPtr
, 0, sizeof (GUID_TO_BASENAME
));
2146 if (sscanf (Line
, "%s %s", GPtr
->Guid
, GPtr
->BaseName
) == 2) {
2147 GPtr
->Next
= mGuidBaseNameList
;
2148 mGuidBaseNameList
= GPtr
;
2151 // Some sort of error. Just continue.
2162 FreeGuidBaseNameList (
2167 Routine Description:
2169 GC_TODO: Add function description
2177 EFI_SUCCESS - GC_TODO: Add description for return value
2181 GUID_TO_BASENAME
*Next
;
2183 while (mGuidBaseNameList
!= NULL
) {
2184 Next
= mGuidBaseNameList
->Next
;
2185 free (mGuidBaseNameList
);
2186 mGuidBaseNameList
= Next
;
2195 LoadGuidedSectionToolsTxt (
2196 IN CHAR8
* FirmwareVolumeFilename
2199 CHAR8
* PeerFilename
;
2206 Places
[0] = FirmwareVolumeFilename
;
2207 //Places[1] = mUtilityFilename;
2209 mParsedGuidedSectionTools
= NULL
;
2211 for (Index
= 0; Index
< (sizeof(Places
)/sizeof(Places
[0])); Index
++) {
2212 PeerFilename
= OsPathPeerFilePath (Places
[Index
], "GuidedSectionTools.txt");
2213 //printf("Loading %s...\n", PeerFilename);
2214 if (OsPathExists (PeerFilename
)) {
2215 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (PeerFilename
);
2217 free (PeerFilename
);
2218 if (mParsedGuidedSectionTools
!= NULL
) {
2231 Routine Description:
2233 GC_TODO: Add function description
2241 GC_TODO: add return values
2248 fprintf (stdout
, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME
);
2251 // Copyright declaration
2253 fprintf (stdout
, "Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.\n\n");
2254 fprintf (stdout
, " Display Tiano Firmware Volume FFS image information\n\n");
2259 fprintf (stdout
, "optional arguments:\n");
2260 fprintf (stdout
, " -h, --help\n\
2261 Show this help message and exit\n");
2262 fprintf (stdout
, " --version\n\
2263 Show program's version number and exit\n");
2264 fprintf (stdout
, " -d [DEBUG], --debug [DEBUG]\n\
2265 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
2266 fprintf (stdout
, " -v, --verbose\n\
2267 Print informational statements\n");
2268 fprintf (stdout
, " -q, --quiet\n\
2269 Returns the exit code, error messages will be displayed\n");
2270 fprintf (stdout
, " -s, --silent\n\
2271 Returns only the exit code; informational and error\n\
2272 messages are not displayed\n");
2273 fprintf (stdout
, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
2274 Parse the basename to file-guid cross reference file(s)\n");
2275 fprintf (stdout
, " -f OFFSET, --offset OFFSET\n\
2276 The offset from the start of the input file to start \n\
2277 processing an FV\n");
2278 fprintf (stdout
, " --hash\n\
2279 Generate HASH value of the entire PE image\n");
2280 fprintf (stdout
, " --sfo\n\
2281 Reserved for future use\n");