2 The tool dumps the contents of a firmware volume
4 Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
21 #include <Common/UefiBaseTypes.h>
22 #include <Common/UefiCapsule.h>
23 #include <Common/PiFirmwareFile.h>
24 #include <Common/PiFirmwareVolume.h>
25 #include <Guid/PiFirmwareFileSystem.h>
26 #include <IndustryStandard/PeImage.h>
27 #include <Protocol/GuidedSectionExtraction.h>
30 #include "Decompress.h"
32 #include "CommonLib.h"
33 #include "EfiUtilityMsgs.h"
34 #include "FirmwareVolumeBufferLib.h"
36 #include "ParseGuidedSectionTools.h"
37 #include "StringFuncs.h"
39 #include "PeCoffLib.h"
42 // Utility global variables
45 EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
47 #define UTILITY_MAJOR_VERSION 1
48 #define UTILITY_MINOR_VERSION 0
50 #define UTILITY_NAME "VolInfo"
52 #define EFI_SECTION_ERROR EFIERR (100)
54 #define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable
57 // Structure to keep a list of guid-to-basenames
59 typedef struct _GUID_TO_BASENAME
{
60 struct _GUID_TO_BASENAME
*Next
;
61 INT8 Guid
[PRINTED_GUID_BUFFER_SIZE
];
62 INT8 BaseName
[MAX_BASENAME_LEN
];
65 static GUID_TO_BASENAME
*mGuidBaseNameList
= NULL
;
68 // Store GUIDed Section guid->tool mapping
70 EFI_HANDLE mParsedGuidedSectionTools
= NULL
;
72 CHAR8
* mUtilityFilename
= NULL
;
74 BOOLEAN EnableHash
= FALSE
;
75 CHAR8
*OpenSslPath
= NULL
;
78 ParseGuidBaseNameFile (
83 FreeGuidBaseNameList (
94 IN UINT8
*SectionBuffer
,
95 IN UINT32 BufferLength
101 IN UINT32 SectionLength
109 OUT BOOLEAN
*ErasePolarity
115 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
116 EFI_FFS_FILE_HEADER
*FileHeader
,
117 BOOLEAN ErasePolarity
129 LoadGuidedSectionToolsTxt (
130 IN CHAR8
* FirmwareVolumeFilename
135 IN CHAR8
* DefaultPath
,
136 IN CHAR8
* AppendPath
,
153 Returns the length of a null-terminated unicode string.
157 String - The pointer to a null-terminated unicode string.
167 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
174 Unicode2AsciiString (
176 OUT CHAR8
*Destination
182 Convert a null-terminated unicode string to a null-terminated ascii string.
186 Source - The pointer to the null-terminated input unicode string.
187 Destination - The pointer to the null-terminated output ascii string.
195 while (*Source
!= '\0') {
196 *(Destination
++) = (CHAR8
) *(Source
++);
199 // End the ascii with a NULL.
213 GC_TODO: Add function description
217 argc - GC_TODO: add argument description
218 ] - GC_TODO: add argument description
222 GC_TODO: add return values
228 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
;
232 BOOLEAN ErasePolarity
;
235 CHAR8
*OpenSslCommand
;
237 SetUtilityName (UTILITY_NAME
);
239 // Print utility header
241 printf ("%s Version %d.%d Build %s\n",
243 UTILITY_MAJOR_VERSION
,
244 UTILITY_MINOR_VERSION
,
259 // Look for help options
261 if ((strcmp(argv
[0], "-h") == 0) || (strcmp(argv
[0], "--help") == 0) ||
262 (strcmp(argv
[0], "-?") == 0) || (strcmp(argv
[0], "/?") == 0)) {
264 return STATUS_SUCCESS
;
267 // Version has already be printed, so just return success
269 if (strcmp(argv
[0], "--version") == 0) {
270 return STATUS_SUCCESS
;
274 // If they specified -x xref guid/basename cross-reference files, process it.
275 // This will print the basename beside each file guid. To use it, specify
276 // -x xref_filename to processdsc, then use xref_filename as a parameter
280 if ((strcmp(argv
[0], "-x") == 0) || (strcmp(argv
[0], "--xref") == 0)) {
281 ParseGuidBaseNameFile (argv
[1]);
282 printf("ParseGuidBaseNameFile: %s\n", argv
[1]);
287 if (strcmp(argv
[0], "--offset") == 0) {
291 if ((argv
[1][0] == '0') && (tolower ((int)argv
[1][1]) == 'x')) {
292 if (sscanf (argv
[1], "%x", &Offset
) != 1) {
293 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
294 return GetUtilityStatus ();
297 if (sscanf (argv
[1], "%d", &Offset
) != 1) {
298 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
299 return GetUtilityStatus ();
302 // See if they said something like "64K"
304 if (tolower ((int)argv
[1][strlen (argv
[1]) - 1]) == 'k') {
313 if ((stricmp (argv
[0], "--hash") == 0)) {
314 if (EnableHash
== TRUE
) {
316 // --hash already given in the option, ignore this one
323 OpenSslCommand
= "openssl";
324 OpenSslEnv
= getenv("OPENSSL_PATH");
325 if (OpenSslEnv
== NULL
) {
326 OpenSslPath
= OpenSslCommand
;
329 // We add quotes to the Openssl Path in case it has space characters
331 OpenSslPath
= malloc(2+strlen(OpenSslEnv
)+strlen(OpenSslCommand
)+1);
332 if (OpenSslPath
== NULL
) {
333 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
334 return GetUtilityStatus ();
336 CombinePath(OpenSslEnv
, OpenSslCommand
, OpenSslPath
);
338 if (OpenSslPath
== NULL
){
339 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
340 return GetUtilityStatus ();
347 if ((stricmp (argv
[0], "-v") == 0) || (stricmp (argv
[0], "--verbose") == 0)) {
348 SetPrintLevel (VERBOSE_LOG_LEVEL
);
354 if ((stricmp (argv
[0], "-q") == 0) || (stricmp (argv
[0], "--quiet") == 0)) {
355 SetPrintLevel (KEY_LOG_LEVEL
);
361 if ((stricmp (argv
[0], "-d") == 0) || (stricmp (argv
[0], "--debug") == 0)) {
362 Status
= AsciiStringToUint64 (argv
[1], FALSE
, &LogLevel
);
363 if (EFI_ERROR (Status
)) {
364 Error (NULL
, 0, 1003, "Invalid option value", "%s = %s", argv
[0], argv
[1]);
368 Error (NULL
, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel
);
371 SetPrintLevel (LogLevel
);
372 DebugMsg (NULL
, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv
[1]);
378 mUtilityFilename
= argv
[0];
384 // Open the file containing the FV
386 if (mUtilityFilename
== NULL
) {
387 Error (NULL
, 0, 1001, "Missing option", "Input files are not specified");
388 return GetUtilityStatus ();
390 InputFile
= fopen (LongFilePath (mUtilityFilename
), "rb");
391 if (InputFile
== NULL
) {
392 Error (NULL
, 0, 0001, "Error opening the input file", mUtilityFilename
);
393 return GetUtilityStatus ();
396 // Skip over pad bytes if specified. This is used if they prepend 0xff
397 // data to the FV image binary.
400 fseek (InputFile
, Offset
, SEEK_SET
);
403 // Determine size of FV
405 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
406 if (EFI_ERROR (Status
)) {
407 Error (NULL
, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename
);
409 return GetUtilityStatus ();
412 // Allocate a buffer for the FV image
414 FvImage
= malloc (FvSize
);
415 if (FvImage
== NULL
) {
416 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
418 return GetUtilityStatus ();
421 // Seek to the start of the image, then read the entire FV to the buffer
423 fseek (InputFile
, Offset
, SEEK_SET
);
424 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
426 if ((unsigned int) BytesRead
!= FvSize
) {
427 Error (NULL
, 0, 0004, "error reading FvImage from", mUtilityFilename
);
429 return GetUtilityStatus ();
432 LoadGuidedSectionToolsTxt (mUtilityFilename
);
434 PrintFvInfo (FvImage
, FALSE
);
440 FreeGuidBaseNameList ();
441 return GetUtilityStatus ();
455 GC_TODO: Add function description
459 Fv - Firmware Volume to print information about
460 IsChildFv - Flag specifies whether the input FV is a child FV.
470 BOOLEAN ErasePolarity
;
472 EFI_FFS_FILE_HEADER
*CurrentFile
;
475 Status
= FvBufGetSize (Fv
, &FvSize
);
479 (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) ?
483 // Get the first file
486 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
487 if (EFI_ERROR (Status
)) {
488 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
489 return GetUtilityStatus ();
492 // Display information about files found
494 while (CurrentFile
!= NULL
) {
496 // Increment the number of files counter
501 // Display info about this file
503 Status
= PrintFileInfo (Fv
, CurrentFile
, ErasePolarity
);
504 if (EFI_ERROR (Status
)) {
505 Error (NULL
, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
506 return GetUtilityStatus ();
511 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
512 if (Status
== EFI_NOT_FOUND
) {
514 } else if (EFI_ERROR (Status
)) {
515 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
516 return GetUtilityStatus ();
521 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles
);
523 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles
);
531 IN UINT32 ActualSize
,
538 This function returns the next larger size that meets the alignment
539 requirement specified.
544 Alignment The desired alignment.
548 EFI_SUCCESS Function completed successfully.
549 EFI_ABORTED The function encountered an error.
555 OccupiedSize
= ActualSize
;
556 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
566 IN EFI_SECTION_TYPE Type
572 Converts EFI Section names to Strings
576 Type - The EFI Section type
580 CHAR8* - Pointer to the String containing the section name.
585 CHAR8
*SectionTypeStringTable
[] = {
593 "EFI_SECTION_COMPRESSION",
597 "EFI_SECTION_GUID_DEFINED",
601 "Unknown section type - Reserved 0x03",
605 "Unknown section type - Reserved 0x04",
609 "Unknown section type - Reserved 0x05",
613 "Unknown section type - Reserved 0x06",
617 "Unknown section type - Reserved 0x07",
621 "Unknown section type - Reserved 0x08",
625 "Unknown section type - Reserved 0x09",
629 "Unknown section type - Reserved 0x0A",
633 "Unknown section type - Reserved 0x0B",
637 "Unknown section type - Reserved 0x0C",
641 "Unknown section type - Reserved 0x0D",
645 "Unknown section type - Reserved 0x0E",
649 "Unknown section type - Reserved 0x0E",
665 "EFI_SECTION_DXE_DEPEX",
669 "EFI_SECTION_VERSION",
673 "EFI_SECTION_USER_INTERFACE",
677 "EFI_SECTION_COMPATIBILITY16",
681 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
685 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
693 "Unknown section type - 0x1A",
697 "EFI_SECTION_PEI_DEPEX",
701 "EFI_SECTION_SMM_DEPEX",
705 "Unknown section type - Reserved - beyond last defined section"
708 if (Type
> EFI_SECTION_LAST_SECTION_TYPE
) {
709 Type
= EFI_SECTION_LAST_SECTION_TYPE
+ 1;
712 SectionStr
= malloc (100);
713 if (SectionStr
== NULL
) {
714 printf ("Error: Out of memory resources.\n");
717 strcpy (SectionStr
, SectionTypeStringTable
[Type
]);
726 OUT BOOLEAN
*ErasePolarity
732 This function determines the size of the FV and the erase polarity. The
733 erase polarity is the FALSE value for file state.
737 InputFile The file that contains the FV image.
738 FvSize The size of the FV.
739 ErasePolarity The FV erase polarity.
743 EFI_SUCCESS Function completed successfully.
744 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
745 EFI_ABORTED The function encountered an error.
749 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
750 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
758 // Check input parameters
760 if (InputFile
== NULL
|| FvSize
== NULL
|| ErasePolarity
== NULL
) {
761 Error (__FILE__
, __LINE__
, 0, "application error", "invalid parameter to function");
762 return EFI_INVALID_PARAMETER
;
767 fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
768 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
769 Signature
[0] = VolumeHeader
.Signature
;
773 // Print FV header information
775 printf ("Signature: %s (%X)\n", (char *) Signature
, (unsigned) VolumeHeader
.Signature
);
776 printf ("Attributes: %X\n", (unsigned) VolumeHeader
.Attributes
);
778 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_DISABLED_CAP
) {
779 printf (" EFI_FVB2_READ_DISABLED_CAP\n");
782 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_ENABLED_CAP
) {
783 printf (" EFI_FVB2_READ_ENABLED_CAP\n");
786 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_STATUS
) {
787 printf (" EFI_FVB2_READ_STATUS\n");
790 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_DISABLED_CAP
) {
791 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
794 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_ENABLED_CAP
) {
795 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
798 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_STATUS
) {
799 printf (" EFI_FVB2_WRITE_STATUS\n");
802 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_CAP
) {
803 printf (" EFI_FVB2_LOCK_CAP\n");
806 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_STATUS
) {
807 printf (" EFI_FVB2_LOCK_STATUS\n");
810 if (VolumeHeader
.Attributes
& EFI_FVB2_STICKY_WRITE
) {
811 printf (" EFI_FVB2_STICKY_WRITE\n");
814 if (VolumeHeader
.Attributes
& EFI_FVB2_MEMORY_MAPPED
) {
815 printf (" EFI_FVB2_MEMORY_MAPPED\n");
818 if (VolumeHeader
.Attributes
& EFI_FVB2_ERASE_POLARITY
) {
819 printf (" EFI_FVB2_ERASE_POLARITY\n");
820 *ErasePolarity
= TRUE
;
823 #if (PI_SPECIFICATION_VERSION < 0x00010000)
824 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
825 printf (" EFI_FVB2_ALIGNMENT\n");
828 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
829 printf (" EFI_FVB2_ALIGNMENT_2\n");
832 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
833 printf (" EFI_FVB2_ALIGNMENT_4\n");
836 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
837 printf (" EFI_FVB2_ALIGNMENT_8\n");
840 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
841 printf (" EFI_FVB2_ALIGNMENT_16\n");
844 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
845 printf (" EFI_FVB2_ALIGNMENT_32\n");
848 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
849 printf (" EFI_FVB2_ALIGNMENT_64\n");
852 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
853 printf (" EFI_FVB2_ALIGNMENT_128\n");
856 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
857 printf (" EFI_FVB2_ALIGNMENT_256\n");
860 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
861 printf (" EFI_FVB2_ALIGNMENT_512\n");
864 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
865 printf (" EFI_FVB2_ALIGNMENT_1K\n");
868 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
869 printf (" EFI_FVB2_ALIGNMENT_2K\n");
872 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
873 printf (" EFI_FVB2_ALIGNMENT_4K\n");
876 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
877 printf (" EFI_FVB2_ALIGNMENT_8K\n");
880 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
881 printf (" EFI_FVB2_ALIGNMENT_16K\n");
884 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
885 printf (" EFI_FVB2_ALIGNMENT_32K\n");
888 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
889 printf (" EFI_FVB2_ALIGNMENT_64K\n");
894 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_CAP
) {
895 printf (" EFI_FVB2_READ_LOCK_CAP\n");
898 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_STATUS
) {
899 printf (" EFI_FVB2_READ_LOCK_STATUS\n");
902 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_CAP
) {
903 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
906 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_STATUS
) {
907 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
910 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1
) {
911 printf (" EFI_FVB2_ALIGNMENT_1\n");
914 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
915 printf (" EFI_FVB2_ALIGNMENT_2\n");
918 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
919 printf (" EFI_FVB2_ALIGNMENT_4\n");
922 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
923 printf (" EFI_FVB2_ALIGNMENT_8\n");
926 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
927 printf (" EFI_FVB2_ALIGNMENT_16\n");
930 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
931 printf (" EFI_FVB2_ALIGNMENT_32\n");
934 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
935 printf (" EFI_FVB2_ALIGNMENT_64\n");
938 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
939 printf (" EFI_FVB2_ALIGNMENT_128\n");
942 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
943 printf (" EFI_FVB2_ALIGNMENT_256\n");
946 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
947 printf (" EFI_FVB2_ALIGNMENT_512\n");
950 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
951 printf (" EFI_FVB2_ALIGNMENT_1K\n");
954 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
955 printf (" EFI_FVB2_ALIGNMENT_2K\n");
958 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
959 printf (" EFI_FVB2_ALIGNMENT_4K\n");
962 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
963 printf (" EFI_FVB2_ALIGNMENT_8K\n");
966 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
967 printf (" EFI_FVB2_ALIGNMENT_16K\n");
970 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
971 printf (" EFI_FVB2_ALIGNMENT_32K\n");
974 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
975 printf (" EFI_FVB2_ALIGNMENT_64K\n");
978 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128K
) {
979 printf (" EFI_FVB2_ALIGNMENT_128K\n");
982 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256K
) {
983 printf (" EFI_FVB2_ALIGNMENT_256K\n");
986 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512K
) {
987 printf (" EFI_FVB2_ALIGNMENT_512K\n");
990 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1M
) {
991 printf (" EFI_FVB2_ALIGNMENT_1M\n");
994 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2M
) {
995 printf (" EFI_FVB2_ALIGNMENT_2M\n");
998 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4M
) {
999 printf (" EFI_FVB2_ALIGNMENT_4M\n");
1002 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8M
) {
1003 printf (" EFI_FVB2_ALIGNMENT_8M\n");
1006 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16M
) {
1007 printf (" EFI_FVB2_ALIGNMENT_16M\n");
1010 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32M
) {
1011 printf (" EFI_FVB2_ALIGNMENT_32M\n");
1014 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
1015 printf (" EFI_FVB2_ALIGNMENT_64M\n");
1018 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
1019 printf (" EFI_FVB2_ALIGNMENT_128M\n");
1022 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
1023 printf (" EFI_FVB2_ALIGNMENT_64M\n");
1026 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
1027 printf (" EFI_FVB2_ALIGNMENT_128M\n");
1030 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256M
) {
1031 printf (" EFI_FVB2_ALIGNMENT_256M\n");
1034 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512M
) {
1035 printf (" EFI_FVB2_ALIGNMENT_512M\n");
1038 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1G
) {
1039 printf (" EFI_FVB2_ALIGNMENT_1G\n");
1042 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2G
) {
1043 printf (" EFI_FVB2_ALIGNMENT_2G\n");
1047 printf ("Header Length: 0x%08X\n", VolumeHeader
.HeaderLength
);
1048 printf ("File System ID: ");
1049 PrintGuid (&VolumeHeader
.FileSystemGuid
);
1053 printf ("Revision: 0x%04X\n", VolumeHeader
.Revision
);
1056 fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
1057 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
1059 if (BlockMap
.NumBlocks
!= 0) {
1060 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap
.NumBlocks
);
1061 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap
.Length
);
1062 Size
+= BlockMap
.NumBlocks
* BlockMap
.Length
;
1065 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.Length
== 0));
1067 if (BytesRead
!= VolumeHeader
.HeaderLength
) {
1068 printf ("ERROR: Header length not consistent with Block Maps!\n");
1072 if (VolumeHeader
.FvLength
!= Size
) {
1073 printf ("ERROR: Volume Size not consistant with Block Maps!\n");
1077 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size
);
1082 // rewind (InputFile);
1090 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
1091 EFI_FFS_FILE_HEADER
*FileHeader
,
1092 BOOLEAN ErasePolarity
1096 Routine Description:
1098 GC_TODO: Add function description
1102 FvImage - GC_TODO: add argument description
1103 FileHeader - GC_TODO: add argument description
1104 ErasePolarity - GC_TODO: add argument description
1108 EFI_SUCCESS - GC_TODO: Add description for return value
1109 EFI_ABORTED - GC_TODO: Add description for return value
1116 EFI_FFS_FILE_HEADER2 BlankHeader
;
1118 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1120 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1124 // Check if we have free space
1126 HeaderSize
= FvBufGetFfsHeaderSize(FileHeader
);
1127 if (ErasePolarity
) {
1128 memset (&BlankHeader
, -1, HeaderSize
);
1130 memset (&BlankHeader
, 0, HeaderSize
);
1133 if (memcmp (&BlankHeader
, FileHeader
, HeaderSize
) == 0) {
1137 // Print file information.
1139 printf ("============================================================\n");
1141 printf ("File Name: ");
1142 PrintGuidToBuffer (&FileHeader
->Name
, GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
1143 printf ("%s ", GuidBuffer
);
1144 PrintGuidName (GuidBuffer
);
1148 // PrintGuid (&FileHeader->Name);
1151 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1152 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN
) FileHeader
- (UINTN
) FvImage
));
1153 printf ("File Length: 0x%08X\n", (unsigned) FileLength
);
1154 printf ("File Attributes: 0x%02X\n", FileHeader
->Attributes
);
1155 printf ("File State: 0x%02X\n", FileHeader
->State
);
1160 FileState
= GetFileState (ErasePolarity
, FileHeader
);
1162 switch (FileState
) {
1164 case EFI_FILE_HEADER_CONSTRUCTION
:
1165 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
1168 case EFI_FILE_HEADER_INVALID
:
1169 printf (" EFI_FILE_HEADER_INVALID\n");
1172 case EFI_FILE_HEADER_VALID
:
1173 printf (" EFI_FILE_HEADER_VALID\n");
1174 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1175 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1176 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1177 if (Checksum
!= 0) {
1178 printf ("ERROR: Header checksum invalid.\n");
1184 case EFI_FILE_DELETED
:
1185 printf (" EFI_FILE_DELETED\n");
1187 case EFI_FILE_MARKED_FOR_UPDATE
:
1188 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
1190 case EFI_FILE_DATA_VALID
:
1191 printf (" EFI_FILE_DATA_VALID\n");
1194 // Calculate header checksum
1196 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, HeaderSize
);
1197 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1198 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1199 if (Checksum
!= 0) {
1200 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer
);
1204 FileLength
= FvBufGetFfsFileSize (FileHeader
);
1206 if (FileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
1208 // Calculate file checksum
1210 Checksum
= CalculateSum8 ((UINT8
*)FileHeader
+ HeaderSize
, FileLength
- HeaderSize
);
1211 Checksum
= Checksum
+ FileHeader
->IntegrityCheck
.Checksum
.File
;
1212 if (Checksum
!= 0) {
1213 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer
);
1217 if (FileHeader
->IntegrityCheck
.Checksum
.File
!= FFS_FIXED_CHECKSUM
) {
1218 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
);
1222 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1224 // Verify tail if present
1226 if (FileHeader
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
1228 // Verify tail is complement of integrity check field in the header.
1230 Tail
= (UINT16
*) ((UINTN
) FileHeader
+ GetLength (FileHeader
->Size
) - sizeof (EFI_FFS_INTEGRITY_CHECK
));
1231 if (FileHeader
->IntegrityCheck
.TailReference
!= (UINT16
)~(*Tail
)) {
1232 Error (NULL
, 0, 0003, "error parsing FFS file", \
1233 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer
);
1241 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer
);
1245 printf ("File Type: 0x%02X ", FileHeader
->Type
);
1247 switch (FileHeader
->Type
) {
1249 case EFI_FV_FILETYPE_RAW
:
1250 printf ("EFI_FV_FILETYPE_RAW\n");
1253 case EFI_FV_FILETYPE_FREEFORM
:
1254 printf ("EFI_FV_FILETYPE_FREEFORM\n");
1257 case EFI_FV_FILETYPE_SECURITY_CORE
:
1258 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
1261 case EFI_FV_FILETYPE_PEI_CORE
:
1262 printf ("EFI_FV_FILETYPE_PEI_CORE\n");
1265 case EFI_FV_FILETYPE_DXE_CORE
:
1266 printf ("EFI_FV_FILETYPE_DXE_CORE\n");
1269 case EFI_FV_FILETYPE_PEIM
:
1270 printf ("EFI_FV_FILETYPE_PEIM\n");
1273 case EFI_FV_FILETYPE_DRIVER
:
1274 printf ("EFI_FV_FILETYPE_DRIVER\n");
1277 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
1278 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
1281 case EFI_FV_FILETYPE_APPLICATION
:
1282 printf ("EFI_FV_FILETYPE_APPLICATION\n");
1285 case EFI_FV_FILETYPE_SMM
:
1286 printf ("EFI_FV_FILETYPE_SMM\n");
1289 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
:
1290 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1293 case EFI_FV_FILETYPE_COMBINED_SMM_DXE
:
1294 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
1297 case EFI_FV_FILETYPE_SMM_CORE
:
1298 printf ("EFI_FV_FILETYPE_SMM_CORE\n");
1301 case EFI_FV_FILETYPE_MM_STANDALONE
:
1302 printf ("EFI_FV_FILETYPE_MM_STANDALONE\n");
1305 case EFI_FV_FILETYPE_MM_CORE_STANDALONE
:
1306 printf ("EFI_FV_FILETYPE_MM_CORE_STANDALONE\n");
1309 case EFI_FV_FILETYPE_FFS_PAD
:
1310 printf ("EFI_FV_FILETYPE_FFS_PAD\n");
1314 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader
->Type
);
1319 switch (FileHeader
->Type
) {
1321 case EFI_FV_FILETYPE_ALL
:
1322 case EFI_FV_FILETYPE_RAW
:
1323 case EFI_FV_FILETYPE_FFS_PAD
:
1328 // All other files have sections
1330 Status
= ParseSection (
1331 (UINT8
*) ((UINTN
) FileHeader
+ HeaderSize
),
1332 FvBufGetFfsFileSize (FileHeader
) - HeaderSize
1334 if (EFI_ERROR (Status
)) {
1336 // printf ("ERROR: Parsing the FFS file.\n");
1348 IN VOID
*FileHandle
,
1349 IN UINTN FileOffset
,
1350 IN OUT UINT32
*ReadSize
,
1355 Routine Description:
1357 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
1361 FileHandle - The handle to the PE/COFF file
1363 FileOffset - The offset, in bytes, into the file to read
1365 ReadSize - The number of bytes to read from the file starting at FileOffset
1367 Buffer - A pointer to the buffer to read the data into.
1371 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1375 CHAR8
*Destination8
;
1379 Destination8
= Buffer
;
1380 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
1383 *(Destination8
++) = *(Source8
++);
1390 SetAddressToSectionHeader (
1392 IN OUT UINT8
*FileBuffer
,
1393 IN UINT64 NewPe32BaseAddress
1397 Routine Description:
1399 Set new base address into the section header of PeImage
1403 FileName - Name of file
1404 FileBuffer - Pointer to PeImage.
1405 NewPe32BaseAddress - New Base Address for PE image.
1409 EFI_SUCCESS Set new base address into this image successfully.
1414 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1416 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1417 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1420 // Initialize context
1422 memset (&ImageContext
, 0, sizeof (ImageContext
));
1423 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1424 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1425 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1426 if (EFI_ERROR (Status
)) {
1427 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1431 if (ImageContext
.RelocationsStripped
) {
1432 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1437 // Get PeHeader pointer
1439 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1442 // Get section header list
1444 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1447 sizeof (EFI_IMAGE_FILE_HEADER
) +
1448 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1452 // Set base address into the first section header that doesn't point to code section.
1454 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1455 if ((SectionHeader
->Characteristics
& EFI_IMAGE_SCN_CNT_CODE
) == 0) {
1456 *(UINT64
*) &SectionHeader
->PointerToRelocations
= NewPe32BaseAddress
;
1462 // BaseAddress is set to section header.
1470 IN OUT UINT8
*FileBuffer
,
1471 IN UINT64 NewPe32BaseAddress
1475 Routine Description:
1477 Set new base address into PeImage, and fix up PeImage based on new address.
1481 FileName - Name of file
1482 FileBuffer - Pointer to PeImage.
1483 NewPe32BaseAddress - New Base Address for PE image.
1487 EFI_INVALID_PARAMETER - BaseAddress is not valid.
1488 EFI_SUCCESS - Update PeImage is correctly.
1493 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
1495 EFI_IMAGE_OPTIONAL_HEADER_UNION
*ImgHdr
;
1496 UINT8
*MemoryImagePointer
;
1497 EFI_IMAGE_SECTION_HEADER
*SectionHeader
;
1500 // Initialize context
1502 memset (&ImageContext
, 0, sizeof (ImageContext
));
1503 ImageContext
.Handle
= (VOID
*) FileBuffer
;
1504 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) RebaseImageRead
;
1505 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
1506 if (EFI_ERROR (Status
)) {
1507 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName
);
1511 if (ImageContext
.RelocationsStripped
) {
1512 Error (NULL
, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName
);
1517 // Get PeHeader pointer
1519 ImgHdr
= (EFI_IMAGE_OPTIONAL_HEADER_UNION
*)(FileBuffer
+ ImageContext
.PeCoffHeaderOffset
);
1522 // Load and Relocate Image Data
1524 MemoryImagePointer
= (UINT8
*) malloc ((UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1525 if (MemoryImagePointer
== NULL
) {
1526 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName
);
1527 return EFI_OUT_OF_RESOURCES
;
1529 memset ((VOID
*) MemoryImagePointer
, 0, (UINTN
) ImageContext
.ImageSize
+ ImageContext
.SectionAlignment
);
1530 ImageContext
.ImageAddress
= ((UINTN
) MemoryImagePointer
+ ImageContext
.SectionAlignment
- 1) & (~((INT64
)ImageContext
.SectionAlignment
- 1));
1532 Status
= PeCoffLoaderLoadImage (&ImageContext
);
1533 if (EFI_ERROR (Status
)) {
1534 Error (NULL
, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName
);
1535 free ((VOID
*) MemoryImagePointer
);
1539 ImageContext
.DestinationAddress
= NewPe32BaseAddress
;
1540 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
1541 if (EFI_ERROR (Status
)) {
1542 Error (NULL
, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName
);
1543 free ((VOID
*) MemoryImagePointer
);
1548 // Copy Relocated data to raw image file.
1550 SectionHeader
= (EFI_IMAGE_SECTION_HEADER
*) (
1553 sizeof (EFI_IMAGE_FILE_HEADER
) +
1554 ImgHdr
->Pe32
.FileHeader
.SizeOfOptionalHeader
1557 for (Index
= 0; Index
< ImgHdr
->Pe32
.FileHeader
.NumberOfSections
; Index
++, SectionHeader
++) {
1559 FileBuffer
+ SectionHeader
->PointerToRawData
,
1560 (VOID
*) (UINTN
) (ImageContext
.ImageAddress
+ SectionHeader
->VirtualAddress
),
1561 SectionHeader
->SizeOfRawData
1565 free ((VOID
*) MemoryImagePointer
);
1568 // Update Image Base Address
1570 if (ImgHdr
->Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1571 ImgHdr
->Pe32
.OptionalHeader
.ImageBase
= (UINT32
) NewPe32BaseAddress
;
1572 } else if (ImgHdr
->Pe32Plus
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
1573 ImgHdr
->Pe32Plus
.OptionalHeader
.ImageBase
= NewPe32BaseAddress
;
1575 Error (NULL
, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
1576 ImgHdr
->Pe32
.OptionalHeader
.Magic
,
1583 // Set new base address into section header
1585 Status
= SetAddressToSectionHeader (FileName
, FileBuffer
, NewPe32BaseAddress
);
1592 IN CHAR8
* DefaultPath
,
1593 IN CHAR8
* AppendPath
,
1597 UINT32 DefaultPathLen
;
1599 CHAR8 QuotesStr
[] = "\"";
1600 strcpy(NewPath
, QuotesStr
);
1601 DefaultPathLen
= strlen(DefaultPath
);
1602 strcat(NewPath
, DefaultPath
);
1604 for (; Index
< DefaultPathLen
+ 1; Index
++) {
1605 if (NewPath
[Index
] == '\\' || NewPath
[Index
] == '/') {
1606 if (NewPath
[Index
+ 1] != '\0') {
1607 NewPath
[Index
] = '/';
1611 if (NewPath
[Index
-1] != '/') {
1612 NewPath
[Index
] = '/';
1613 NewPath
[Index
+ 1] = '\0';
1615 strcat(NewPath
, AppendPath
);
1616 strcat(NewPath
, QuotesStr
);
1622 IN UINT8
*SectionBuffer
,
1623 IN UINT32 BufferLength
1627 Routine Description:
1633 SectionBuffer - Buffer containing the section to parse.
1634 BufferLength - Length of SectionBuffer
1638 EFI_SECTION_ERROR - Problem with section parsing.
1639 (a) compression errors
1640 (b) unrecognized section
1641 EFI_UNSUPPORTED - Do not know how to parse the section.
1642 EFI_SUCCESS - Section successfully parsed.
1643 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1647 EFI_SECTION_TYPE Type
;
1649 UINT32 SectionLength
;
1650 UINT32 SectionHeaderLen
;
1653 UINT32 ParsedLength
;
1654 UINT8
*CompressedBuffer
;
1655 UINT32 CompressedLength
;
1656 UINT8
*UncompressedBuffer
;
1657 UINT32 UncompressedLength
;
1658 UINT8
*ToolOutputBuffer
;
1659 UINT32 ToolOutputLength
;
1660 UINT8 CompressionType
;
1663 UINT8
*ScratchBuffer
;
1664 DECOMPRESS_FUNCTION DecompressFunction
;
1665 GETINFO_FUNCTION GetInfoFunction
;
1667 CHAR8
*ExtractionTool
;
1668 CHAR8
*ToolInputFile
;
1669 CHAR8
*ToolOutputFile
;
1670 CHAR8
*SystemCommand
;
1675 CHAR8
*ToolInputFileName
;
1676 CHAR8
*ToolOutputFileName
;
1680 ToolInputFileName
= NULL
;
1681 ToolOutputFileName
= NULL
;
1683 while (ParsedLength
< BufferLength
) {
1684 Ptr
= SectionBuffer
+ ParsedLength
;
1686 SectionLength
= GetLength (((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Size
);
1687 Type
= ((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Type
;
1690 // This is sort of an odd check, but is necessary because FFS files are
1691 // padded to a QWORD boundary, meaning there is potentially a whole section
1692 // header worth of 0xFF bytes.
1694 if (SectionLength
== 0xffffff && Type
== 0xff) {
1700 // Get real section file size
1702 SectionLength
= GetSectionFileLength ((EFI_COMMON_SECTION_HEADER
*) Ptr
);
1703 SectionHeaderLen
= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
1705 SectionName
= SectionNameToStr (Type
);
1706 if (SectionName
!= NULL
) {
1707 printf ("------------------------------------------------------------\n");
1708 printf (" Type: %s\n Size: 0x%08X\n", SectionName
, (unsigned) SectionLength
);
1713 case EFI_SECTION_RAW
:
1714 case EFI_SECTION_PIC
:
1715 case EFI_SECTION_TE
:
1716 // default is no more information
1719 case EFI_SECTION_PE32
:
1721 ToolInputFileName
= "edk2Temp_InputEfi.tmp";
1722 ToolOutputFileName
= "edk2Temp_OutputHash.tmp";
1723 RebaseImage(ToolInputFileName
, (UINT8
*)Ptr
+ SectionHeaderLen
, 0);
1726 (CHAR8
*)Ptr
+ SectionHeaderLen
,
1727 SectionLength
- SectionHeaderLen
1730 SystemCommand
= malloc (
1731 strlen (OPENSSL_COMMAND_FORMAT_STRING
) +
1732 strlen (OpenSslPath
) +
1733 strlen (ToolInputFileName
) +
1734 strlen (ToolOutputFileName
) +
1737 if (SystemCommand
== NULL
) {
1738 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1739 return EFI_OUT_OF_RESOURCES
;
1743 OPENSSL_COMMAND_FORMAT_STRING
,
1749 if (system (SystemCommand
) != EFI_SUCCESS
) {
1750 Error (NULL
, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL
);
1757 if((fp
= fopen(ToolOutputFileName
,"r")) == NULL
) {
1758 Error (NULL
, 0, 0004, "Hash the PE32 image failed.", NULL
);
1761 fseek(fp
,0,SEEK_SET
);
1762 fseek(fp
,0,SEEK_END
);
1763 nFileLen
= ftell(fp
);
1764 fseek(fp
,0,SEEK_SET
);
1765 StrLine
= malloc(nFileLen
);
1766 if (StrLine
== NULL
) {
1768 free (SystemCommand
);
1769 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1770 return EFI_OUT_OF_RESOURCES
;
1772 fgets(StrLine
, nFileLen
, fp
);
1773 NewStr
= strrchr (StrLine
, '=');
1774 printf (" SHA1: %s\n", NewStr
+ 1);
1779 remove(ToolInputFileName
);
1780 remove(ToolOutputFileName
);
1781 free (SystemCommand
);
1785 case EFI_SECTION_USER_INTERFACE
:
1786 UIFileName
= (CHAR8
*) malloc (UnicodeStrLen (((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
) + 1);
1787 if (UIFileName
== NULL
) {
1788 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1789 return EFI_OUT_OF_RESOURCES
;
1791 Unicode2AsciiString (((EFI_USER_INTERFACE_SECTION
*) Ptr
)->FileNameString
, UIFileName
);
1792 printf (" String: %s\n", UIFileName
);
1796 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
1797 Status
= PrintFvInfo (Ptr
+ SectionHeaderLen
, TRUE
);
1798 if (EFI_ERROR (Status
)) {
1799 Error (NULL
, 0, 0003, "printing of FV section contents failed", NULL
);
1800 return EFI_SECTION_ERROR
;
1804 case EFI_SECTION_COMPATIBILITY16
:
1805 case EFI_SECTION_FREEFORM_SUBTYPE_GUID
:
1807 // Section does not contain any further header information.
1811 case EFI_SECTION_PEI_DEPEX
:
1812 case EFI_SECTION_DXE_DEPEX
:
1813 case EFI_SECTION_SMM_DEPEX
:
1814 DumpDepexSection (Ptr
, SectionLength
);
1817 case EFI_SECTION_VERSION
:
1818 printf (" Build Number: 0x%02X\n", *(UINT16
*)(Ptr
+ SectionHeaderLen
));
1819 printf (" Version Strg: %s\n", (char*) (Ptr
+ SectionHeaderLen
+ sizeof (UINT16
)));
1822 case EFI_SECTION_COMPRESSION
:
1823 UncompressedBuffer
= NULL
;
1824 if (SectionHeaderLen
== sizeof (EFI_COMMON_SECTION_HEADER
)) {
1825 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION
);
1826 UncompressedLength
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->UncompressedLength
;
1827 CompressionType
= ((EFI_COMPRESSION_SECTION
*)Ptr
)->CompressionType
;
1829 RealHdrLen
= sizeof(EFI_COMPRESSION_SECTION2
);
1830 UncompressedLength
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->UncompressedLength
;
1831 CompressionType
= ((EFI_COMPRESSION_SECTION2
*)Ptr
)->CompressionType
;
1833 CompressedLength
= SectionLength
- RealHdrLen
;
1834 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength
);
1836 if (CompressionType
== EFI_NOT_COMPRESSED
) {
1837 printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1838 if (CompressedLength
!= UncompressedLength
) {
1843 "file is not compressed, but the compressed length does not match the uncompressed length",
1846 return EFI_SECTION_ERROR
;
1849 UncompressedBuffer
= Ptr
+ RealHdrLen
;
1850 } else if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1851 GetInfoFunction
= EfiGetInfo
;
1852 DecompressFunction
= EfiDecompress
;
1853 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
1855 CompressedBuffer
= Ptr
+ RealHdrLen
;
1857 Status
= GetInfoFunction (CompressedBuffer
, CompressedLength
, &DstSize
, &ScratchSize
);
1858 if (EFI_ERROR (Status
)) {
1859 Error (NULL
, 0, 0003, "error getting compression info from compression section", NULL
);
1860 return EFI_SECTION_ERROR
;
1863 if (DstSize
!= UncompressedLength
) {
1864 Error (NULL
, 0, 0003, "compression error in the compression section", NULL
);
1865 return EFI_SECTION_ERROR
;
1868 ScratchBuffer
= malloc (ScratchSize
);
1869 if (ScratchBuffer
== NULL
) {
1870 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1871 return EFI_OUT_OF_RESOURCES
;
1873 UncompressedBuffer
= malloc (UncompressedLength
);
1874 if (UncompressedBuffer
== NULL
) {
1875 free (ScratchBuffer
);
1876 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1877 return EFI_OUT_OF_RESOURCES
;
1879 Status
= DecompressFunction (
1887 free (ScratchBuffer
);
1888 if (EFI_ERROR (Status
)) {
1889 Error (NULL
, 0, 0003, "decompress failed", NULL
);
1890 free (UncompressedBuffer
);
1891 return EFI_SECTION_ERROR
;
1894 Error (NULL
, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType
);
1895 return EFI_SECTION_ERROR
;
1898 Status
= ParseSection (UncompressedBuffer
, UncompressedLength
);
1900 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1902 // We need to deallocate Buffer
1904 free (UncompressedBuffer
);
1907 if (EFI_ERROR (Status
)) {
1908 Error (NULL
, 0, 0003, "failed to parse section", NULL
);
1909 return EFI_SECTION_ERROR
;
1913 case EFI_SECTION_GUID_DEFINED
:
1914 if (SectionHeaderLen
== sizeof(EFI_COMMON_SECTION_HEADER
)) {
1915 EfiGuid
= &((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
;
1916 DataOffset
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
;
1917 Attributes
= ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->Attributes
;
1919 EfiGuid
= &((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->SectionDefinitionGuid
;
1920 DataOffset
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->DataOffset
;
1921 Attributes
= ((EFI_GUID_DEFINED_SECTION2
*) Ptr
)->Attributes
;
1923 printf (" SectionDefinitionGuid: ");
1924 PrintGuid (EfiGuid
);
1926 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset
);
1927 printf (" Attributes: 0x%04X\n", (unsigned) Attributes
);
1930 LookupGuidedSectionToolPath (
1931 mParsedGuidedSectionTools
,
1935 if (ExtractionTool
!= NULL
) {
1937 ToolInputFile
= CloneString (tmpnam (NULL
));
1938 ToolOutputFile
= CloneString (tmpnam (NULL
));
1940 char tmp1
[] = "/tmp/fileXXXXXX";
1941 char tmp2
[] = "/tmp/fileXXXXXX";
1944 fd1
= mkstemp(tmp1
);
1945 fd2
= mkstemp(tmp2
);
1946 ToolInputFile
= CloneString(tmp1
);
1947 ToolOutputFile
= CloneString(tmp2
);
1952 if ((ToolInputFile
== NULL
) || (ToolOutputFile
== NULL
)) {
1953 if (ToolInputFile
!= NULL
) {
1954 free (ToolInputFile
);
1956 if (ToolOutputFile
!= NULL
) {
1957 free (ToolOutputFile
);
1959 free (ExtractionTool
);
1961 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1962 return EFI_OUT_OF_RESOURCES
;
1966 // Construction 'system' command string
1968 SystemCommand
= malloc (
1969 strlen (EXTRACT_COMMAND_FORMAT_STRING
) +
1970 strlen (ExtractionTool
) +
1971 strlen (ToolInputFile
) +
1972 strlen (ToolOutputFile
) +
1975 if (SystemCommand
== NULL
) {
1976 free (ToolInputFile
);
1977 free (ToolOutputFile
);
1978 free (ExtractionTool
);
1980 Error (NULL
, 0, 4001, "Resource", "memory cannot be allocated!");
1981 return EFI_OUT_OF_RESOURCES
;
1985 EXTRACT_COMMAND_FORMAT_STRING
,
1990 free (ExtractionTool
);
1995 (CHAR8
*) SectionBuffer
+ DataOffset
,
1996 BufferLength
- DataOffset
1999 system (SystemCommand
);
2000 remove (ToolInputFile
);
2001 free (ToolInputFile
);
2006 (CHAR8
**)&ToolOutputBuffer
,
2009 remove (ToolOutputFile
);
2010 free (ToolOutputFile
);
2011 free (SystemCommand
);
2012 if (EFI_ERROR (Status
)) {
2013 Error (NULL
, 0, 0004, "unable to read decoded GUIDED section", NULL
);
2014 return EFI_SECTION_ERROR
;
2017 Status
= ParseSection (
2021 if (EFI_ERROR (Status
)) {
2022 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
2023 return EFI_SECTION_ERROR
;
2027 // Check for CRC32 sections which we can handle internally if needed.
2029 } else if (!CompareGuid (
2031 &gEfiCrc32GuidedSectionExtractionProtocolGuid
2035 // CRC32 guided section
2037 Status
= ParseSection (
2038 SectionBuffer
+ DataOffset
,
2039 BufferLength
- DataOffset
2041 if (EFI_ERROR (Status
)) {
2042 Error (NULL
, 0, 0003, "parse of CRC32 GUIDED section failed", NULL
);
2043 return EFI_SECTION_ERROR
;
2047 // We don't know how to parse it now.
2049 Error (NULL
, 0, 0003, "Error parsing section", \
2050 "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).");
2051 return EFI_UNSUPPORTED
;
2057 // Unknown section, return error
2059 Error (NULL
, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type
);
2060 return EFI_SECTION_ERROR
;
2063 ParsedLength
+= SectionLength
;
2065 // We make then next section begin on a 4-byte boundary
2067 ParsedLength
= GetOccupiedSize (ParsedLength
, 4);
2070 if (ParsedLength
< BufferLength
) {
2071 Error (NULL
, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL
);
2072 return EFI_SECTION_ERROR
;
2081 IN UINT32 SectionLength
2085 Routine Description:
2087 GC_TODO: Add function description
2091 Ptr - GC_TODO: add argument description
2092 SectionLength - GC_TODO: add argument description
2096 EFI_SUCCESS - GC_TODO: Add description for return value
2100 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
2103 // Need at least a section header + data
2105 if (SectionLength
<= sizeof (EFI_COMMON_SECTION_HEADER
)) {
2109 Ptr
+= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2110 SectionLength
-= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER
*)Ptr
);
2111 while (SectionLength
> 0) {
2114 case EFI_DEP_BEFORE
:
2115 printf ("BEFORE\n");
2128 PrintGuidToBuffer ((EFI_GUID
*) (Ptr
+ 1), GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
2129 printf ("%s ", GuidBuffer
);
2130 PrintGuidName (GuidBuffer
);
2133 // PrintGuid ((EFI_GUID *)(Ptr + 1));
2136 SectionLength
-= 17;
2170 printf ("END DEPEX\n");
2182 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr
);
2196 Routine Description:
2198 GC_TODO: Add function description
2202 GuidStr - GC_TODO: add argument description
2206 EFI_SUCCESS - GC_TODO: Add description for return value
2207 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
2211 GUID_TO_BASENAME
*GPtr
;
2213 // If we have a list of guid-to-basenames, then go through the list to
2214 // look for a guid string match. If found, print the basename to stdout,
2215 // otherwise return a failure.
2217 GPtr
= mGuidBaseNameList
;
2218 while (GPtr
!= NULL
) {
2219 if (_stricmp ((CHAR8
*) GuidStr
, (CHAR8
*) GPtr
->Guid
) == 0) {
2220 printf ("%s", GPtr
->BaseName
);
2227 return EFI_INVALID_PARAMETER
;
2231 ParseGuidBaseNameFile (
2236 Routine Description:
2238 GC_TODO: Add function description
2242 FileName - GC_TODO: add argument description
2246 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
2247 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
2248 EFI_SUCCESS - GC_TODO: Add description for return value
2253 CHAR8 Line
[MAX_LINE_LEN
];
2254 CHAR8 FormatString
[MAX_LINE_LEN
];
2255 GUID_TO_BASENAME
*GPtr
;
2257 if ((Fptr
= fopen (LongFilePath (FileName
), "r")) == NULL
) {
2258 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName
);
2259 return EFI_DEVICE_ERROR
;
2263 // Generate the format string for fscanf
2268 (unsigned) sizeof (GPtr
->Guid
) - 1,
2269 (unsigned) sizeof (GPtr
->BaseName
) - 1
2272 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
2274 // Allocate space for another guid/basename element
2276 GPtr
= malloc (sizeof (GUID_TO_BASENAME
));
2279 return EFI_OUT_OF_RESOURCES
;
2282 memset ((char *) GPtr
, 0, sizeof (GUID_TO_BASENAME
));
2283 if (sscanf (Line
, FormatString
, GPtr
->Guid
, GPtr
->BaseName
) == 2) {
2284 GPtr
->Next
= mGuidBaseNameList
;
2285 mGuidBaseNameList
= GPtr
;
2288 // Some sort of error. Just continue.
2299 FreeGuidBaseNameList (
2304 Routine Description:
2306 GC_TODO: Add function description
2314 EFI_SUCCESS - GC_TODO: Add description for return value
2318 GUID_TO_BASENAME
*Next
;
2320 while (mGuidBaseNameList
!= NULL
) {
2321 Next
= mGuidBaseNameList
->Next
;
2322 free (mGuidBaseNameList
);
2323 mGuidBaseNameList
= Next
;
2332 LoadGuidedSectionToolsTxt (
2333 IN CHAR8
* FirmwareVolumeFilename
2336 CHAR8
* PeerFilename
;
2343 Places
[0] = FirmwareVolumeFilename
;
2344 //Places[1] = mUtilityFilename;
2346 mParsedGuidedSectionTools
= NULL
;
2348 for (Index
= 0; Index
< (sizeof(Places
)/sizeof(Places
[0])); Index
++) {
2349 PeerFilename
= OsPathPeerFilePath (Places
[Index
], "GuidedSectionTools.txt");
2350 //printf("Loading %s...\n", PeerFilename);
2351 if (OsPathExists (PeerFilename
)) {
2352 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (PeerFilename
);
2354 free (PeerFilename
);
2355 if (mParsedGuidedSectionTools
!= NULL
) {
2368 Routine Description:
2370 GC_TODO: Add function description
2378 GC_TODO: add return values
2385 fprintf (stdout
, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME
);
2388 // Copyright declaration
2390 fprintf (stdout
, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
2391 fprintf (stdout
, " Display Tiano Firmware Volume FFS image information\n\n");
2396 fprintf (stdout
, "optional arguments:\n");
2397 fprintf (stdout
, " -h, --help\n\
2398 Show this help message and exit\n");
2399 fprintf (stdout
, " --version\n\
2400 Show program's version number and exit\n");
2401 fprintf (stdout
, " -d [DEBUG], --debug [DEBUG]\n\
2402 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
2403 fprintf (stdout
, " -v, --verbose\n\
2404 Print informational statements\n");
2405 fprintf (stdout
, " -q, --quiet\n\
2406 Returns the exit code, error messages will be displayed\n");
2407 fprintf (stdout
, " -s, --silent\n\
2408 Returns only the exit code; informational and error\n\
2409 messages are not displayed\n");
2410 fprintf (stdout
, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
2411 Parse the basename to file-guid cross reference file(s)\n");
2412 fprintf (stdout
, " -f OFFSET, --offset OFFSET\n\
2413 The offset from the start of the input file to start \n\
2414 processing an FV\n");
2415 fprintf (stdout
, " --hash\n\
2416 Generate HASH value of the entire PE image\n");
2417 fprintf (stdout
, " --sfo\n\
2418 Reserved for future use\n");