3 Copyright (c) 1999 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 The tool dumps the contents of a firmware volume
29 #include <Common/UefiBaseTypes.h>
30 #include <Common/UefiCapsule.h>
31 #include <Common/PiFirmwareFile.h>
32 #include <Common/PiFirmwareVolume.h>
33 #include <Guid/PiFirmwareFileSystem.h>
34 #include <IndustryStandard/PeImage.h>
35 #include <Protocol/GuidedSectionExtraction.h>
38 #include "Decompress.h"
40 #include "CommonLib.h"
41 #include "EfiUtilityMsgs.h"
42 #include "FirmwareVolumeBufferLib.h"
44 #include "ParseGuidedSectionTools.h"
45 #include "StringFuncs.h"
48 // Utility global variables
51 EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid
= EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID
;
53 #define UTILITY_MAJOR_VERSION 0
54 #define UTILITY_MINOR_VERSION 82
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
;
81 ParseGuidBaseNameFile (
86 FreeGuidBaseNameList (
97 IN UINT8
*SectionBuffer
,
98 IN UINT32 BufferLength
104 IN UINT32 SectionLength
112 OUT BOOLEAN
*ErasePolarity
118 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
119 EFI_FFS_FILE_HEADER
*FileHeader
,
120 BOOLEAN ErasePolarity
131 LoadGuidedSectionToolsTxt (
132 IN CHAR8
* FirmwareVolumeFilename
149 GC_TODO: Add function description
153 argc - GC_TODO: add argument description
154 ] - GC_TODO: add argument description
158 GC_TODO: add return values
164 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
;
168 BOOLEAN ErasePolarity
;
170 SetUtilityName (UTILITY_NAME
);
172 // Print utility header
174 printf ("%s Tiano Firmware Volume FFS image info. Version %d.%d, %s\n",
176 UTILITY_MAJOR_VERSION
,
177 UTILITY_MINOR_VERSION
,
182 // Save, and then skip filename arg
184 mUtilityFilename
= argv
[0];
191 // If they specified -x xref guid/basename cross-reference files, process it.
192 // This will print the basename beside each file guid. To use it, specify
193 // -x xref_filename to processdsc, then use xref_filename as a parameter
197 if ((strcmp(argv
[0], "-x") == 0) || (strcmp(argv
[0], "--xref") == 0)) {
198 ParseGuidBaseNameFile (argv
[1]);
199 printf("ParseGuidBaseNameFile: %s\n", argv
[1]);
202 } else if (strcmp(argv
[0], "--offset") == 0) {
206 if ((argv
[1][0] == '0') && (tolower (argv
[1][1]) == 'x')) {
207 if (sscanf (argv
[1], "%x", &Offset
) != 1) {
208 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
209 return GetUtilityStatus ();
212 if (sscanf (argv
[1], "%d", &Offset
) != 1) {
213 Error (NULL
, 0, 1003, "Invalid option value", "Offset = %s", argv
[1]);
214 return GetUtilityStatus ();
217 // See if they said something like "64K"
219 if (tolower (argv
[1][strlen (argv
[1]) - 1]) == 'k') {
232 // Check for proper number of arguments
239 // Look for help options
241 if ((strcmp(argv
[0], "-h") == 0) || (strcmp(argv
[0], "--help") == 0) ||
242 (strcmp(argv
[0], "-?") == 0) || (strcmp(argv
[0], "/?") == 0)) {
248 // Open the file containing the FV
250 InputFile
= fopen (argv
[0], "rb");
251 if (InputFile
== NULL
) {
252 Error (NULL
, 0, 0001, "Error opening the input file", argv
[0]);
253 return GetUtilityStatus ();
256 // Skip over pad bytes if specified. This is used if they prepend 0xff
257 // data to the FV image binary.
260 fseek (InputFile
, Offset
, SEEK_SET
);
263 // Determine size of FV
265 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
266 if (EFI_ERROR (Status
)) {
267 Error (NULL
, 0, 0003, "error parsing FV image", "%s Header is invalid", argv
[0]);
269 return GetUtilityStatus ();
272 // Allocate a buffer for the FV image
274 FvImage
= malloc (FvSize
);
275 if (FvImage
== NULL
) {
276 Error (NULL
, 0, 4001, "Resource: Memory can't be allocated", NULL
);
278 return GetUtilityStatus ();
281 // Seek to the start of the image, then read the entire FV to the buffer
283 fseek (InputFile
, Offset
, SEEK_SET
);
284 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
286 if ((unsigned int) BytesRead
!= FvSize
) {
287 Error (NULL
, 0, 0004, "error reading FvImage from", argv
[0]);
289 return GetUtilityStatus ();
292 LoadGuidedSectionToolsTxt (argv
[0]);
294 PrintFvInfo (FvImage
);
300 FreeGuidBaseNameList ();
301 return GetUtilityStatus ();
314 GC_TODO: Add function description
318 Fv - Firmware Volume to print information about
328 BOOLEAN ErasePolarity
;
330 EFI_FFS_FILE_HEADER
*CurrentFile
;
333 Status
= FvBufGetSize (Fv
, &FvSize
);
337 (((EFI_FIRMWARE_VOLUME_HEADER
*)Fv
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) ?
341 // Get the first file
344 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
345 if (EFI_ERROR (Status
)) {
346 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
347 return GetUtilityStatus ();
350 // Display information about files found
352 while (CurrentFile
!= NULL
) {
354 // Increment the number of files counter
359 // Display info about this file
361 Status
= PrintFileInfo (Fv
, CurrentFile
, ErasePolarity
);
362 if (EFI_ERROR (Status
)) {
363 Error (NULL
, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
364 return GetUtilityStatus ();
369 Status
= FvBufFindNextFile (Fv
, &Key
, (VOID
**) &CurrentFile
);
370 if (Status
== EFI_NOT_FOUND
) {
372 } else if (EFI_ERROR (Status
)) {
373 Error (NULL
, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
374 return GetUtilityStatus ();
378 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles
);
385 IN UINT32 ActualSize
,
392 This function returns the next larger size that meets the alignment
393 requirement specified.
398 Alignment The desired alignment.
402 EFI_SUCCESS Function completed successfully.
403 EFI_ABORTED The function encountered an error.
409 OccupiedSize
= ActualSize
;
410 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
420 IN EFI_SECTION_TYPE Type
426 Converts EFI Section names to Strings
430 Type - The EFI Section type
434 CHAR8* - Pointer to the String containing the section name.
439 CHAR8
*SectionTypeStringTable
[] = {
447 "EFI_SECTION_COMPRESSION",
451 "EFI_SECTION_GUID_DEFINED",
455 "Unknown section type - Reserved 0x03",
459 "Unknown section type - Reserved 0x04",
463 "Unknown section type - Reserved 0x05",
467 "Unknown section type - Reserved 0x06",
471 "Unknown section type - Reserved 0x07",
475 "Unknown section type - Reserved 0x08",
479 "Unknown section type - Reserved 0x09",
483 "Unknown section type - Reserved 0x0A",
487 "Unknown section type - Reserved 0x0B",
491 "Unknown section type - Reserved 0x0C",
495 "Unknown section type - Reserved 0x0D",
499 "Unknown section type - Reserved 0x0E",
503 "Unknown section type - Reserved 0x0E",
519 "EFI_SECTION_DXE_DEPEX",
523 "EFI_SECTION_VERSION",
527 "EFI_SECTION_USER_INTERFACE",
531 "EFI_SECTION_COMPATIBILITY16",
535 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
539 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
547 "Unknown section type - 0x1A",
551 "EFI_SECTION_PEI_DEPEX",
555 "EFI_SECTION_SMM_DEPEX",
559 "Unknown section type - Reserved - beyond last defined section"
562 if (Type
> EFI_SECTION_LAST_SECTION_TYPE
) {
563 Type
= EFI_SECTION_LAST_SECTION_TYPE
+ 1;
566 SectionStr
= malloc (100);
567 if (SectionStr
== NULL
) {
568 printf ("Error: Out of memory resources.\n");
571 strcpy (SectionStr
, SectionTypeStringTable
[Type
]);
580 OUT BOOLEAN
*ErasePolarity
586 This function determines the size of the FV and the erase polarity. The
587 erase polarity is the FALSE value for file state.
591 InputFile The file that contains the FV image.
592 FvSize The size of the FV.
593 ErasePolarity The FV erase polarity.
597 EFI_SUCCESS Function completed successfully.
598 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
599 EFI_ABORTED The function encountered an error.
603 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
604 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
612 // Check input parameters
614 if (InputFile
== NULL
|| FvSize
== NULL
|| ErasePolarity
== NULL
) {
615 Error (__FILE__
, __LINE__
, 0, "application error", "invalid parameter to function");
616 return EFI_INVALID_PARAMETER
;
621 fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
622 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
623 Signature
[0] = VolumeHeader
.Signature
;
627 // Print FV header information
629 printf ("Signature: %s (%X)\n", (char *) Signature
, (unsigned) VolumeHeader
.Signature
);
630 printf ("Attributes: %X\n", (unsigned) VolumeHeader
.Attributes
);
632 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_DISABLED_CAP
) {
633 printf (" EFI_FVB2_READ_DISABLED_CAP\n");
636 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_ENABLED_CAP
) {
637 printf (" EFI_FVB2_READ_ENABLED_CAP\n");
640 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_STATUS
) {
641 printf (" EFI_FVB2_READ_STATUS\n");
644 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_DISABLED_CAP
) {
645 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
648 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_ENABLED_CAP
) {
649 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
652 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_STATUS
) {
653 printf (" EFI_FVB2_WRITE_STATUS\n");
656 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_CAP
) {
657 printf (" EFI_FVB2_LOCK_CAP\n");
660 if (VolumeHeader
.Attributes
& EFI_FVB2_LOCK_STATUS
) {
661 printf (" EFI_FVB2_LOCK_STATUS\n");
664 if (VolumeHeader
.Attributes
& EFI_FVB2_STICKY_WRITE
) {
665 printf (" EFI_FVB2_STICKY_WRITE\n");
668 if (VolumeHeader
.Attributes
& EFI_FVB2_MEMORY_MAPPED
) {
669 printf (" EFI_FVB2_MEMORY_MAPPED\n");
672 if (VolumeHeader
.Attributes
& EFI_FVB2_ERASE_POLARITY
) {
673 printf (" EFI_FVB2_ERASE_POLARITY\n");
674 *ErasePolarity
= TRUE
;
677 #if (PI_SPECIFICATION_VERSION < 0x00010000)
678 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT
) {
679 printf (" EFI_FVB2_ALIGNMENT\n");
682 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
683 printf (" EFI_FVB2_ALIGNMENT_2\n");
686 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
687 printf (" EFI_FVB2_ALIGNMENT_4\n");
690 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
691 printf (" EFI_FVB2_ALIGNMENT_8\n");
694 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
695 printf (" EFI_FVB2_ALIGNMENT_16\n");
698 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
699 printf (" EFI_FVB2_ALIGNMENT_32\n");
702 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
703 printf (" EFI_FVB2_ALIGNMENT_64\n");
706 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
707 printf (" EFI_FVB2_ALIGNMENT_128\n");
710 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
711 printf (" EFI_FVB2_ALIGNMENT_256\n");
714 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
715 printf (" EFI_FVB2_ALIGNMENT_512\n");
718 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
719 printf (" EFI_FVB2_ALIGNMENT_1K\n");
722 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
723 printf (" EFI_FVB2_ALIGNMENT_2K\n");
726 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
727 printf (" EFI_FVB2_ALIGNMENT_4K\n");
730 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
731 printf (" EFI_FVB2_ALIGNMENT_8K\n");
734 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
735 printf (" EFI_FVB2_ALIGNMENT_16K\n");
738 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
739 printf (" EFI_FVB2_ALIGNMENT_32K\n");
742 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
743 printf (" EFI_FVB2_ALIGNMENT_64K\n");
748 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_CAP
) {
749 printf (" EFI_FVB2_READ_LOCK_CAP\n");
752 if (VolumeHeader
.Attributes
& EFI_FVB2_READ_LOCK_STATUS
) {
753 printf (" EFI_FVB2_READ_LOCK_STATUS\n");
756 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_CAP
) {
757 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
760 if (VolumeHeader
.Attributes
& EFI_FVB2_WRITE_LOCK_STATUS
) {
761 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
764 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1
) {
765 printf (" EFI_FVB2_ALIGNMENT_1\n");
768 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2
) {
769 printf (" EFI_FVB2_ALIGNMENT_2\n");
772 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4
) {
773 printf (" EFI_FVB2_ALIGNMENT_4\n");
776 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8
) {
777 printf (" EFI_FVB2_ALIGNMENT_8\n");
780 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16
) {
781 printf (" EFI_FVB2_ALIGNMENT_16\n");
784 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32
) {
785 printf (" EFI_FVB2_ALIGNMENT_32\n");
788 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64
) {
789 printf (" EFI_FVB2_ALIGNMENT_64\n");
792 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128
) {
793 printf (" EFI_FVB2_ALIGNMENT_128\n");
796 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256
) {
797 printf (" EFI_FVB2_ALIGNMENT_256\n");
800 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512
) {
801 printf (" EFI_FVB2_ALIGNMENT_512\n");
804 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1K
) {
805 printf (" EFI_FVB2_ALIGNMENT_1K\n");
808 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2K
) {
809 printf (" EFI_FVB2_ALIGNMENT_2K\n");
812 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4K
) {
813 printf (" EFI_FVB2_ALIGNMENT_4K\n");
816 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8K
) {
817 printf (" EFI_FVB2_ALIGNMENT_8K\n");
820 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16K
) {
821 printf (" EFI_FVB2_ALIGNMENT_16K\n");
824 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32K
) {
825 printf (" EFI_FVB2_ALIGNMENT_32K\n");
828 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64K
) {
829 printf (" EFI_FVB2_ALIGNMENT_64K\n");
832 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128K
) {
833 printf (" EFI_FVB2_ALIGNMENT_128K\n");
836 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256K
) {
837 printf (" EFI_FVB2_ALIGNMENT_256K\n");
840 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMNET_512K
) {
841 printf (" EFI_FVB2_ALIGNMNET_512K\n");
844 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1M
) {
845 printf (" EFI_FVB2_ALIGNMENT_1M\n");
848 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2M
) {
849 printf (" EFI_FVB2_ALIGNMENT_2M\n");
852 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_4M
) {
853 printf (" EFI_FVB2_ALIGNMENT_4M\n");
856 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_8M
) {
857 printf (" EFI_FVB2_ALIGNMENT_8M\n");
860 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_16M
) {
861 printf (" EFI_FVB2_ALIGNMENT_16M\n");
864 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_32M
) {
865 printf (" EFI_FVB2_ALIGNMENT_32M\n");
868 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
869 printf (" EFI_FVB2_ALIGNMENT_64M\n");
872 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
873 printf (" EFI_FVB2_ALIGNMENT_128M\n");
876 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_64M
) {
877 printf (" EFI_FVB2_ALIGNMENT_64M\n");
880 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_128M
) {
881 printf (" EFI_FVB2_ALIGNMENT_128M\n");
884 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_256M
) {
885 printf (" EFI_FVB2_ALIGNMENT_256M\n");
888 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_512M
) {
889 printf (" EFI_FVB2_ALIGNMENT_512M\n");
892 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_1G
) {
893 printf (" EFI_FVB2_ALIGNMENT_1G\n");
896 if (VolumeHeader
.Attributes
& EFI_FVB2_ALIGNMENT_2G
) {
897 printf (" EFI_FVB2_ALIGNMENT_2G\n");
901 printf ("Header Length: 0x%08X\n", VolumeHeader
.HeaderLength
);
902 printf ("File System ID: ");
903 PrintGuid (&VolumeHeader
.FileSystemGuid
);
907 printf ("Revision: 0x%04X\n", VolumeHeader
.Revision
);
910 fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
911 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
913 if (BlockMap
.NumBlocks
!= 0) {
914 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap
.NumBlocks
);
915 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap
.Length
);
916 Size
+= BlockMap
.NumBlocks
* BlockMap
.Length
;
919 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.Length
== 0));
921 if (BytesRead
!= VolumeHeader
.HeaderLength
) {
922 printf ("ERROR: Header length not consistent with Block Maps!\n");
926 if (VolumeHeader
.FvLength
!= Size
) {
927 printf ("ERROR: Volume Size not consistant with Block Maps!\n");
931 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size
);
936 // rewind (InputFile);
944 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
,
945 EFI_FFS_FILE_HEADER
*FileHeader
,
946 BOOLEAN ErasePolarity
952 GC_TODO: Add function description
956 FvImage - GC_TODO: add argument description
957 FileHeader - GC_TODO: add argument description
958 ErasePolarity - GC_TODO: add argument description
962 EFI_SUCCESS - GC_TODO: Add description for return value
963 EFI_ABORTED - GC_TODO: Add description for return value
970 EFI_FFS_FILE_HEADER BlankHeader
;
972 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
973 #if (PI_SPECIFICATION_VERSION < 0x00010000)
977 // Check if we have free space
980 memset (&BlankHeader
, -1, sizeof (EFI_FFS_FILE_HEADER
));
982 memset (&BlankHeader
, 0, sizeof (EFI_FFS_FILE_HEADER
));
985 if (memcmp (&BlankHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER
)) == 0) {
989 // Print file information.
991 printf ("============================================================\n");
993 printf ("File Name: ");
994 PrintGuidToBuffer (&FileHeader
->Name
, GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
995 printf ("%s ", GuidBuffer
);
996 PrintGuidName (GuidBuffer
);
1000 // PrintGuid (&FileHeader->Name);
1003 FileLength
= GetLength (FileHeader
->Size
);
1004 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN
) FileHeader
- (UINTN
) FvImage
));
1005 printf ("File Length: 0x%08X\n", (unsigned) FileLength
);
1006 printf ("File Attributes: 0x%02X\n", FileHeader
->Attributes
);
1007 printf ("File State: 0x%02X\n", FileHeader
->State
);
1012 FileState
= GetFileState (ErasePolarity
, FileHeader
);
1014 switch (FileState
) {
1016 case EFI_FILE_HEADER_CONSTRUCTION
:
1017 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
1020 case EFI_FILE_HEADER_INVALID
:
1021 printf (" EFI_FILE_HEADER_INVALID\n");
1024 case EFI_FILE_HEADER_VALID
:
1025 printf (" EFI_FILE_HEADER_VALID\n");
1026 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
1027 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1028 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1029 if (Checksum
!= 0) {
1030 printf ("ERROR: Header checksum invalid.\n");
1036 case EFI_FILE_DELETED
:
1037 printf (" EFI_FILE_DELETED\n");
1039 case EFI_FILE_MARKED_FOR_UPDATE
:
1040 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
1042 case EFI_FILE_DATA_VALID
:
1043 printf (" EFI_FILE_DATA_VALID\n");
1046 // Calculate header checksum
1048 Checksum
= CalculateSum8 ((UINT8
*) FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
1049 Checksum
= (UINT8
) (Checksum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
1050 Checksum
= (UINT8
) (Checksum
- FileHeader
->State
);
1051 if (Checksum
!= 0) {
1052 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer
);
1056 FileLength
= GetLength (FileHeader
->Size
);
1058 if (FileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
1060 // Calculate file checksum
1062 Checksum
= CalculateSum8 ((UINT8
*) (FileHeader
+ 1), FileLength
- sizeof (EFI_FFS_FILE_HEADER
));
1063 Checksum
= Checksum
+ FileHeader
->IntegrityCheck
.Checksum
.File
;
1064 if (Checksum
!= 0) {
1065 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer
);
1069 if (FileHeader
->IntegrityCheck
.Checksum
.File
!= FFS_FIXED_CHECKSUM
) {
1070 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
);
1074 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1076 // Verify tail if present
1078 if (FileHeader
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
1080 // Verify tail is complement of integrity check field in the header.
1082 Tail
= (UINT16
*) ((UINTN
) FileHeader
+ GetLength (FileHeader
->Size
) - sizeof (EFI_FFS_INTEGRITY_CHECK
));
1083 if (FileHeader
->IntegrityCheck
.TailReference
!= (UINT16
)~(*Tail
)) {
1084 Error (NULL
, 0, 0003, "error parsing FFS file", \
1085 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer
);
1093 Error (NULL
, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer
);
1097 printf ("File Type: 0x%02X ", FileHeader
->Type
);
1099 switch (FileHeader
->Type
) {
1101 case EFI_FV_FILETYPE_RAW
:
1102 printf ("EFI_FV_FILETYPE_RAW\n");
1105 case EFI_FV_FILETYPE_FREEFORM
:
1106 printf ("EFI_FV_FILETYPE_FREEFORM\n");
1109 case EFI_FV_FILETYPE_SECURITY_CORE
:
1110 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
1113 case EFI_FV_FILETYPE_PEI_CORE
:
1114 printf ("EFI_FV_FILETYPE_PEI_CORE\n");
1117 case EFI_FV_FILETYPE_DXE_CORE
:
1118 printf ("EFI_FV_FILETYPE_DXE_CORE\n");
1121 case EFI_FV_FILETYPE_PEIM
:
1122 printf ("EFI_FV_FILETYPE_PEIM\n");
1125 case EFI_FV_FILETYPE_DRIVER
:
1126 printf ("EFI_FV_FILETYPE_DRIVER\n");
1129 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
1130 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
1133 case EFI_FV_FILETYPE_APPLICATION
:
1134 printf ("EFI_FV_FILETYPE_APPLICATION\n");
1137 case EFI_FV_FILETYPE_SMM
:
1138 printf ("EFI_FV_FILETYPE_SMM\n");
1141 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
:
1142 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1145 case EFI_FV_FILETYPE_COMBINED_SMM_DXE
:
1146 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
1149 case EFI_FV_FILETYPE_SMM_CORE
:
1150 printf ("EFI_FV_FILETYPE_SMM_CORE\n");
1153 case EFI_FV_FILETYPE_FFS_PAD
:
1154 printf ("EFI_FV_FILETYPE_FFS_PAD\n");
1158 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader
->Type
);
1163 switch (FileHeader
->Type
) {
1165 case EFI_FV_FILETYPE_ALL
:
1166 case EFI_FV_FILETYPE_RAW
:
1167 case EFI_FV_FILETYPE_FFS_PAD
:
1172 // All other files have sections
1174 Status
= ParseSection (
1175 (UINT8
*) ((UINTN
) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER
)),
1176 GetLength (FileHeader
->Size
) - sizeof (EFI_FFS_FILE_HEADER
)
1178 if (EFI_ERROR (Status
)) {
1180 // printf ("ERROR: Parsing the FFS file.\n");
1192 IN UINT8
*SectionBuffer
,
1193 IN UINT32 BufferLength
1197 Routine Description:
1203 SectionBuffer - Buffer containing the section to parse.
1204 BufferLength - Length of SectionBuffer
1208 EFI_SECTION_ERROR - Problem with section parsing.
1209 (a) compression errors
1210 (b) unrecognized section
1211 EFI_UNSUPPORTED - Do not know how to parse the section.
1212 EFI_SUCCESS - Section successfully parsed.
1213 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1217 EFI_SECTION_TYPE Type
;
1219 UINT32 SectionLength
;
1222 UINT32 ParsedLength
;
1223 UINT8
*CompressedBuffer
;
1224 UINT32 CompressedLength
;
1225 UINT8
*UncompressedBuffer
;
1226 UINT32 UncompressedLength
;
1227 UINT8
*ToolOutputBuffer
;
1228 UINT32 ToolOutputLength
;
1229 UINT8 CompressionType
;
1232 UINT8
*ScratchBuffer
;
1233 DECOMPRESS_FUNCTION DecompressFunction
;
1234 GETINFO_FUNCTION GetInfoFunction
;
1236 CHAR8
*ExtractionTool
;
1237 CHAR8
*ToolInputFile
;
1238 CHAR8
*ToolOutputFile
;
1239 CHAR8
*SystemCommandFormatString
;
1240 CHAR8
*SystemCommand
;
1243 while (ParsedLength
< BufferLength
) {
1244 Ptr
= SectionBuffer
+ ParsedLength
;
1246 SectionLength
= GetLength (((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Size
);
1247 Type
= ((EFI_COMMON_SECTION_HEADER
*) Ptr
)->Type
;
1250 // This is sort of an odd check, but is necessary because FFS files are
1251 // padded to a QWORD boundary, meaning there is potentially a whole section
1252 // header worth of 0xFF bytes.
1254 if (SectionLength
== 0xffffff && Type
== 0xff) {
1259 SectionName
= SectionNameToStr (Type
);
1260 printf ("------------------------------------------------------------\n");
1261 printf (" Type: %s\n Size: 0x%08X\n", SectionName
, (unsigned) SectionLength
);
1265 case EFI_SECTION_RAW
:
1266 case EFI_SECTION_PE32
:
1267 case EFI_SECTION_PIC
:
1268 case EFI_SECTION_TE
:
1269 // default is no more information
1272 case EFI_SECTION_USER_INTERFACE
:
1273 // name = &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString;
1274 // printf (" String: %s\n", &name);
1277 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE
:
1278 Status
= PrintFvInfo (((EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*)Ptr
) + 1);
1279 if (EFI_ERROR (Status
)) {
1280 Error (NULL
, 0, 0003, "printing of FV section contents failed", NULL
);
1281 return EFI_SECTION_ERROR
;
1285 case EFI_SECTION_COMPATIBILITY16
:
1286 case EFI_SECTION_FREEFORM_SUBTYPE_GUID
:
1288 // Section does not contain any further header information.
1292 case EFI_SECTION_PEI_DEPEX
:
1293 case EFI_SECTION_DXE_DEPEX
:
1294 case EFI_SECTION_SMM_DEPEX
:
1295 DumpDepexSection (Ptr
, SectionLength
);
1298 case EFI_SECTION_VERSION
:
1299 printf (" Build Number: 0x%02X\n", ((EFI_VERSION_SECTION
*) Ptr
)->BuildNumber
);
1300 printf (" Version Strg: %s\n", (char*) ((EFI_VERSION_SECTION
*) Ptr
)->VersionString
);
1303 case EFI_SECTION_COMPRESSION
:
1304 UncompressedBuffer
= NULL
;
1305 CompressedLength
= SectionLength
- sizeof (EFI_COMPRESSION_SECTION
);
1306 UncompressedLength
= ((EFI_COMPRESSION_SECTION
*) Ptr
)->UncompressedLength
;
1307 CompressionType
= ((EFI_COMPRESSION_SECTION
*) Ptr
)->CompressionType
;
1308 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength
);
1310 if (CompressionType
== EFI_NOT_COMPRESSED
) {
1311 printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1312 if (CompressedLength
!= UncompressedLength
) {
1317 "file is not compressed, but the compressed length does not match the uncompressed length",
1320 return EFI_SECTION_ERROR
;
1323 UncompressedBuffer
= Ptr
+ sizeof (EFI_COMPRESSION_SECTION
);
1324 } else if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1325 GetInfoFunction
= EfiGetInfo
;
1326 DecompressFunction
= EfiDecompress
;
1327 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
1329 CompressedBuffer
= Ptr
+ sizeof (EFI_COMPRESSION_SECTION
);
1331 Status
= GetInfoFunction (CompressedBuffer
, CompressedLength
, &DstSize
, &ScratchSize
);
1332 if (EFI_ERROR (Status
)) {
1333 Error (NULL
, 0, 0003, "error getting compression info from compression section", NULL
);
1334 return EFI_SECTION_ERROR
;
1337 if (DstSize
!= UncompressedLength
) {
1338 Error (NULL
, 0, 0003, "compression error in the compression section", NULL
);
1339 return EFI_SECTION_ERROR
;
1342 ScratchBuffer
= malloc (ScratchSize
);
1343 UncompressedBuffer
= malloc (UncompressedLength
);
1344 if ((ScratchBuffer
== NULL
) || (UncompressedBuffer
== NULL
)) {
1345 return EFI_OUT_OF_RESOURCES
;
1347 Status
= DecompressFunction (
1355 free (ScratchBuffer
);
1356 if (EFI_ERROR (Status
)) {
1357 Error (NULL
, 0, 0003, "decompress failed", NULL
);
1358 free (UncompressedBuffer
);
1359 return EFI_SECTION_ERROR
;
1362 Error (NULL
, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType
);
1363 return EFI_SECTION_ERROR
;
1366 Status
= ParseSection (UncompressedBuffer
, UncompressedLength
);
1368 if (CompressionType
== EFI_STANDARD_COMPRESSION
) {
1370 // We need to deallocate Buffer
1372 free (UncompressedBuffer
);
1375 if (EFI_ERROR (Status
)) {
1376 Error (NULL
, 0, 0003, "failed to parse section", NULL
);
1377 return EFI_SECTION_ERROR
;
1381 case EFI_SECTION_GUID_DEFINED
:
1382 printf (" SectionDefinitionGuid: ");
1383 PrintGuid (&((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
);
1385 printf (" DataOffset: 0x%04X\n", (unsigned) ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
);
1386 printf (" Attributes: 0x%04X\n", (unsigned) ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->Attributes
);
1389 LookupGuidedSectionToolPath (
1390 mParsedGuidedSectionTools
,
1391 &((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
1394 if (ExtractionTool
!= NULL
) {
1396 ToolInputFile
= CloneString (tmpnam (NULL
));
1397 ToolOutputFile
= CloneString (tmpnam (NULL
));
1400 // Construction 'system' command string
1402 SystemCommandFormatString
= "%s -d -o %s %s";
1403 SystemCommand
= malloc (
1404 strlen (SystemCommandFormatString
) +
1405 strlen (ExtractionTool
) +
1406 strlen (ToolInputFile
) +
1407 strlen (ToolOutputFile
) +
1412 SystemCommandFormatString
,
1417 free (ExtractionTool
);
1422 (CHAR8
*) SectionBuffer
+ ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
,
1423 BufferLength
- ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
1426 system (SystemCommand
);
1427 remove (ToolInputFile
);
1428 free (ToolInputFile
);
1433 (CHAR8
**)&ToolOutputBuffer
,
1436 remove (ToolOutputFile
);
1437 free (ToolOutputFile
);
1438 if (EFI_ERROR (Status
)) {
1439 Error (NULL
, 0, 0004, "unable to read decoded GUIDED section", NULL
);
1440 return EFI_SECTION_ERROR
;
1443 Status
= ParseSection (
1447 if (EFI_ERROR (Status
)) {
1448 Error (NULL
, 0, 0003, "parse of decoded GUIDED section failed", NULL
);
1449 return EFI_SECTION_ERROR
;
1453 // Check for CRC32 sections which we can handle internally if needed.
1455 } else if (!CompareGuid (
1456 &((EFI_GUID_DEFINED_SECTION
*) Ptr
)->SectionDefinitionGuid
,
1457 &gEfiCrc32GuidedSectionExtractionProtocolGuid
1461 // CRC32 guided section
1463 Status
= ParseSection (
1464 SectionBuffer
+ ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
,
1465 BufferLength
- ((EFI_GUID_DEFINED_SECTION
*) Ptr
)->DataOffset
1467 if (EFI_ERROR (Status
)) {
1468 Error (NULL
, 0, 0003, "parse of CRC32 GUIDED section failed", NULL
);
1469 return EFI_SECTION_ERROR
;
1473 // We don't know how to parse it now.
1475 Error (NULL
, 0, 0003, "Error parsing section", \
1476 "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).");
1477 return EFI_UNSUPPORTED
;
1483 // Unknown section, return error
1485 Error (NULL
, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type
);
1486 return EFI_SECTION_ERROR
;
1489 ParsedLength
+= SectionLength
;
1491 // We make then next section begin on a 4-byte boundary
1493 ParsedLength
= GetOccupiedSize (ParsedLength
, 4);
1496 if (ParsedLength
< BufferLength
) {
1497 Error (NULL
, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL
);
1498 return EFI_SECTION_ERROR
;
1507 IN UINT32 SectionLength
1511 Routine Description:
1513 GC_TODO: Add function description
1517 Ptr - GC_TODO: add argument description
1518 SectionLength - GC_TODO: add argument description
1522 EFI_SUCCESS - GC_TODO: Add description for return value
1526 UINT8 GuidBuffer
[PRINTED_GUID_BUFFER_SIZE
];
1529 // Need at least a section header + data
1531 if (SectionLength
<= sizeof (EFI_COMMON_SECTION_HEADER
)) {
1535 Ptr
+= sizeof (EFI_COMMON_SECTION_HEADER
);
1536 SectionLength
-= sizeof (EFI_COMMON_SECTION_HEADER
);
1537 while (SectionLength
> 0) {
1540 case EFI_DEP_BEFORE
:
1541 printf ("BEFORE\n");
1554 PrintGuidToBuffer ((EFI_GUID
*) (Ptr
+ 1), GuidBuffer
, sizeof (GuidBuffer
), TRUE
);
1555 printf ("%s ", GuidBuffer
);
1556 PrintGuidName (GuidBuffer
);
1559 // PrintGuid ((EFI_GUID *)(Ptr + 1));
1562 SectionLength
-= 17;
1596 printf ("END DEPEX\n");
1608 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr
);
1622 Routine Description:
1624 GC_TODO: Add function description
1628 GuidStr - GC_TODO: add argument description
1632 EFI_SUCCESS - GC_TODO: Add description for return value
1633 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
1637 GUID_TO_BASENAME
*GPtr
;
1639 // If we have a list of guid-to-basenames, then go through the list to
1640 // look for a guid string match. If found, print the basename to stdout,
1641 // otherwise return a failure.
1643 GPtr
= mGuidBaseNameList
;
1644 while (GPtr
!= NULL
) {
1645 if (_stricmp ((CHAR8
*) GuidStr
, (CHAR8
*) GPtr
->Guid
) == 0) {
1646 printf ("%s", GPtr
->BaseName
);
1653 return EFI_INVALID_PARAMETER
;
1657 ParseGuidBaseNameFile (
1662 Routine Description:
1664 GC_TODO: Add function description
1668 FileName - GC_TODO: add argument description
1672 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
1673 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
1674 EFI_SUCCESS - GC_TODO: Add description for return value
1679 CHAR8 Line
[MAX_LINE_LEN
];
1680 GUID_TO_BASENAME
*GPtr
;
1682 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
1683 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName
);
1684 return EFI_DEVICE_ERROR
;
1687 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
1689 // Allocate space for another guid/basename element
1691 GPtr
= malloc (sizeof (GUID_TO_BASENAME
));
1693 return EFI_OUT_OF_RESOURCES
;
1696 memset ((char *) GPtr
, 0, sizeof (GUID_TO_BASENAME
));
1697 if (sscanf (Line
, "%s %s", GPtr
->Guid
, GPtr
->BaseName
) == 2) {
1698 GPtr
->Next
= mGuidBaseNameList
;
1699 mGuidBaseNameList
= GPtr
;
1702 // Some sort of error. Just continue.
1713 FreeGuidBaseNameList (
1718 Routine Description:
1720 GC_TODO: Add function description
1728 EFI_SUCCESS - GC_TODO: Add description for return value
1732 GUID_TO_BASENAME
*Next
;
1734 while (mGuidBaseNameList
!= NULL
) {
1735 Next
= mGuidBaseNameList
->Next
;
1736 free (mGuidBaseNameList
);
1737 mGuidBaseNameList
= Next
;
1746 LoadGuidedSectionToolsTxt (
1747 IN CHAR8
* FirmwareVolumeFilename
1750 CHAR8
* PeerFilename
;
1757 Places
[0] = FirmwareVolumeFilename
;
1758 //Places[1] = mUtilityFilename;
1760 mParsedGuidedSectionTools
= NULL
;
1762 for (Index
= 0; Index
< (sizeof(Places
)/sizeof(Places
[0])); Index
++) {
1763 PeerFilename
= OsPathPeerFilePath (Places
[Index
], "GuidedSectionTools.txt");
1764 //printf("Loading %s...\n", PeerFilename);
1765 if (OsPathExists (PeerFilename
)) {
1766 mParsedGuidedSectionTools
= ParseGuidedSectionToolsFile (PeerFilename
);
1768 free (PeerFilename
);
1769 if (mParsedGuidedSectionTools
!= NULL
) {
1782 Routine Description:
1784 GC_TODO: Add function description
1792 GC_TODO: add return values
1799 fprintf (stdout
, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME
);
1802 // Copyright declaration
1804 fprintf (stdout
, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");
1809 fprintf (stdout
, "Options:\n");
1810 fprintf (stdout
, " -x xref, --xref xref\n\
1811 Parse basename to file-guid cross reference file(s).\n");
1812 fprintf (stdout
, " --offset offset\n\
1813 Offset of file to start processing FV at.\n");
1814 fprintf (stdout
, " -h, --help\n\
1815 Show this help message and exit.\n");