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 if (OpenSslPath
== NULL
) {
269 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
270 return GetUtilityStatus ();
272 CombinePath(OpenSslEnv
, OpenSslCommand
, OpenSslPath
);
274 if (OpenSslPath
== NULL
){
275 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
276 return GetUtilityStatus ();
283 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
284 SetPrintLevel (VERBOSE_LOG_LEVEL
);
290 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
291 SetPrintLevel (KEY_LOG_LEVEL
);
297 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
298 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
299 if (EFI_ERROR (Status
)) {
300 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
304 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel
);
307 SetPrintLevel (LogLevel
);
308 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
314 mUtilityFilename
= argv
[0];
320 // Open the file containing the FV
322 if (mUtilityFilename
== NULL
) {
323 Error (NULL
, 0, 1001, "Missing option", "Input files are not specified");
324 return GetUtilityStatus ();
326 InputFile
= fopen (LongFilePath (mUtilityFilename
), "rb");
327 if (InputFile
== NULL
) {
328 Error (NULL
, 0, 0001, "Error opening the input file", mUtilityFilename
);
329 return GetUtilityStatus ();
332 // Skip over pad bytes if specified. This is used if they prepend 0xff
333 // data to the FV image binary.
336 fseek (InputFile
, Offset
, SEEK_SET
);
339 // Determine size of FV
341 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
342 if (EFI_ERROR (Status
)) {
343 Error (NULL
, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename
);
345 return GetUtilityStatus ();
348 // Allocate a buffer for the FV image
350 FvImage
= malloc (FvSize
);
351 if (FvImage
== NULL
) {
352 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
354 return GetUtilityStatus ();
357 // Seek to the start of the image, then read the entire FV to the buffer
359 fseek (InputFile
, Offset
, SEEK_SET
);
360 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
362 if ((unsigned int) BytesRead
!= FvSize
) {
363 Error (NULL
, 0, 0004, "error reading FvImage from", mUtilityFilename
);
365 return GetUtilityStatus ();
368 LoadGuidedSectionToolsTxt (mUtilityFilename
);
370 PrintFvInfo (FvImage
, FALSE
);
376 FreeGuidBaseNameList ();
377 return GetUtilityStatus ();
391 GC_TODO: Add function description
395 Fv - Firmware Volume to print information about
396 IsChildFv - Flag specifies whether the input FV is a child FV.
406 BOOLEAN ErasePolarity
;
408 EFI_FFS_FILE_HEADER
*CurrentFile
;
411 Status
= FvBufGetSize (Fv
, &FvSize
);
415 (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) ?
419 // Get the first file
422 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
423 if (EFI_ERROR (Status
)) {
424 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
425 return GetUtilityStatus ();
428 // Display information about files found
430 while (CurrentFile
!= NULL
) {
432 // Increment the number of files counter
437 // Display info about this file
439 Status
= PrintFileInfo (Fv
, CurrentFile
, ErasePolarity
);
440 if (EFI_ERROR (Status
)) {
441 Error (NULL
, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
442 return GetUtilityStatus ();
447 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
448 if (Status
== EFI_NOT_FOUND
) {
450 } else if (EFI_ERROR (Status
)) {
451 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
452 return GetUtilityStatus ();
457 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles
);
459 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles
);
467 IN UINT32 ActualSize
,
474 This function returns the next larger size that meets the alignment
475 requirement specified.
480 Alignment The desired alignment.
484 EFI_SUCCESS Function completed successfully.
485 EFI_ABORTED The function encountered an error.
491 OccupiedSize
= ActualSize
;
492 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
502 IN EFI_SECTION_TYPE Type
508 Converts EFI Section names to Strings
512 Type - The EFI Section type
516 CHAR8* - Pointer to the String containing the section name.
521 CHAR8
*SectionTypeStringTable
[] = {
529 "EFI_SECTION_COMPRESSION",
533 "EFI_SECTION_GUID_DEFINED",
537 "Unknown section type - Reserved 0x03",
541 "Unknown section type - Reserved 0x04",
545 "Unknown section type - Reserved 0x05",
549 "Unknown section type - Reserved 0x06",
553 "Unknown section type - Reserved 0x07",
557 "Unknown section type - Reserved 0x08",
561 "Unknown section type - Reserved 0x09",
565 "Unknown section type - Reserved 0x0A",
569 "Unknown section type - Reserved 0x0B",
573 "Unknown section type - Reserved 0x0C",
577 "Unknown section type - Reserved 0x0D",
581 "Unknown section type - Reserved 0x0E",
585 "Unknown section type - Reserved 0x0E",
601 "EFI_SECTION_DXE_DEPEX",
605 "EFI_SECTION_VERSION",
609 "EFI_SECTION_USER_INTERFACE",
613 "EFI_SECTION_COMPATIBILITY16",
617 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
621 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
629 "Unknown section type - 0x1A",
633 "EFI_SECTION_PEI_DEPEX",
637 "EFI_SECTION_SMM_DEPEX",
641 "Unknown section type - Reserved - beyond last defined section"
644 if (Type
> EFI_SECTION_LAST_SECTION_TYPE
) {
645 Type
= EFI_SECTION_LAST_SECTION_TYPE
+ 1;
648 SectionStr
= malloc (100);
649 if (SectionStr
== NULL
) {
650 printf ("Error: Out of memory resources.\n");
653 strcpy (SectionStr
, SectionTypeStringTable
[Type
]);
662 OUT BOOLEAN
*ErasePolarity
668 This function determines the size of the FV and the erase polarity. The
669 erase polarity is the FALSE value for file state.
673 InputFile The file that contains the FV image.
674 FvSize The size of the FV.
675 ErasePolarity The FV erase polarity.
679 EFI_SUCCESS Function completed successfully.
680 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
681 EFI_ABORTED The function encountered an error.
685 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
686 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
694 // Check input parameters
696 if (InputFile
== NULL
|| FvSize
== NULL
|| ErasePolarity
== NULL
) {
697 Error (__FILE__
, __LINE__
, 0, "application error", "invalid parameter to function");
698 return EFI_INVALID_PARAMETER
;
703 fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
704 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
705 Signature
[0] = VolumeHeader
.Signature
;
709 // Print FV header information
711 printf ("Signature: %s (%X)\n", (char *) Signature
, (unsigned) VolumeHeader
.Signature
);
712 printf ("Attributes: %X\n", (unsigned) VolumeHeader
.Attributes
);
714 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_DISABLED_CAP
) {
715 printf (" EFI_FVB2_READ_DISABLED_CAP\n");
718 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_ENABLED_CAP
) {
719 printf (" EFI_FVB2_READ_ENABLED_CAP\n");
722 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_STATUS
) {
723 printf (" EFI_FVB2_READ_STATUS\n");
726 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_DISABLED_CAP
) {
727 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
730 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_ENABLED_CAP
) {
731 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
734 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_STATUS
) {
735 printf (" EFI_FVB2_WRITE_STATUS\n");
738 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_CAP
) {
739 printf (" EFI_FVB2_LOCK_CAP\n");
742 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_STATUS
) {
743 printf (" EFI_FVB2_LOCK_STATUS\n");
746 if (VolumeHeader
.Attributes
& EFI_FVB2_STICKY_WRITE
) {
747 printf (" EFI_FVB2_STICKY_WRITE\n");
750 if (VolumeHeader
.Attributes
& EFI_FVB2_MEMORY_MAPPED
) {
751 printf (" EFI_FVB2_MEMORY_MAPPED\n");
754 if (VolumeHeader
.Attributes
& EFI_FVB2_ERASE_POLARITY
) {
755 printf (" EFI_FVB2_ERASE_POLARITY\n");
756 *ErasePolarity
= TRUE
;
759 #if (PI_SPECIFICATION_VERSION < 0x00010000)
760 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
761 printf (" EFI_FVB2_ALIGNMENT\n");
764 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
765 printf (" EFI_FVB2_ALIGNMENT_2\n");
768 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
769 printf (" EFI_FVB2_ALIGNMENT_4\n");
772 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
773 printf (" EFI_FVB2_ALIGNMENT_8\n");
776 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
777 printf (" EFI_FVB2_ALIGNMENT_16\n");
780 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
781 printf (" EFI_FVB2_ALIGNMENT_32\n");
784 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
785 printf (" EFI_FVB2_ALIGNMENT_64\n");
788 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
789 printf (" EFI_FVB2_ALIGNMENT_128\n");
792 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
793 printf (" EFI_FVB2_ALIGNMENT_256\n");
796 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
797 printf (" EFI_FVB2_ALIGNMENT_512\n");
800 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
801 printf (" EFI_FVB2_ALIGNMENT_1K\n");
804 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
805 printf (" EFI_FVB2_ALIGNMENT_2K\n");
808 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
809 printf (" EFI_FVB2_ALIGNMENT_4K\n");
812 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
813 printf (" EFI_FVB2_ALIGNMENT_8K\n");
816 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
817 printf (" EFI_FVB2_ALIGNMENT_16K\n");
820 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
821 printf (" EFI_FVB2_ALIGNMENT_32K\n");
824 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
825 printf (" EFI_FVB2_ALIGNMENT_64K\n");
830 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_CAP
) {
831 printf (" EFI_FVB2_READ_LOCK_CAP\n");
834 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_STATUS
) {
835 printf (" EFI_FVB2_READ_LOCK_STATUS\n");
838 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_CAP
) {
839 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
842 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_STATUS
) {
843 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
846 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1
) {
847 printf (" EFI_FVB2_ALIGNMENT_1\n");
850 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
851 printf (" EFI_FVB2_ALIGNMENT_2\n");
854 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
855 printf (" EFI_FVB2_ALIGNMENT_4\n");
858 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
859 printf (" EFI_FVB2_ALIGNMENT_8\n");
862 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
863 printf (" EFI_FVB2_ALIGNMENT_16\n");
866 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
867 printf (" EFI_FVB2_ALIGNMENT_32\n");
870 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
871 printf (" EFI_FVB2_ALIGNMENT_64\n");
874 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
875 printf (" EFI_FVB2_ALIGNMENT_128\n");
878 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
879 printf (" EFI_FVB2_ALIGNMENT_256\n");
882 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
883 printf (" EFI_FVB2_ALIGNMENT_512\n");
886 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
887 printf (" EFI_FVB2_ALIGNMENT_1K\n");
890 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
891 printf (" EFI_FVB2_ALIGNMENT_2K\n");
894 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
895 printf (" EFI_FVB2_ALIGNMENT_4K\n");
898 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
899 printf (" EFI_FVB2_ALIGNMENT_8K\n");
902 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
903 printf (" EFI_FVB2_ALIGNMENT_16K\n");
906 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
907 printf (" EFI_FVB2_ALIGNMENT_32K\n");
910 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
911 printf (" EFI_FVB2_ALIGNMENT_64K\n");
914 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128K
) {
915 printf (" EFI_FVB2_ALIGNMENT_128K\n");
918 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256K
) {
919 printf (" EFI_FVB2_ALIGNMENT_256K\n");
922 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512K
) {
923 printf (" EFI_FVB2_ALIGNMENT_512K\n");
926 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1M
) {
927 printf (" EFI_FVB2_ALIGNMENT_1M\n");
930 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2M
) {
931 printf (" EFI_FVB2_ALIGNMENT_2M\n");
934 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4M
) {
935 printf (" EFI_FVB2_ALIGNMENT_4M\n");
938 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8M
) {
939 printf (" EFI_FVB2_ALIGNMENT_8M\n");
942 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16M
) {
943 printf (" EFI_FVB2_ALIGNMENT_16M\n");
946 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32M
) {
947 printf (" EFI_FVB2_ALIGNMENT_32M\n");
950 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
951 printf (" EFI_FVB2_ALIGNMENT_64M\n");
954 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
955 printf (" EFI_FVB2_ALIGNMENT_128M\n");
958 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
959 printf (" EFI_FVB2_ALIGNMENT_64M\n");
962 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
963 printf (" EFI_FVB2_ALIGNMENT_128M\n");
966 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256M
) {
967 printf (" EFI_FVB2_ALIGNMENT_256M\n");
970 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512M
) {
971 printf (" EFI_FVB2_ALIGNMENT_512M\n");
974 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1G
) {
975 printf (" EFI_FVB2_ALIGNMENT_1G\n");
978 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2G
) {
979 printf (" EFI_FVB2_ALIGNMENT_2G\n");
983 printf ("Header Length: 0x%08X\n", VolumeHeader
.HeaderLength
);
984 printf ("File System ID: ");
985 PrintGuid (&VolumeHeader
.FileSystemGuid
);
989 printf ("Revision: 0x%04X\n", VolumeHeader
.Revision
);
992 fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
993 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
995 if (BlockMap
.NumBlocks
!= 0) {
996 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap
.NumBlocks
);
997 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap
.Length
);
998 Size
+= BlockMap
.NumBlocks
* BlockMap
.Length
;
1001 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.Length
== 0));
1003 if (BytesRead
!= VolumeHeader
.HeaderLength
) {
1004 printf ("ERROR: Header length not consistent with Block Maps!\n");
1008 if (VolumeHeader
.FvLength
!= Size
) {
1009 printf ("ERROR: Volume Size not consistant with Block Maps!\n");
1013 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size
);
1018 // rewind (InputFile);
1026 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
1027 EFI_FFS_FILE_HEADER
*FileHeader
,
1028 BOOLEAN ErasePolarity
1032 Routine Description:
1034 GC_TODO: Add function description
1038 FvImage - GC_TODO: add argument description
1039 FileHeader - GC_TODO: add argument description
1040 ErasePolarity - GC_TODO: add argument description
1044 EFI_SUCCESS - GC_TODO: Add description for return value
1045 EFI_ABORTED - GC_TODO: Add description for return value
1052 EFI_FFS_FILE_HEADER2 BlankHeader
;
1054 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1056 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1060 // Check if we have free space
1062 HeaderSize
= FvBufGetFfsHeaderSize(FileHeader
);
1063 if (ErasePolarity
) {
1064 memset (&BlankHeader
, -1, HeaderSize
);
1066 memset (&BlankHeader
, 0, HeaderSize
);
1069 if (memcmp (&BlankHeader
, FileHeader
, HeaderSize
) == 0) {
1073 // Print file information.
1075 printf ("============================================================\n");
1077 printf ("File Name: ");
1078 PrintGuidToBuffer (&FileHeader
->Name
, GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
1079 printf ("%s ", GuidBuffer
);
1080 PrintGuidName (GuidBuffer
);
1084 // PrintGuid (&FileHeader->Name);
1087 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1088 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN
) FileHeader
- (UINTN
) FvImage
));
1089 printf ("File Length: 0x%08X\n", (unsigned) FileLength
);
1090 printf ("File Attributes: 0x%02X\n", FileHeader
->Attributes
);
1091 printf ("File State: 0x%02X\n", FileHeader
->State
);
1096 FileState
= GetFileState (ErasePolarity
, FileHeader
);
1098 switch (FileState
) {
1100 case EFI_FILE_HEADER_CONSTRUCTION
:
1101 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
1104 case EFI_FILE_HEADER_INVALID
:
1105 printf (" EFI_FILE_HEADER_INVALID\n");
1108 case EFI_FILE_HEADER_VALID
:
1109 printf (" EFI_FILE_HEADER_VALID\n");
1110 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1111 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1112 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1113 if (Checksum
!= 0) {
1114 printf ("ERROR: Header checksum invalid.\n");
1120 case EFI_FILE_DELETED
:
1121 printf (" EFI_FILE_DELETED\n");
1123 case EFI_FILE_MARKED_FOR_UPDATE
:
1124 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
1126 case EFI_FILE_DATA_VALID
:
1127 printf (" EFI_FILE_DATA_VALID\n");
1130 // Calculate header checksum
1132 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1133 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1134 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1135 if (Checksum
!= 0) {
1136 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer
);
1140 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1142 if (FileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
1144 // Calculate file checksum
1146 Checksum
= CalculateSum8 ((UINT8
*)FileHeader
+ HeaderSize
, FileLength
- HeaderSize
);
1147 Checksum
= Checksum
+ FileHeader
->IntegrityCheck
.Checksum
.File
;
1148 if (Checksum
!= 0) {
1149 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer
);
1153 if (FileHeader
->IntegrityCheck
.Checksum
.File
!= FFS_FIXED_CHECKSUM
) {
1154 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
);
1158 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1160 // Verify tail if present
1162 if (FileHeader
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
1164 // Verify tail is complement of integrity check field in the header.
1166 Tail
= (UINT16
*) ((UINTN
) FileHeader
+ GetLength (FileHeader
->Size
) - sizeof (EFI_FFS_INTEGRITY_CHECK
));
1167 if (FileHeader
->IntegrityCheck
.TailReference
!= (UINT16
)~(*Tail
)) {
1168 Error (NULL
, 0, 0003, "error parsing FFS file", \
1169 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer
);
1177 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer
);
1181 printf ("File Type: 0x%02X ", FileHeader
->Type
);
1183 switch (FileHeader
->Type
) {
1185 case EFI_FV_FILETYPE_RAW
:
1186 printf ("EFI_FV_FILETYPE_RAW\n");
1189 case EFI_FV_FILETYPE_FREEFORM
:
1190 printf ("EFI_FV_FILETYPE_FREEFORM\n");
1193 case EFI_FV_FILETYPE_SECURITY_CORE
:
1194 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
1197 case EFI_FV_FILETYPE_PEI_CORE
:
1198 printf ("EFI_FV_FILETYPE_PEI_CORE\n");
1201 case EFI_FV_FILETYPE_DXE_CORE
:
1202 printf ("EFI_FV_FILETYPE_DXE_CORE\n");
1205 case EFI_FV_FILETYPE_PEIM
:
1206 printf ("EFI_FV_FILETYPE_PEIM\n");
1209 case EFI_FV_FILETYPE_DRIVER
:
1210 printf ("EFI_FV_FILETYPE_DRIVER\n");
1213 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
1214 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
1217 case EFI_FV_FILETYPE_APPLICATION
:
1218 printf ("EFI_FV_FILETYPE_APPLICATION\n");
1221 case EFI_FV_FILETYPE_SMM
:
1222 printf ("EFI_FV_FILETYPE_SMM\n");
1225 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
:
1226 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1229 case EFI_FV_FILETYPE_COMBINED_SMM_DXE
:
1230 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
1233 case EFI_FV_FILETYPE_SMM_CORE
:
1234 printf ("EFI_FV_FILETYPE_SMM_CORE\n");
1237 case EFI_FV_FILETYPE_FFS_PAD
:
1238 printf ("EFI_FV_FILETYPE_FFS_PAD\n");
1242 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader
->Type
);
1247 switch (FileHeader
->Type
) {
1249 case EFI_FV_FILETYPE_ALL
:
1250 case EFI_FV_FILETYPE_RAW
:
1251 case EFI_FV_FILETYPE_FFS_PAD
:
1256 // All other files have sections
1258 Status
= ParseSection (
1259 (UINT8
*) ((UINTN
) FileHeader
+ HeaderSize
),
1260 FvBufGetFfsFileSize (FileHeader
) - HeaderSize
1262 if (EFI_ERROR (Status
)) {
1264 // printf ("ERROR: Parsing the FFS file.\n");
1276 IN VOID
*FileHandle
,
1277 IN UINTN FileOffset
,
1278 IN OUT UINT32
*ReadSize
,
1283 Routine Description:
1285 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
1289 FileHandle - The handle to the PE/COFF file
1291 FileOffset - The offset, in bytes, into the file to read
1293 ReadSize - The number of bytes to read from the file starting at FileOffset
1295 Buffer - A pointer to the buffer to read the data into.
1299 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1303 CHAR8
*Destination8
;
1307 Destination8
= Buffer
;
1308 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
1311 *(Destination8
++) = *(Source8
++);
1318 SetAddressToSectionHeader (
1320 IN OUT UINT8
*FileBuffer
,
1321 IN UINT64 NewPe32BaseAddress
1325 Routine Description:
1327 Set new base address into the section header of PeImage
1331 FileName - Name of file
1332 FileBuffer - Pointer to PeImage.
1333 NewPe32BaseAddress - New Base Address for PE image.
1337 EFI_SUCCESS Set new base address into this image successfully.
1342 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1344 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1345 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1348 // Initialize context
1350 memset (&ImageContext
, 0, sizeof (ImageContext
));
1351 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1352 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1353 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1354 if (EFI_ERROR (Status
)) {
1355 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1359 if (ImageContext
.RelocationsStripped
) {
1360 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1365 // Get PeHeader pointer
1367 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1370 // Get section header list
1372 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1375 sizeof (EFI_IMAGE_FILE_HEADER
) +
1376 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1380 // Set base address into the first section header that doesn't point to code section.
1382 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1383 if ((SectionHeader
->Characteristics
& EFI_IMAGE_SCN_CNT_CODE
) == 0) {
1384 *(UINT64
*) &SectionHeader
->PointerToRelocations
= NewPe32BaseAddress
;
1390 // BaseAddress is set to section header.
1398 IN OUT UINT8
*FileBuffer
,
1399 IN UINT64 NewPe32BaseAddress
1403 Routine Description:
1405 Set new base address into PeImage, and fix up PeImage based on new address.
1409 FileName - Name of file
1410 FileBuffer - Pointer to PeImage.
1411 NewPe32BaseAddress - New Base Address for PE image.
1415 EFI_INVALID_PARAMETER - BaseAddress is not valid.
1416 EFI_SUCCESS - Update PeImage is correctly.
1421 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1423 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1424 UINT8
*MemoryImagePointer
;
1425 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1428 // Initialize context
1430 memset (&ImageContext
, 0, sizeof (ImageContext
));
1431 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1432 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1433 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1434 if (EFI_ERROR (Status
)) {
1435 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1439 if (ImageContext
.RelocationsStripped
) {
1440 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1445 // Get PeHeader pointer
1447 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1450 // Load and Relocate Image Data
1452 MemoryImagePointer
= (UINT8
*) malloc ((UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1453 if (MemoryImagePointer
== NULL
) {
1454 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName
);
1455 return EFI_OUT_OF_RESOURCES
;
1457 memset ((VOID
*) MemoryImagePointer
, 0, (UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1458 ImageContext
.ImageAddress
= ((UINTN
) MemoryImagePointer
+ ImageContext
.SectionAlignment
- 1) & (~((INT64
)ImageContext
.SectionAlignment
- 1));
1460 Status
= PeCoffLoaderLoadImage (&ImageContext
);
1461 if (EFI_ERROR (Status
)) {
1462 Error (NULL
, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName
);
1463 free ((VOID
*) MemoryImagePointer
);
1467 ImageContext
.DestinationAddress
= NewPe32BaseAddress
;
1468 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
1469 if (EFI_ERROR (Status
)) {
1470 Error (NULL
, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName
);
1471 free ((VOID
*) MemoryImagePointer
);
1476 // Copy Relocated data to raw image file.
1478 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1481 sizeof (EFI_IMAGE_FILE_HEADER
) +
1482 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1485 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1487 FileBuffer
+ SectionHeader
->PointerToRawData
,
1488 (VOID
*) (UINTN
) (ImageContext
.ImageAddress
+ SectionHeader
->VirtualAddress
),
1489 SectionHeader
->SizeOfRawData
1493 free ((VOID
*) MemoryImagePointer
);
1496 // Update Image Base Address
1498 if ((ImgHdr
->Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) && (ImgHdr
->Pe32
.FileHeader
.Machine
!= IMAGE_FILE_MACHINE_IA64
)) {
1499 ImgHdr
->Pe32
.OptionalHeader
.ImageBase
= (UINT32
) NewPe32BaseAddress
;
1500 } else if (ImgHdr
->Pe32Plus
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
1501 ImgHdr
->Pe32Plus
.OptionalHeader
.ImageBase
= NewPe32BaseAddress
;
1503 Error (NULL
, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
1504 ImgHdr
->Pe32
.OptionalHeader
.Magic
,
1511 // Set new base address into section header
1513 Status
= SetAddressToSectionHeader (FileName
, FileBuffer
, NewPe32BaseAddress
);
1520 IN CHAR8
* DefaultPath
,
1521 IN CHAR8
* AppendPath
,
1525 UINT32 DefaultPathLen
;
1526 DefaultPathLen
= strlen(DefaultPath
);
1527 strcpy(NewPath
, DefaultPath
);
1529 for (; Index
< DefaultPathLen
; Index
++) {
1530 if (NewPath
[Index
] == '\\' || NewPath
[Index
] == '/') {
1531 if (NewPath
[Index
+ 1] != '\0') {
1532 NewPath
[Index
] = '/';
1536 if (NewPath
[Index
-1] != '/') {
1537 NewPath
[Index
] = '/';
1538 NewPath
[Index
+ 1] = '\0';
1540 strcat(NewPath
, AppendPath
);
1546 IN UINT8
*SectionBuffer
,
1547 IN UINT32 BufferLength
1551 Routine Description:
1557 SectionBuffer - Buffer containing the section to parse.
1558 BufferLength - Length of SectionBuffer
1562 EFI_SECTION_ERROR - Problem with section parsing.
1563 (a) compression errors
1564 (b) unrecognized section
1565 EFI_UNSUPPORTED - Do not know how to parse the section.
1566 EFI_SUCCESS - Section successfully parsed.
1567 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1571 EFI_SECTION_TYPE Type
;
1573 UINT32 SectionLength
;
1574 UINT32 SectionHeaderLen
;
1577 UINT32 ParsedLength
;
1578 UINT8
*CompressedBuffer
;
1579 UINT32 CompressedLength
;
1580 UINT8
*UncompressedBuffer
;
1581 UINT32 UncompressedLength
;
1582 UINT8
*ToolOutputBuffer
;
1583 UINT32 ToolOutputLength
;
1584 UINT8 CompressionType
;
1587 UINT8
*ScratchBuffer
;
1588 DECOMPRESS_FUNCTION DecompressFunction
;
1589 GETINFO_FUNCTION GetInfoFunction
;
1591 CHAR8
*ExtractionTool
;
1592 CHAR8
*ToolInputFile
;
1593 CHAR8
*ToolOutputFile
;
1594 CHAR8
*SystemCommandFormatString
;
1595 CHAR8
*SystemCommand
;
1600 CHAR8
*ToolInputFileName
;
1601 CHAR8
*ToolOutputFileName
;
1604 ToolInputFileName
= NULL
;
1605 ToolOutputFileName
= NULL
;
1607 while (ParsedLength
< BufferLength
) {
1608 Ptr
= SectionBuffer
+ ParsedLength
;
1610 SectionLength
= GetLength (((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Size
);
1611 Type
= ((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Type
;
1614 // This is sort of an odd check, but is necessary because FFS files are
1615 // padded to a QWORD boundary, meaning there is potentially a whole section
1616 // header worth of 0xFF bytes.
1618 if (SectionLength
== 0xffffff && Type
== 0xff) {
1624 // Get real section file size
1626 SectionLength
= GetSectionFileLength ((EFI_COMMON_SECTION_HEADER
*) Ptr
);
1627 SectionHeaderLen
= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
1629 SectionName
= SectionNameToStr (Type
);
1630 if (SectionName
!= NULL
) {
1631 printf ("------------------------------------------------------------\n");
1632 printf (" Type: %s\n Size: 0x%08X\n", SectionName
, (unsigned) SectionLength
);
1637 case EFI_SECTION_RAW
:
1638 case EFI_SECTION_PIC
:
1639 case EFI_SECTION_TE
:
1640 // default is no more information
1643 case EFI_SECTION_PE32
:
1645 ToolInputFileName
= "edk2Temp_InputEfi.tmp";
1646 ToolOutputFileName
= "edk2Temp_OutputHash.tmp";
1647 RebaseImage(ToolInputFileName
, (UINT8
*)Ptr
+ SectionHeaderLen
, 0);
1650 (CHAR8
*)Ptr
+ SectionHeaderLen
,
1651 SectionLength
- SectionHeaderLen
1654 SystemCommandFormatString
= "%s sha1 -out %s %s";
1655 SystemCommand
= malloc (
1656 strlen (SystemCommandFormatString
) +
1657 strlen (OpenSslPath
) +
1658 strlen (ToolInputFileName
) +
1659 strlen (ToolOutputFileName
) +
1662 if (SystemCommand
== NULL
) {
1663 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1664 return EFI_OUT_OF_RESOURCES
;
1668 SystemCommandFormatString
,
1674 if (system (SystemCommand
) != EFI_SUCCESS
) {
1675 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
1682 if((fp
= fopen(ToolOutputFileName
,"r")) == NULL
) {
1683 Error (NULL
, 0, 0004, "Hash the PE32 image failed.", NULL
);
1686 fseek(fp
,0,SEEK_SET
);
1687 fseek(fp
,0,SEEK_END
);
1688 nFileLen
= ftell(fp
);
1689 fseek(fp
,0,SEEK_SET
);
1690 StrLine
= malloc(nFileLen
);
1691 if (StrLine
== NULL
) {
1693 free (SystemCommand
);
1694 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1695 return EFI_OUT_OF_RESOURCES
;
1697 fgets(StrLine
, nFileLen
, fp
);
1698 NewStr
= strrchr (StrLine
, '=');
1699 printf (" SHA1: %s\n", NewStr
+ 1);
1704 remove(ToolInputFileName
);
1705 remove(ToolOutputFileName
);
1706 free (SystemCommand
);
1710 case EFI_SECTION_USER_INTERFACE
:
1711 printf (" String: %ls\n", (CHAR16
*) &((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
);
1714 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
1715 Status
= PrintFvInfo (Ptr
+ SectionHeaderLen
, TRUE
);
1716 if (EFI_ERROR (Status
)) {
1717 Error (NULL
, 0, 0003, "printing of FV section contents failed", NULL
);
1718 return EFI_SECTION_ERROR
;
1722 case EFI_SECTION_COMPATIBILITY16
:
1723 case EFI_SECTION_FREEFORM_SUBTYPE_GUID
:
1725 // Section does not contain any further header information.
1729 case EFI_SECTION_PEI_DEPEX
:
1730 case EFI_SECTION_DXE_DEPEX
:
1731 case EFI_SECTION_SMM_DEPEX
:
1732 DumpDepexSection (Ptr
, SectionLength
);
1735 case EFI_SECTION_VERSION
:
1736 printf (" Build Number: 0x%02X\n", *(UINT16
*)(Ptr
+ SectionHeaderLen
));
1737 printf (" Version Strg: %s\n", (char*) (Ptr
+ SectionHeaderLen
+ sizeof (UINT16
)));
1740 case EFI_SECTION_COMPRESSION
:
1741 UncompressedBuffer
= NULL
;
1742 if (SectionHeaderLen
== sizeof (EFI_COMMON_SECTION_HEADER
)) {
1743 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION
);
1744 UncompressedLength
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->UncompressedLength
;
1745 CompressionType
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->CompressionType
;
1747 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION2
);
1748 UncompressedLength
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->UncompressedLength
;
1749 CompressionType
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->CompressionType
;
1751 CompressedLength
= SectionLength
- RealHdrLen
;
1752 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength
);
1754 if (CompressionType
== EFI_NOT_COMPRESSED
) {
1755 printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1756 if (CompressedLength
!= UncompressedLength
) {
1761 "file is not compressed, but the compressed length does not match the uncompressed length",
1764 return EFI_SECTION_ERROR
;
1767 UncompressedBuffer
= Ptr
+ RealHdrLen
;
1768 } else if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1769 GetInfoFunction
= EfiGetInfo
;
1770 DecompressFunction
= EfiDecompress
;
1771 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
1773 CompressedBuffer
= Ptr
+ RealHdrLen
;
1775 Status
= GetInfoFunction (CompressedBuffer
, CompressedLength
, &DstSize
, &ScratchSize
);
1776 if (EFI_ERROR (Status
)) {
1777 Error (NULL
, 0, 0003, "error getting compression info from compression section", NULL
);
1778 return EFI_SECTION_ERROR
;
1781 if (DstSize
!= UncompressedLength
) {
1782 Error (NULL
, 0, 0003, "compression error in the compression section", NULL
);
1783 return EFI_SECTION_ERROR
;
1786 ScratchBuffer
= malloc (ScratchSize
);
1787 UncompressedBuffer
= malloc (UncompressedLength
);
1788 if ((ScratchBuffer
== NULL
) || (UncompressedBuffer
== NULL
)) {
1789 return EFI_OUT_OF_RESOURCES
;
1791 Status
= DecompressFunction (
1799 free (ScratchBuffer
);
1800 if (EFI_ERROR (Status
)) {
1801 Error (NULL
, 0, 0003, "decompress failed", NULL
);
1802 free (UncompressedBuffer
);
1803 return EFI_SECTION_ERROR
;
1806 Error (NULL
, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType
);
1807 return EFI_SECTION_ERROR
;
1810 Status
= ParseSection (UncompressedBuffer
, UncompressedLength
);
1812 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1814 // We need to deallocate Buffer
1816 free (UncompressedBuffer
);
1819 if (EFI_ERROR (Status
)) {
1820 Error (NULL
, 0, 0003, "failed to parse section", NULL
);
1821 return EFI_SECTION_ERROR
;
1825 case EFI_SECTION_GUID_DEFINED
:
1826 if (SectionHeaderLen
== sizeof(EFI_COMMON_SECTION_HEADER
)) {
1827 EfiGuid
= &((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
;
1828 DataOffset
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
;
1829 Attributes
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->Attributes
;
1831 EfiGuid
= &((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->SectionDefinitionGuid
;
1832 DataOffset
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->DataOffset
;
1833 Attributes
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->Attributes
;
1835 printf (" SectionDefinitionGuid: ");
1836 PrintGuid (EfiGuid
);
1838 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset
);
1839 printf (" Attributes: 0x%04X\n", (unsigned) Attributes
);
1842 LookupGuidedSectionToolPath (
1843 mParsedGuidedSectionTools
,
1847 if (ExtractionTool
!= NULL
) {
1849 ToolInputFile
= CloneString (tmpnam (NULL
));
1850 ToolOutputFile
= CloneString (tmpnam (NULL
));
1852 char tmp1
[] = "/tmp/fileXXXXXX";
1853 char tmp2
[] = "/tmp/fileXXXXXX";
1856 fd1
= mkstemp(tmp1
);
1857 fd2
= mkstemp(tmp2
);
1858 ToolInputFile
= CloneString(tmp1
);
1859 ToolOutputFile
= CloneString(tmp2
);
1864 if ((ToolInputFile
== NULL
) || (ToolOutputFile
== NULL
)) {
1865 if (ToolInputFile
!= NULL
) {
1866 free (ToolInputFile
);
1868 if (ToolOutputFile
!= NULL
) {
1869 free (ToolOutputFile
);
1871 free (ExtractionTool
);
1873 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1874 return EFI_OUT_OF_RESOURCES
;
1878 // Construction 'system' command string
1880 SystemCommandFormatString
= "%s -d -o %s %s";
1881 SystemCommand
= malloc (
1882 strlen (SystemCommandFormatString
) +
1883 strlen (ExtractionTool
) +
1884 strlen (ToolInputFile
) +
1885 strlen (ToolOutputFile
) +
1888 if (SystemCommand
== NULL
) {
1889 free (ToolInputFile
);
1890 free (ToolOutputFile
);
1891 free (ExtractionTool
);
1893 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1894 return EFI_OUT_OF_RESOURCES
;
1898 SystemCommandFormatString
,
1903 free (ExtractionTool
);
1908 (CHAR8
*) SectionBuffer
+ DataOffset
,
1909 BufferLength
- DataOffset
1912 system (SystemCommand
);
1913 remove (ToolInputFile
);
1914 free (ToolInputFile
);
1919 (CHAR8
**)&ToolOutputBuffer
,
1922 remove (ToolOutputFile
);
1923 free (ToolOutputFile
);
1924 free (SystemCommand
);
1925 if (EFI_ERROR (Status
)) {
1926 Error (NULL
, 0, 0004, "unable to read decoded GUIDED section", NULL
);
1927 return EFI_SECTION_ERROR
;
1930 Status
= ParseSection (
1934 if (EFI_ERROR (Status
)) {
1935 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
1936 return EFI_SECTION_ERROR
;
1940 // Check for CRC32 sections which we can handle internally if needed.
1942 } else if (!CompareGuid (
1944 &gEfiCrc32GuidedSectionExtractionProtocolGuid
1948 // CRC32 guided section
1950 Status
= ParseSection (
1951 SectionBuffer
+ DataOffset
,
1952 BufferLength
- DataOffset
1954 if (EFI_ERROR (Status
)) {
1955 Error (NULL
, 0, 0003, "parse of CRC32 GUIDED section failed", NULL
);
1956 return EFI_SECTION_ERROR
;
1960 // We don't know how to parse it now.
1962 Error (NULL
, 0, 0003, "Error parsing section", \
1963 "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).");
1964 return EFI_UNSUPPORTED
;
1970 // Unknown section, return error
1972 Error (NULL
, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type
);
1973 return EFI_SECTION_ERROR
;
1976 ParsedLength
+= SectionLength
;
1978 // We make then next section begin on a 4-byte boundary
1980 ParsedLength
= GetOccupiedSize (ParsedLength
, 4);
1983 if (ParsedLength
< BufferLength
) {
1984 Error (NULL
, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL
);
1985 return EFI_SECTION_ERROR
;
1994 IN UINT32 SectionLength
1998 Routine Description:
2000 GC_TODO: Add function description
2004 Ptr - GC_TODO: add argument description
2005 SectionLength - GC_TODO: add argument description
2009 EFI_SUCCESS - GC_TODO: Add description for return value
2013 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
2016 // Need at least a section header + data
2018 if (SectionLength
<= sizeof (EFI_COMMON_SECTION_HEADER
)) {
2022 Ptr
+= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2023 SectionLength
-= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2024 while (SectionLength
> 0) {
2027 case EFI_DEP_BEFORE
:
2028 printf ("BEFORE\n");
2041 PrintGuidToBuffer ((EFI_GUID
*) (Ptr
+ 1), GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
2042 printf ("%s ", GuidBuffer
);
2043 PrintGuidName (GuidBuffer
);
2046 // PrintGuid ((EFI_GUID *)(Ptr + 1));
2049 SectionLength
-= 17;
2083 printf ("END DEPEX\n");
2095 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr
);
2109 Routine Description:
2111 GC_TODO: Add function description
2115 GuidStr - GC_TODO: add argument description
2119 EFI_SUCCESS - GC_TODO: Add description for return value
2120 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
2124 GUID_TO_BASENAME
*GPtr
;
2126 // If we have a list of guid-to-basenames, then go through the list to
2127 // look for a guid string match. If found, print the basename to stdout,
2128 // otherwise return a failure.
2130 GPtr
= mGuidBaseNameList
;
2131 while (GPtr
!= NULL
) {
2132 if (_stricmp ((CHAR8
*) GuidStr
, (CHAR8
*) GPtr
->Guid
) == 0) {
2133 printf ("%s", GPtr
->BaseName
);
2140 return EFI_INVALID_PARAMETER
;
2144 ParseGuidBaseNameFile (
2149 Routine Description:
2151 GC_TODO: Add function description
2155 FileName - GC_TODO: add argument description
2159 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
2160 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
2161 EFI_SUCCESS - GC_TODO: Add description for return value
2166 CHAR8 Line
[MAX_LINE_LEN
];
2167 GUID_TO_BASENAME
*GPtr
;
2169 if ((Fptr
= fopen (LongFilePath (FileName
), "r")) == NULL
) {
2170 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName
);
2171 return EFI_DEVICE_ERROR
;
2174 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
2176 // Allocate space for another guid/basename element
2178 GPtr
= malloc (sizeof (GUID_TO_BASENAME
));
2180 return EFI_OUT_OF_RESOURCES
;
2183 memset ((char *) GPtr
, 0, sizeof (GUID_TO_BASENAME
));
2184 if (sscanf (Line
, "%s %s", GPtr
->Guid
, GPtr
->BaseName
) == 2) {
2185 GPtr
->Next
= mGuidBaseNameList
;
2186 mGuidBaseNameList
= GPtr
;
2189 // Some sort of error. Just continue.
2200 FreeGuidBaseNameList (
2205 Routine Description:
2207 GC_TODO: Add function description
2215 EFI_SUCCESS - GC_TODO: Add description for return value
2219 GUID_TO_BASENAME
*Next
;
2221 while (mGuidBaseNameList
!= NULL
) {
2222 Next
= mGuidBaseNameList
->Next
;
2223 free (mGuidBaseNameList
);
2224 mGuidBaseNameList
= Next
;
2233 LoadGuidedSectionToolsTxt (
2234 IN CHAR8
* FirmwareVolumeFilename
2237 CHAR8
* PeerFilename
;
2244 Places
[0] = FirmwareVolumeFilename
;
2245 //Places[1] = mUtilityFilename;
2247 mParsedGuidedSectionTools
= NULL
;
2249 for (Index
= 0; Index
< (sizeof(Places
)/sizeof(Places
[0])); Index
++) {
2250 PeerFilename
= OsPathPeerFilePath (Places
[Index
], "GuidedSectionTools.txt");
2251 //printf("Loading %s...\n", PeerFilename);
2252 if (OsPathExists (PeerFilename
)) {
2253 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (PeerFilename
);
2255 free (PeerFilename
);
2256 if (mParsedGuidedSectionTools
!= NULL
) {
2269 Routine Description:
2271 GC_TODO: Add function description
2279 GC_TODO: add return values
2286 fprintf (stdout
, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME
);
2289 // Copyright declaration
2291 fprintf (stdout
, "Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.\n\n");
2292 fprintf (stdout
, " Display Tiano Firmware Volume FFS image information\n\n");
2297 fprintf (stdout
, "optional arguments:\n");
2298 fprintf (stdout
, " -h, --help\n\
2299 Show this help message and exit\n");
2300 fprintf (stdout
, " --version\n\
2301 Show program's version number and exit\n");
2302 fprintf (stdout
, " -d [DEBUG], --debug [DEBUG]\n\
2303 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
2304 fprintf (stdout
, " -v, --verbose\n\
2305 Print informational statements\n");
2306 fprintf (stdout
, " -q, --quiet\n\
2307 Returns the exit code, error messages will be displayed\n");
2308 fprintf (stdout
, " -s, --silent\n\
2309 Returns only the exit code; informational and error\n\
2310 messages are not displayed\n");
2311 fprintf (stdout
, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
2312 Parse the basename to file-guid cross reference file(s)\n");
2313 fprintf (stdout
, " -f OFFSET, --offset OFFSET\n\
2314 The offset from the start of the input file to start \n\
2315 processing an FV\n");
2316 fprintf (stdout
, " --hash\n\
2317 Generate HASH value of the entire PE image\n");
2318 fprintf (stdout
, " --sfo\n\
2319 Reserved for future use\n");