]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VolInfo/VolInfo.c
License header updated to match correct format.
[mirror_edk2.git] / BaseTools / Source / C / VolInfo / VolInfo.c
CommitLineData
f51461c8 1/** @file\r
97fa0ee9 2The tool dumps the contents of a firmware volume\r
f51461c8 3\r
e4ac870f 4Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>\r
f51461c8
LG
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
f51461c8
LG
13**/\r
14\r
15#include <stdio.h>\r
16#include <stdlib.h>\r
17#include <string.h>\r
18#include <ctype.h>\r
19#include <assert.h>\r
20\r
21#include <FvLib.h>\r
22#include <Common/UefiBaseTypes.h>\r
23#include <Common/UefiCapsule.h>\r
24#include <Common/PiFirmwareFile.h>\r
25#include <Common/PiFirmwareVolume.h>\r
26#include <Guid/PiFirmwareFileSystem.h>\r
27#include <IndustryStandard/PeImage.h>\r
28#include <Protocol/GuidedSectionExtraction.h>\r
29\r
30#include "Compress.h"\r
31#include "Decompress.h"\r
32#include "VolInfo.h"\r
33#include "CommonLib.h"\r
34#include "EfiUtilityMsgs.h"\r
35#include "FirmwareVolumeBufferLib.h"\r
36#include "OsPath.h"\r
37#include "ParseGuidedSectionTools.h"\r
38#include "StringFuncs.h"\r
39\r
40//\r
41// Utility global variables\r
42//\r
43\r
44EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
45\r
46#define UTILITY_MAJOR_VERSION 0\r
f4260465 47#define UTILITY_MINOR_VERSION 83\r
f51461c8
LG
48\r
49#define UTILITY_NAME "VolInfo"\r
50\r
51#define EFI_SECTION_ERROR EFIERR (100)\r
52\r
53#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable\r
54\r
55//\r
56// Structure to keep a list of guid-to-basenames\r
57//\r
58typedef struct _GUID_TO_BASENAME {\r
59 struct _GUID_TO_BASENAME *Next;\r
60 INT8 Guid[PRINTED_GUID_BUFFER_SIZE];\r
61 INT8 BaseName[MAX_BASENAME_LEN];\r
62} GUID_TO_BASENAME;\r
63\r
64static GUID_TO_BASENAME *mGuidBaseNameList = NULL;\r
65\r
66//\r
67// Store GUIDed Section guid->tool mapping\r
68//\r
69EFI_HANDLE mParsedGuidedSectionTools = NULL;\r
70\r
71CHAR8* mUtilityFilename = NULL;\r
72\r
73EFI_STATUS\r
74ParseGuidBaseNameFile (\r
75 CHAR8 *FileName\r
76 );\r
77\r
78EFI_STATUS\r
79FreeGuidBaseNameList (\r
80 VOID\r
81 );\r
82\r
83EFI_STATUS\r
84PrintGuidName (\r
85 IN UINT8 *GuidStr\r
86 );\r
87\r
88EFI_STATUS\r
89ParseSection (\r
90 IN UINT8 *SectionBuffer,\r
91 IN UINT32 BufferLength\r
92 );\r
93\r
94EFI_STATUS\r
95DumpDepexSection (\r
96 IN UINT8 *Ptr,\r
97 IN UINT32 SectionLength\r
98 );\r
99\r
100STATIC\r
101EFI_STATUS\r
102ReadHeader (\r
103 IN FILE *InputFile,\r
104 OUT UINT32 *FvSize,\r
105 OUT BOOLEAN *ErasePolarity\r
106 );\r
107\r
108STATIC\r
109EFI_STATUS\r
110PrintFileInfo (\r
111 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
112 EFI_FFS_FILE_HEADER *FileHeader,\r
113 BOOLEAN ErasePolarity\r
114 );\r
115\r
116static\r
117EFI_STATUS\r
118PrintFvInfo (\r
119 IN VOID *Fv,\r
120 IN BOOLEAN IsChildFv\r
121 );\r
122\r
123static\r
124VOID\r
125LoadGuidedSectionToolsTxt (\r
126 IN CHAR8* FirmwareVolumeFilename\r
127 );\r
128\r
129void\r
130Usage (\r
131 VOID\r
132 );\r
133\r
134int\r
135main (\r
136 int argc,\r
137 char *argv[]\r
138 )\r
139/*++\r
140\r
141Routine Description:\r
142\r
143 GC_TODO: Add function description\r
144\r
145Arguments:\r
146\r
147 argc - GC_TODO: add argument description\r
148 ] - GC_TODO: add argument description\r
149\r
150Returns:\r
151\r
152 GC_TODO: add return values\r
153\r
154--*/\r
155{\r
156 FILE *InputFile;\r
157 int BytesRead;\r
158 EFI_FIRMWARE_VOLUME_HEADER *FvImage;\r
159 UINT32 FvSize;\r
160 EFI_STATUS Status;\r
161 int Offset;\r
162 BOOLEAN ErasePolarity;\r
163\r
164 SetUtilityName (UTILITY_NAME);\r
165 //\r
166 // Print utility header\r
167 //\r
f4260465 168 printf ("%s Version %d.%d %s, %s\n",\r
f51461c8
LG
169 UTILITY_NAME,\r
170 UTILITY_MAJOR_VERSION,\r
171 UTILITY_MINOR_VERSION,\r
172 __BUILD_VERSION,\r
173 __DATE__\r
174 );\r
175\r
176 //\r
177 // Save, and then skip filename arg\r
178 //\r
179 mUtilityFilename = argv[0];\r
180 argc--;\r
181 argv++;\r
182\r
183 Offset = 0;\r
184\r
185 //\r
186 // If they specified -x xref guid/basename cross-reference files, process it.\r
187 // This will print the basename beside each file guid. To use it, specify\r
188 // -x xref_filename to processdsc, then use xref_filename as a parameter\r
189 // here.\r
190 //\r
191 while (argc > 2) {\r
192 if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {\r
193 ParseGuidBaseNameFile (argv[1]);\r
194 printf("ParseGuidBaseNameFile: %s\n", argv[1]);\r
195 argc -= 2;\r
196 argv += 2;\r
197 } else if (strcmp(argv[0], "--offset") == 0) {\r
198 //\r
199 // Hex or decimal?\r
200 //\r
201 if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {\r
202 if (sscanf (argv[1], "%x", &Offset) != 1) {\r
203 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
204 return GetUtilityStatus ();\r
205 }\r
206 } else {\r
207 if (sscanf (argv[1], "%d", &Offset) != 1) {\r
208 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
209 return GetUtilityStatus ();\r
210 }\r
211 //\r
212 // See if they said something like "64K"\r
213 //\r
214 if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {\r
215 Offset *= 1024;\r
216 }\r
217 }\r
218\r
219 argc -= 2;\r
220 argv += 2;\r
221 } else {\r
222 Usage ();\r
223 return -1;\r
224 }\r
225 }\r
226 //\r
227 // Check for proper number of arguments\r
228 //\r
229 if (argc != 1) {\r
230 Usage ();\r
231 return -1;\r
232 }\r
233 //\r
234 // Look for help options\r
235 //\r
236 if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) || \r
237 (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {\r
238 Usage();\r
239 return STATUS_ERROR;\r
240 }\r
241\r
242 //\r
243 // Open the file containing the FV\r
244 //\r
1be2ed90 245 InputFile = fopen (LongFilePath (argv[0]), "rb");\r
f51461c8
LG
246 if (InputFile == NULL) {\r
247 Error (NULL, 0, 0001, "Error opening the input file", argv[0]);\r
248 return GetUtilityStatus ();\r
249 }\r
250 //\r
251 // Skip over pad bytes if specified. This is used if they prepend 0xff\r
252 // data to the FV image binary.\r
253 //\r
254 if (Offset != 0) {\r
255 fseek (InputFile, Offset, SEEK_SET);\r
256 }\r
257 //\r
258 // Determine size of FV\r
259 //\r
260 Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);\r
261 if (EFI_ERROR (Status)) {\r
262 Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", argv[0]);\r
263 fclose (InputFile);\r
264 return GetUtilityStatus ();\r
265 }\r
266 //\r
267 // Allocate a buffer for the FV image\r
268 //\r
269 FvImage = malloc (FvSize);\r
270 if (FvImage == NULL) {\r
271 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);\r
272 fclose (InputFile);\r
273 return GetUtilityStatus ();\r
274 }\r
275 //\r
276 // Seek to the start of the image, then read the entire FV to the buffer\r
277 //\r
278 fseek (InputFile, Offset, SEEK_SET);\r
279 BytesRead = fread (FvImage, 1, FvSize, InputFile);\r
280 fclose (InputFile);\r
281 if ((unsigned int) BytesRead != FvSize) {\r
282 Error (NULL, 0, 0004, "error reading FvImage from", argv[0]);\r
283 free (FvImage);\r
284 return GetUtilityStatus ();\r
285 }\r
286\r
287 LoadGuidedSectionToolsTxt (argv[0]);\r
288\r
289 PrintFvInfo (FvImage, FALSE);\r
290\r
291 //\r
292 // Clean up\r
293 //\r
294 free (FvImage);\r
295 FreeGuidBaseNameList ();\r
296 return GetUtilityStatus ();\r
297}\r
298\r
299\r
300static\r
301EFI_STATUS\r
302PrintFvInfo (\r
303 IN VOID *Fv,\r
304 IN BOOLEAN IsChildFv\r
305 )\r
306/*++\r
307\r
308Routine Description:\r
309\r
310 GC_TODO: Add function description\r
311\r
312Arguments:\r
313\r
314 Fv - Firmware Volume to print information about\r
315 IsChildFv - Flag specifies whether the input FV is a child FV.\r
316\r
317Returns:\r
318\r
319 EFI_STATUS\r
320\r
321--*/\r
322{\r
323 EFI_STATUS Status;\r
324 UINTN NumberOfFiles;\r
325 BOOLEAN ErasePolarity;\r
326 UINTN FvSize;\r
327 EFI_FFS_FILE_HEADER *CurrentFile;\r
328 UINTN Key;\r
329\r
330 Status = FvBufGetSize (Fv, &FvSize);\r
331\r
332 NumberOfFiles = 0;\r
333 ErasePolarity =\r
334 (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?\r
335 TRUE : FALSE;\r
336\r
337 //\r
338 // Get the first file\r
339 //\r
340 Key = 0;\r
341 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
342 if (EFI_ERROR (Status)) {\r
343 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");\r
344 return GetUtilityStatus ();\r
345 }\r
346 //\r
347 // Display information about files found\r
348 //\r
349 while (CurrentFile != NULL) {\r
350 //\r
351 // Increment the number of files counter\r
352 //\r
353 NumberOfFiles++;\r
354\r
355 //\r
356 // Display info about this file\r
357 //\r
358 Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);\r
359 if (EFI_ERROR (Status)) {\r
360 Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");\r
361 return GetUtilityStatus ();\r
362 }\r
363 //\r
364 // Get the next file\r
365 //\r
366 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
367 if (Status == EFI_NOT_FOUND) {\r
368 CurrentFile = NULL;\r
369 } else if (EFI_ERROR (Status)) {\r
370 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");\r
371 return GetUtilityStatus ();\r
372 }\r
373 }\r
374\r
375 if (IsChildFv) {\r
376 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles);\r
377 } else {\r
378 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles);\r
379 }\r
380\r
381 return EFI_SUCCESS;\r
382}\r
383\r
384UINT32\r
385GetOccupiedSize (\r
386 IN UINT32 ActualSize,\r
387 IN UINT32 Alignment\r
388 )\r
389/*++\r
390\r
391Routine Description:\r
392\r
393 This function returns the next larger size that meets the alignment \r
394 requirement specified.\r
395\r
396Arguments:\r
397\r
398 ActualSize The size.\r
399 Alignment The desired alignment.\r
400 \r
401Returns:\r
402 \r
403 EFI_SUCCESS Function completed successfully.\r
404 EFI_ABORTED The function encountered an error.\r
405\r
406--*/\r
407{\r
408 UINT32 OccupiedSize;\r
409\r
410 OccupiedSize = ActualSize;\r
411 while ((OccupiedSize & (Alignment - 1)) != 0) {\r
412 OccupiedSize++;\r
413 }\r
414\r
415 return OccupiedSize;\r
416}\r
417\r
418static\r
419CHAR8 *\r
420SectionNameToStr (\r
421 IN EFI_SECTION_TYPE Type\r
422 )\r
423/*++\r
424\r
425Routine Description:\r
426\r
427 Converts EFI Section names to Strings\r
428\r
429Arguments:\r
430\r
431 Type - The EFI Section type\r
432\r
433Returns:\r
434\r
435 CHAR8* - Pointer to the String containing the section name.\r
436\r
437--*/\r
438{\r
439 CHAR8 *SectionStr;\r
440 CHAR8 *SectionTypeStringTable[] = {\r
441 //\r
442 // 0X00\r
443 //\r
444 "EFI_SECTION_ALL",\r
445 //\r
446 // 0x01\r
447 //\r
448 "EFI_SECTION_COMPRESSION",\r
449 //\r
450 // 0x02\r
451 //\r
452 "EFI_SECTION_GUID_DEFINED", \r
453 //\r
454 // 0x03\r
455 //\r
456 "Unknown section type - Reserved 0x03",\r
457 //\r
458 // 0x04\r
459 //\r
460 "Unknown section type - Reserved 0x04",\r
461 //\r
462 // 0x05\r
463 //\r
464 "Unknown section type - Reserved 0x05",\r
465 //\r
466 // 0x06\r
467 //\r
468 "Unknown section type - Reserved 0x06",\r
469 //\r
470 // 0x07\r
471 //\r
472 "Unknown section type - Reserved 0x07",\r
473 //\r
474 // 0x08\r
475 //\r
476 "Unknown section type - Reserved 0x08",\r
477 //\r
478 // 0x09\r
479 //\r
480 "Unknown section type - Reserved 0x09",\r
481 //\r
482 // 0x0A\r
483 //\r
484 "Unknown section type - Reserved 0x0A",\r
485 //\r
486 // 0x0B\r
487 //\r
488 "Unknown section type - Reserved 0x0B",\r
489 //\r
490 // 0x0C\r
491 //\r
492 "Unknown section type - Reserved 0x0C",\r
493 //\r
494 // 0x0D\r
495 //\r
496 "Unknown section type - Reserved 0x0D",\r
497 //\r
498 // 0x0E\r
499 //\r
500 "Unknown section type - Reserved 0x0E",\r
501 //\r
502 // 0x0F\r
503 //\r
504 "Unknown section type - Reserved 0x0E",\r
505 //\r
506 // 0x10\r
507 //\r
508 "EFI_SECTION_PE32",\r
509 //\r
510 // 0x11\r
511 //\r
512 "EFI_SECTION_PIC",\r
513 //\r
514 // 0x12\r
515 //\r
516 "EFI_SECTION_TE", \r
517 //\r
518 // 0x13\r
519 //\r
520 "EFI_SECTION_DXE_DEPEX", \r
521 //\r
522 // 0x14\r
523 //\r
524 "EFI_SECTION_VERSION",\r
525 //\r
526 // 0x15\r
527 //\r
528 "EFI_SECTION_USER_INTERFACE",\r
529 //\r
530 // 0x16\r
531 //\r
532 "EFI_SECTION_COMPATIBILITY16",\r
533 //\r
534 // 0x17\r
535 //\r
536 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",\r
537 //\r
538 // 0x18\r
539 //\r
540 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",\r
541 //\r
542 // 0x19\r
543 //\r
544 "EFI_SECTION_RAW",\r
545 //\r
546 // 0x1A\r
547 //\r
548 "Unknown section type - 0x1A",\r
549 //\r
550 // 0x1B\r
551 //\r
552 "EFI_SECTION_PEI_DEPEX",\r
553 //\r
554 // 0x1C\r
555 //\r
556 "EFI_SECTION_SMM_DEPEX",\r
557 //\r
558 // 0x1C+\r
559 //\r
560 "Unknown section type - Reserved - beyond last defined section"\r
561 };\r
562\r
563 if (Type > EFI_SECTION_LAST_SECTION_TYPE) {\r
564 Type = EFI_SECTION_LAST_SECTION_TYPE + 1;\r
565 }\r
566\r
567 SectionStr = malloc (100);\r
568 if (SectionStr == NULL) {\r
569 printf ("Error: Out of memory resources.\n");\r
570 return SectionStr;\r
571 }\r
572 strcpy (SectionStr, SectionTypeStringTable[Type]);\r
573 return SectionStr;\r
574}\r
575\r
576STATIC\r
577EFI_STATUS\r
578ReadHeader (\r
579 IN FILE *InputFile,\r
580 OUT UINT32 *FvSize,\r
581 OUT BOOLEAN *ErasePolarity\r
582 )\r
583/*++\r
584\r
585Routine Description:\r
586\r
587 This function determines the size of the FV and the erase polarity. The \r
588 erase polarity is the FALSE value for file state.\r
589\r
590Arguments:\r
591\r
592 InputFile The file that contains the FV image.\r
593 FvSize The size of the FV.\r
594 ErasePolarity The FV erase polarity.\r
595 \r
596Returns:\r
597 \r
598 EFI_SUCCESS Function completed successfully.\r
599 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.\r
600 EFI_ABORTED The function encountered an error.\r
601\r
602--*/\r
603{\r
604 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
605 EFI_FV_BLOCK_MAP_ENTRY BlockMap;\r
606 UINTN Signature[2];\r
607 UINTN BytesRead;\r
608 UINT32 Size;\r
609\r
610 BytesRead = 0;\r
611 Size = 0;\r
612 //\r
613 // Check input parameters\r
614 //\r
615 if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {\r
616 Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");\r
617 return EFI_INVALID_PARAMETER;\r
618 }\r
619 //\r
620 // Read the header\r
621 //\r
622 fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
623 BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
624 Signature[0] = VolumeHeader.Signature;\r
625 Signature[1] = 0;\r
626\r
627 //\r
628 // Print FV header information\r
629 //\r
630 printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);\r
631 printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);\r
632\r
633 if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {\r
634 printf (" EFI_FVB2_READ_DISABLED_CAP\n");\r
635 }\r
636\r
637 if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {\r
638 printf (" EFI_FVB2_READ_ENABLED_CAP\n");\r
639 }\r
640\r
641 if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {\r
642 printf (" EFI_FVB2_READ_STATUS\n");\r
643 }\r
644\r
645 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {\r
646 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");\r
647 }\r
648\r
649 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {\r
650 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");\r
651 }\r
652\r
653 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {\r
654 printf (" EFI_FVB2_WRITE_STATUS\n");\r
655 }\r
656\r
657 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {\r
658 printf (" EFI_FVB2_LOCK_CAP\n");\r
659 }\r
660\r
661 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {\r
662 printf (" EFI_FVB2_LOCK_STATUS\n");\r
663 }\r
664\r
665 if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {\r
666 printf (" EFI_FVB2_STICKY_WRITE\n");\r
667 }\r
668\r
669 if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {\r
670 printf (" EFI_FVB2_MEMORY_MAPPED\n");\r
671 }\r
672\r
673 if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {\r
674 printf (" EFI_FVB2_ERASE_POLARITY\n");\r
675 *ErasePolarity = TRUE;\r
676 }\r
677\r
678#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
679 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {\r
680 printf (" EFI_FVB2_ALIGNMENT\n");\r
681 }\r
682\r
683 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
684 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
685 }\r
686\r
687 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
688 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
689 }\r
690\r
691 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
692 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
693 }\r
694\r
695 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
696 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
697 }\r
698\r
699 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
700 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
701 }\r
702\r
703 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
704 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
705 }\r
706\r
707 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
708 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
709 }\r
710\r
711 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
712 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
713 }\r
714\r
715 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
716 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
717 }\r
718\r
719 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
720 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
721 }\r
722\r
723 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
724 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
725 }\r
726\r
727 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
728 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
729 }\r
730\r
731 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
732 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
733 }\r
734\r
735 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
736 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
737 }\r
738\r
739 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
740 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
741 }\r
742\r
743 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
744 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
745 }\r
746 \r
747#else\r
748\r
749 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {\r
750 printf (" EFI_FVB2_READ_LOCK_CAP\n");\r
751 }\r
752\r
753 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {\r
754 printf (" EFI_FVB2_READ_LOCK_STATUS\n");\r
755 }\r
756\r
757 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {\r
758 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");\r
759 }\r
760\r
761 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {\r
762 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");\r
763 }\r
764\r
765 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {\r
766 printf (" EFI_FVB2_ALIGNMENT_1\n");\r
767 }\r
768\r
769 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
770 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
771 }\r
772\r
773 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
774 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
775 }\r
776\r
777 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
778 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
779 }\r
780\r
781 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
782 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
783 }\r
784\r
785 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
786 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
787 }\r
788\r
789 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
790 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
791 }\r
792\r
793 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
794 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
795 }\r
796\r
797 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
798 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
799 }\r
800\r
801 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
802 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
803 }\r
804\r
805 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
806 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
807 }\r
808\r
809 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
810 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
811 }\r
812\r
813 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
814 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
815 }\r
816\r
817 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
818 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
819 }\r
820\r
821 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
822 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
823 }\r
824\r
825 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
826 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
827 }\r
828\r
829 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
830 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
831 }\r
832\r
833 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {\r
834 printf (" EFI_FVB2_ALIGNMENT_128K\n");\r
835 }\r
836\r
837 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {\r
838 printf (" EFI_FVB2_ALIGNMENT_256K\n");\r
839 }\r
840\r
841 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) {\r
842 printf (" EFI_FVB2_ALIGNMENT_512K\n");\r
843 }\r
844\r
845 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {\r
846 printf (" EFI_FVB2_ALIGNMENT_1M\n");\r
847 }\r
848\r
849 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {\r
850 printf (" EFI_FVB2_ALIGNMENT_2M\n");\r
851 }\r
852\r
853 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {\r
854 printf (" EFI_FVB2_ALIGNMENT_4M\n");\r
855 }\r
856\r
857 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {\r
858 printf (" EFI_FVB2_ALIGNMENT_8M\n");\r
859 }\r
860\r
861 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {\r
862 printf (" EFI_FVB2_ALIGNMENT_16M\n");\r
863 }\r
864\r
865 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {\r
866 printf (" EFI_FVB2_ALIGNMENT_32M\n");\r
867 }\r
868\r
869 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
870 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
871 }\r
872\r
873 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
874 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
875 }\r
876\r
877 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
878 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
879 }\r
880\r
881 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
882 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
883 }\r
884\r
885 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {\r
886 printf (" EFI_FVB2_ALIGNMENT_256M\n");\r
887 }\r
888\r
889 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {\r
890 printf (" EFI_FVB2_ALIGNMENT_512M\n");\r
891 }\r
892\r
893 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {\r
894 printf (" EFI_FVB2_ALIGNMENT_1G\n");\r
895 }\r
896\r
897 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {\r
898 printf (" EFI_FVB2_ALIGNMENT_2G\n");\r
899 }\r
900\r
901#endif\r
902 printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);\r
903 printf ("File System ID: ");\r
904 PrintGuid (&VolumeHeader.FileSystemGuid);\r
905 //\r
906 // printf ("\n");\r
907 //\r
908 printf ("Revision: 0x%04X\n", VolumeHeader.Revision);\r
909\r
910 do {\r
911 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
912 BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
913\r
914 if (BlockMap.NumBlocks != 0) {\r
915 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);\r
916 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);\r
917 Size += BlockMap.NumBlocks * BlockMap.Length;\r
918 }\r
919\r
920 } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));\r
921\r
922 if (BytesRead != VolumeHeader.HeaderLength) {\r
923 printf ("ERROR: Header length not consistent with Block Maps!\n");\r
924 return EFI_ABORTED;\r
925 }\r
926\r
927 if (VolumeHeader.FvLength != Size) {\r
928 printf ("ERROR: Volume Size not consistant with Block Maps!\n");\r
929 return EFI_ABORTED;\r
930 }\r
931\r
932 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);\r
933\r
934 *FvSize = Size;\r
935\r
936 //\r
937 // rewind (InputFile);\r
938 //\r
939 return EFI_SUCCESS;\r
940}\r
941\r
942STATIC\r
943EFI_STATUS\r
944PrintFileInfo (\r
945 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
946 EFI_FFS_FILE_HEADER *FileHeader,\r
947 BOOLEAN ErasePolarity\r
948 )\r
949/*++\r
950\r
951Routine Description:\r
952\r
953 GC_TODO: Add function description\r
954\r
955Arguments:\r
956\r
957 FvImage - GC_TODO: add argument description\r
958 FileHeader - GC_TODO: add argument description\r
959 ErasePolarity - GC_TODO: add argument description\r
960\r
961Returns:\r
962\r
963 EFI_SUCCESS - GC_TODO: Add description for return value\r
964 EFI_ABORTED - GC_TODO: Add description for return value\r
965\r
966--*/\r
967{\r
968 UINT32 FileLength;\r
969 UINT8 FileState;\r
970 UINT8 Checksum;\r
e4ac870f 971 EFI_FFS_FILE_HEADER2 BlankHeader;\r
f51461c8
LG
972 EFI_STATUS Status;\r
973 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
e4ac870f 974 UINT32 HeaderSize;\r
f51461c8
LG
975#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
976 UINT16 *Tail;\r
977#endif\r
978 //\r
979 // Check if we have free space\r
980 //\r
e4ac870f 981 HeaderSize = FvBufGetFfsHeaderSize(FileHeader);\r
f51461c8 982 if (ErasePolarity) {\r
e4ac870f 983 memset (&BlankHeader, -1, HeaderSize);\r
f51461c8 984 } else {\r
e4ac870f 985 memset (&BlankHeader, 0, HeaderSize);\r
f51461c8
LG
986 }\r
987\r
e4ac870f 988 if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {\r
f51461c8
LG
989 return EFI_SUCCESS;\r
990 }\r
991 //\r
992 // Print file information.\r
993 //\r
994 printf ("============================================================\n");\r
995\r
996 printf ("File Name: ");\r
997 PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);\r
998 printf ("%s ", GuidBuffer);\r
999 PrintGuidName (GuidBuffer);\r
1000 printf ("\n");\r
1001\r
1002 //\r
1003 // PrintGuid (&FileHeader->Name);\r
1004 // printf ("\n");\r
1005 //\r
e4ac870f 1006 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1007 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));\r
1008 printf ("File Length: 0x%08X\n", (unsigned) FileLength);\r
1009 printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);\r
1010 printf ("File State: 0x%02X\n", FileHeader->State);\r
1011\r
1012 //\r
1013 // Print file state\r
1014 //\r
1015 FileState = GetFileState (ErasePolarity, FileHeader);\r
1016\r
1017 switch (FileState) {\r
1018\r
1019 case EFI_FILE_HEADER_CONSTRUCTION:\r
1020 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");\r
1021 return EFI_SUCCESS;\r
1022\r
1023 case EFI_FILE_HEADER_INVALID:\r
1024 printf (" EFI_FILE_HEADER_INVALID\n");\r
1025 return EFI_SUCCESS;\r
1026\r
1027 case EFI_FILE_HEADER_VALID:\r
1028 printf (" EFI_FILE_HEADER_VALID\n");\r
e4ac870f 1029 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1030 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1031 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1032 if (Checksum != 0) {\r
1033 printf ("ERROR: Header checksum invalid.\n");\r
1034 return EFI_ABORTED;\r
1035 }\r
1036\r
1037 return EFI_SUCCESS;\r
1038\r
1039 case EFI_FILE_DELETED:\r
1040 printf (" EFI_FILE_DELETED\n");\r
1041\r
1042 case EFI_FILE_MARKED_FOR_UPDATE:\r
1043 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");\r
1044\r
1045 case EFI_FILE_DATA_VALID:\r
1046 printf (" EFI_FILE_DATA_VALID\n");\r
1047\r
1048 //\r
1049 // Calculate header checksum\r
1050 //\r
e4ac870f 1051 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1052 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1053 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1054 if (Checksum != 0) {\r
1055 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);\r
1056 return EFI_ABORTED;\r
1057 }\r
1058\r
e4ac870f 1059 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1060\r
1061 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
1062 //\r
1063 // Calculate file checksum\r
1064 //\r
e4ac870f 1065 Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);\r
f51461c8
LG
1066 Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;\r
1067 if (Checksum != 0) {\r
1068 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);\r
1069 return EFI_ABORTED;\r
1070 }\r
1071 } else {\r
1072 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
1073 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);\r
1074 return EFI_ABORTED;\r
1075 }\r
1076 }\r
1077#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
1078 //\r
1079 // Verify tail if present\r
1080 //\r
1081 if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
1082 //\r
1083 // Verify tail is complement of integrity check field in the header.\r
1084 //\r
1085 Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));\r
1086 if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {\r
1087 Error (NULL, 0, 0003, "error parsing FFS file", \\r
1088 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);\r
1089 return EFI_ABORTED;\r
1090 }\r
1091 }\r
1092 #endif \r
1093 break;\r
1094\r
1095 default:\r
1096 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);\r
1097 return EFI_ABORTED;\r
1098 }\r
1099\r
1100 printf ("File Type: 0x%02X ", FileHeader->Type);\r
1101\r
1102 switch (FileHeader->Type) {\r
1103\r
1104 case EFI_FV_FILETYPE_RAW:\r
1105 printf ("EFI_FV_FILETYPE_RAW\n");\r
1106 break;\r
1107\r
1108 case EFI_FV_FILETYPE_FREEFORM:\r
1109 printf ("EFI_FV_FILETYPE_FREEFORM\n");\r
1110 break;\r
1111\r
1112 case EFI_FV_FILETYPE_SECURITY_CORE:\r
1113 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");\r
1114 break;\r
1115\r
1116 case EFI_FV_FILETYPE_PEI_CORE:\r
1117 printf ("EFI_FV_FILETYPE_PEI_CORE\n");\r
1118 break;\r
1119\r
1120 case EFI_FV_FILETYPE_DXE_CORE:\r
1121 printf ("EFI_FV_FILETYPE_DXE_CORE\n");\r
1122 break;\r
1123\r
1124 case EFI_FV_FILETYPE_PEIM:\r
1125 printf ("EFI_FV_FILETYPE_PEIM\n");\r
1126 break;\r
1127\r
1128 case EFI_FV_FILETYPE_DRIVER:\r
1129 printf ("EFI_FV_FILETYPE_DRIVER\n");\r
1130 break;\r
1131\r
1132 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
1133 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");\r
1134 break;\r
1135\r
1136 case EFI_FV_FILETYPE_APPLICATION:\r
1137 printf ("EFI_FV_FILETYPE_APPLICATION\n");\r
1138 break;\r
1139\r
1140 case EFI_FV_FILETYPE_SMM:\r
1141 printf ("EFI_FV_FILETYPE_SMM\n");\r
1142 break;\r
1143\r
1144 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
1145 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");\r
1146 break;\r
1147\r
1148 case EFI_FV_FILETYPE_COMBINED_SMM_DXE:\r
1149 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");\r
1150 break;\r
1151\r
1152 case EFI_FV_FILETYPE_SMM_CORE:\r
1153 printf ("EFI_FV_FILETYPE_SMM_CORE\n");\r
1154 break;\r
1155\r
1156 case EFI_FV_FILETYPE_FFS_PAD:\r
1157 printf ("EFI_FV_FILETYPE_FFS_PAD\n");\r
1158 break;\r
1159\r
1160 default:\r
1161 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);\r
1162 return EFI_ABORTED;\r
1163 break;\r
1164 }\r
1165\r
1166 switch (FileHeader->Type) {\r
1167\r
1168 case EFI_FV_FILETYPE_ALL:\r
1169 case EFI_FV_FILETYPE_RAW:\r
1170 case EFI_FV_FILETYPE_FFS_PAD:\r
1171 break;\r
1172\r
1173 default:\r
1174 //\r
1175 // All other files have sections\r
1176 //\r
1177 Status = ParseSection (\r
e4ac870f
LG
1178 (UINT8 *) ((UINTN) FileHeader + HeaderSize),\r
1179 FvBufGetFfsFileSize (FileHeader) - HeaderSize\r
f51461c8
LG
1180 );\r
1181 if (EFI_ERROR (Status)) {\r
1182 //\r
1183 // printf ("ERROR: Parsing the FFS file.\n");\r
1184 //\r
1185 return EFI_ABORTED;\r
1186 }\r
1187 break;\r
1188 }\r
1189\r
1190 return EFI_SUCCESS;\r
1191}\r
1192\r
1193EFI_STATUS\r
1194ParseSection (\r
1195 IN UINT8 *SectionBuffer,\r
1196 IN UINT32 BufferLength\r
1197 )\r
1198/*++\r
1199\r
1200Routine Description:\r
1201\r
1202 Parses EFI Sections\r
1203\r
1204Arguments:\r
1205\r
1206 SectionBuffer - Buffer containing the section to parse.\r
1207 BufferLength - Length of SectionBuffer\r
1208\r
1209Returns:\r
1210\r
1211 EFI_SECTION_ERROR - Problem with section parsing.\r
1212 (a) compression errors\r
1213 (b) unrecognized section \r
1214 EFI_UNSUPPORTED - Do not know how to parse the section.\r
1215 EFI_SUCCESS - Section successfully parsed.\r
1216 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1217\r
1218--*/\r
1219{\r
1220 EFI_SECTION_TYPE Type;\r
1221 UINT8 *Ptr;\r
1222 UINT32 SectionLength;\r
e4ac870f 1223 UINT32 SectionHeaderLen;\r
f51461c8
LG
1224 CHAR8 *SectionName;\r
1225 EFI_STATUS Status;\r
1226 UINT32 ParsedLength;\r
1227 UINT8 *CompressedBuffer;\r
1228 UINT32 CompressedLength;\r
1229 UINT8 *UncompressedBuffer;\r
1230 UINT32 UncompressedLength;\r
1231 UINT8 *ToolOutputBuffer;\r
1232 UINT32 ToolOutputLength;\r
1233 UINT8 CompressionType;\r
1234 UINT32 DstSize;\r
1235 UINT32 ScratchSize;\r
1236 UINT8 *ScratchBuffer;\r
1237 DECOMPRESS_FUNCTION DecompressFunction;\r
1238 GETINFO_FUNCTION GetInfoFunction;\r
1239 // CHAR16 *name;\r
1240 CHAR8 *ExtractionTool;\r
1241 CHAR8 *ToolInputFile;\r
1242 CHAR8 *ToolOutputFile;\r
1243 CHAR8 *SystemCommandFormatString;\r
1244 CHAR8 *SystemCommand;\r
e4ac870f
LG
1245 EFI_GUID *EfiGuid;\r
1246 UINT16 DataOffset;\r
1247 UINT16 Attributes;\r
1248 UINT32 RealHdrLen;\r
f51461c8
LG
1249\r
1250 ParsedLength = 0;\r
1251 while (ParsedLength < BufferLength) {\r
1252 Ptr = SectionBuffer + ParsedLength;\r
1253\r
1254 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
1255 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
1256\r
1257 //\r
1258 // This is sort of an odd check, but is necessary because FFS files are\r
1259 // padded to a QWORD boundary, meaning there is potentially a whole section\r
1260 // header worth of 0xFF bytes.\r
1261 //\r
1262 if (SectionLength == 0xffffff && Type == 0xff) {\r
1263 ParsedLength += 4;\r
1264 continue;\r
1265 }\r
1266\r
e4ac870f
LG
1267 //\r
1268 // Get real section file size\r
1269 //\r
1270 SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);\r
1271 SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1272\r
f51461c8
LG
1273 SectionName = SectionNameToStr (Type);\r
1274 printf ("------------------------------------------------------------\n");\r
1275 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);\r
1276 free (SectionName);\r
1277\r
1278 switch (Type) {\r
1279 case EFI_SECTION_RAW:\r
1280 case EFI_SECTION_PE32:\r
1281 case EFI_SECTION_PIC:\r
1282 case EFI_SECTION_TE:\r
1283 // default is no more information\r
1284 break;\r
1285\r
1286 case EFI_SECTION_USER_INTERFACE:\r
1287 // name = &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString;\r
1288 // printf (" String: %s\n", &name);\r
1289 break;\r
1290\r
1291 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
e4ac870f 1292 Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);\r
f51461c8
LG
1293 if (EFI_ERROR (Status)) {\r
1294 Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);\r
1295 return EFI_SECTION_ERROR;\r
1296 }\r
1297 break;\r
1298\r
1299 case EFI_SECTION_COMPATIBILITY16:\r
1300 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
1301 //\r
1302 // Section does not contain any further header information.\r
1303 //\r
1304 break;\r
1305\r
1306 case EFI_SECTION_PEI_DEPEX:\r
1307 case EFI_SECTION_DXE_DEPEX:\r
1308 case EFI_SECTION_SMM_DEPEX:\r
1309 DumpDepexSection (Ptr, SectionLength);\r
1310 break;\r
1311\r
1312 case EFI_SECTION_VERSION:\r
e4ac870f
LG
1313 printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));\r
1314 printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));\r
f51461c8
LG
1315 break;\r
1316\r
1317 case EFI_SECTION_COMPRESSION:\r
1318 UncompressedBuffer = NULL;\r
e4ac870f
LG
1319 if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1320 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);\r
1321 UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;\r
1322 CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;\r
1323 } else {\r
1324 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);\r
1325 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;\r
1326 CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;\r
1327 }\r
1328 CompressedLength = SectionLength - RealHdrLen;\r
f51461c8
LG
1329 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);\r
1330\r
1331 if (CompressionType == EFI_NOT_COMPRESSED) {\r
1332 printf (" Compression Type: EFI_NOT_COMPRESSED\n");\r
1333 if (CompressedLength != UncompressedLength) {\r
1334 Error (\r
1335 NULL,\r
1336 0,\r
1337 0,\r
1338 "file is not compressed, but the compressed length does not match the uncompressed length",\r
1339 NULL\r
1340 );\r
1341 return EFI_SECTION_ERROR;\r
1342 }\r
1343\r
e4ac870f 1344 UncompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1345 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1346 GetInfoFunction = EfiGetInfo;\r
1347 DecompressFunction = EfiDecompress;\r
1348 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");\r
1349\r
e4ac870f 1350 CompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1351\r
1352 Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);\r
1353 if (EFI_ERROR (Status)) {\r
1354 Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);\r
1355 return EFI_SECTION_ERROR;\r
1356 }\r
1357\r
1358 if (DstSize != UncompressedLength) {\r
1359 Error (NULL, 0, 0003, "compression error in the compression section", NULL);\r
1360 return EFI_SECTION_ERROR;\r
1361 }\r
1362\r
1363 ScratchBuffer = malloc (ScratchSize);\r
1364 UncompressedBuffer = malloc (UncompressedLength);\r
1365 if ((ScratchBuffer == NULL) || (UncompressedBuffer == NULL)) {\r
1366 return EFI_OUT_OF_RESOURCES;\r
1367 }\r
1368 Status = DecompressFunction (\r
1369 CompressedBuffer,\r
1370 CompressedLength,\r
1371 UncompressedBuffer,\r
1372 UncompressedLength,\r
1373 ScratchBuffer,\r
1374 ScratchSize\r
1375 );\r
1376 free (ScratchBuffer);\r
1377 if (EFI_ERROR (Status)) {\r
1378 Error (NULL, 0, 0003, "decompress failed", NULL);\r
1379 free (UncompressedBuffer);\r
1380 return EFI_SECTION_ERROR;\r
1381 }\r
1382 } else {\r
1383 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);\r
1384 return EFI_SECTION_ERROR;\r
1385 }\r
1386\r
1387 Status = ParseSection (UncompressedBuffer, UncompressedLength);\r
1388\r
1389 if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1390 //\r
1391 // We need to deallocate Buffer\r
1392 //\r
1393 free (UncompressedBuffer);\r
1394 }\r
1395\r
1396 if (EFI_ERROR (Status)) {\r
1397 Error (NULL, 0, 0003, "failed to parse section", NULL);\r
1398 return EFI_SECTION_ERROR;\r
1399 }\r
1400 break;\r
1401\r
1402 case EFI_SECTION_GUID_DEFINED:\r
e4ac870f
LG
1403 if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {\r
1404 EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;\r
1405 DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;\r
1406 Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;\r
1407 } else {\r
1408 EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;\r
1409 DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;\r
1410 Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;\r
1411 }\r
f51461c8 1412 printf (" SectionDefinitionGuid: ");\r
e4ac870f 1413 PrintGuid (EfiGuid);\r
f51461c8 1414 printf ("\n");\r
e4ac870f
LG
1415 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);\r
1416 printf (" Attributes: 0x%04X\n", (unsigned) Attributes);\r
f51461c8
LG
1417\r
1418 ExtractionTool =\r
1419 LookupGuidedSectionToolPath (\r
1420 mParsedGuidedSectionTools,\r
e4ac870f 1421 EfiGuid\r
f51461c8
LG
1422 );\r
1423\r
1424 if (ExtractionTool != NULL) {\r
1425\r
1426 ToolInputFile = CloneString (tmpnam (NULL));\r
1427 ToolOutputFile = CloneString (tmpnam (NULL));\r
1428\r
1429 //\r
1430 // Construction 'system' command string\r
1431 //\r
1432 SystemCommandFormatString = "%s -d -o %s %s";\r
1433 SystemCommand = malloc (\r
1434 strlen (SystemCommandFormatString) +\r
1435 strlen (ExtractionTool) +\r
1436 strlen (ToolInputFile) +\r
1437 strlen (ToolOutputFile) +\r
1438 1\r
1439 );\r
1440 sprintf (\r
1441 SystemCommand,\r
1442 SystemCommandFormatString,\r
1443 ExtractionTool,\r
1444 ToolOutputFile,\r
1445 ToolInputFile\r
1446 );\r
1447 free (ExtractionTool);\r
1448\r
1449 Status =\r
1450 PutFileImage (\r
1451 ToolInputFile,\r
e4ac870f
LG
1452 (CHAR8*) SectionBuffer + DataOffset,\r
1453 BufferLength - DataOffset\r
f51461c8
LG
1454 );\r
1455\r
1456 system (SystemCommand);\r
1457 remove (ToolInputFile);\r
1458 free (ToolInputFile);\r
1459\r
1460 Status =\r
1461 GetFileImage (\r
1462 ToolOutputFile,\r
1463 (CHAR8 **)&ToolOutputBuffer,\r
1464 &ToolOutputLength\r
1465 );\r
1466 remove (ToolOutputFile);\r
1467 free (ToolOutputFile);\r
1468 if (EFI_ERROR (Status)) {\r
1469 Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);\r
1470 return EFI_SECTION_ERROR;\r
1471 }\r
1472\r
1473 Status = ParseSection (\r
1474 ToolOutputBuffer,\r
1475 ToolOutputLength\r
1476 );\r
1477 if (EFI_ERROR (Status)) {\r
1478 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);\r
1479 return EFI_SECTION_ERROR;\r
1480 }\r
1481\r
1482 //\r
1483 // Check for CRC32 sections which we can handle internally if needed.\r
1484 //\r
1485 } else if (!CompareGuid (\r
e4ac870f 1486 EfiGuid,\r
f51461c8
LG
1487 &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
1488 )\r
1489 ) {\r
1490 //\r
1491 // CRC32 guided section\r
1492 //\r
1493 Status = ParseSection (\r
e4ac870f
LG
1494 SectionBuffer + DataOffset,\r
1495 BufferLength - DataOffset\r
f51461c8
LG
1496 );\r
1497 if (EFI_ERROR (Status)) {\r
1498 Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);\r
1499 return EFI_SECTION_ERROR;\r
1500 }\r
1501 } else {\r
1502 //\r
1503 // We don't know how to parse it now.\r
1504 //\r
1505 Error (NULL, 0, 0003, "Error parsing section", \\r
1506 "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).");\r
1507 return EFI_UNSUPPORTED;\r
1508 }\r
1509 break;\r
1510\r
1511 default:\r
1512 //\r
1513 // Unknown section, return error\r
1514 //\r
1515 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);\r
1516 return EFI_SECTION_ERROR;\r
1517 }\r
1518\r
1519 ParsedLength += SectionLength;\r
1520 //\r
1521 // We make then next section begin on a 4-byte boundary\r
1522 //\r
1523 ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
1524 }\r
1525\r
1526 if (ParsedLength < BufferLength) {\r
1527 Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);\r
1528 return EFI_SECTION_ERROR;\r
1529 }\r
1530\r
1531 return EFI_SUCCESS;\r
1532}\r
1533\r
1534EFI_STATUS\r
1535DumpDepexSection (\r
1536 IN UINT8 *Ptr,\r
1537 IN UINT32 SectionLength\r
1538 )\r
1539/*++\r
1540\r
1541Routine Description:\r
1542\r
1543 GC_TODO: Add function description\r
1544\r
1545Arguments:\r
1546\r
1547 Ptr - GC_TODO: add argument description\r
1548 SectionLength - GC_TODO: add argument description\r
1549\r
1550Returns:\r
1551\r
1552 EFI_SUCCESS - GC_TODO: Add description for return value\r
1553\r
1554--*/\r
1555{\r
1556 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
1557\r
1558 //\r
1559 // Need at least a section header + data\r
1560 //\r
1561 if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1562 return EFI_SUCCESS;\r
1563 }\r
1564\r
e4ac870f
LG
1565 Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1566 SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
f51461c8
LG
1567 while (SectionLength > 0) {\r
1568 printf (" ");\r
1569 switch (*Ptr) {\r
1570 case EFI_DEP_BEFORE:\r
1571 printf ("BEFORE\n");\r
1572 Ptr++;\r
1573 SectionLength--;\r
1574 break;\r
1575\r
1576 case EFI_DEP_AFTER:\r
1577 printf ("AFTER\n");\r
1578 Ptr++;\r
1579 SectionLength--;\r
1580 break;\r
1581\r
1582 case EFI_DEP_PUSH:\r
1583 printf ("PUSH\n ");\r
1584 PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);\r
1585 printf ("%s ", GuidBuffer);\r
1586 PrintGuidName (GuidBuffer);\r
1587 printf ("\n");\r
1588 //\r
1589 // PrintGuid ((EFI_GUID *)(Ptr + 1));\r
1590 //\r
1591 Ptr += 17;\r
1592 SectionLength -= 17;\r
1593 break;\r
1594\r
1595 case EFI_DEP_AND:\r
1596 printf ("AND\n");\r
1597 Ptr++;\r
1598 SectionLength--;\r
1599 break;\r
1600\r
1601 case EFI_DEP_OR:\r
1602 printf ("OR\n");\r
1603 Ptr++;\r
1604 SectionLength--;\r
1605 break;\r
1606\r
1607 case EFI_DEP_NOT:\r
1608 printf ("NOT\n");\r
1609 Ptr++;\r
1610 SectionLength--;\r
1611 break;\r
1612\r
1613 case EFI_DEP_TRUE:\r
1614 printf ("TRUE\n");\r
1615 Ptr++;\r
1616 SectionLength--;\r
1617 break;\r
1618\r
1619 case EFI_DEP_FALSE:\r
1620 printf ("FALSE\n");\r
1621 Ptr++;\r
1622 SectionLength--;\r
1623 break;\r
1624\r
1625 case EFI_DEP_END:\r
1626 printf ("END DEPEX\n");\r
1627 Ptr++;\r
1628 SectionLength--;\r
1629 break;\r
1630\r
1631 case EFI_DEP_SOR:\r
1632 printf ("SOR\n");\r
1633 Ptr++;\r
1634 SectionLength--;\r
1635 break;\r
1636\r
1637 default:\r
1638 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);\r
1639 return EFI_SUCCESS;\r
1640 }\r
1641 }\r
1642\r
1643 return EFI_SUCCESS;\r
1644}\r
1645\r
1646EFI_STATUS\r
1647PrintGuidName (\r
1648 IN UINT8 *GuidStr\r
1649 )\r
1650/*++\r
1651\r
1652Routine Description:\r
1653\r
1654 GC_TODO: Add function description\r
1655\r
1656Arguments:\r
1657\r
1658 GuidStr - GC_TODO: add argument description\r
1659\r
1660Returns:\r
1661\r
1662 EFI_SUCCESS - GC_TODO: Add description for return value\r
1663 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
1664\r
1665--*/\r
1666{\r
1667 GUID_TO_BASENAME *GPtr;\r
1668 //\r
1669 // If we have a list of guid-to-basenames, then go through the list to\r
1670 // look for a guid string match. If found, print the basename to stdout,\r
1671 // otherwise return a failure.\r
1672 //\r
1673 GPtr = mGuidBaseNameList;\r
1674 while (GPtr != NULL) {\r
1675 if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {\r
1676 printf ("%s", GPtr->BaseName);\r
1677 return EFI_SUCCESS;\r
1678 }\r
1679\r
1680 GPtr = GPtr->Next;\r
1681 }\r
1682\r
1683 return EFI_INVALID_PARAMETER;\r
1684}\r
1685\r
1686EFI_STATUS\r
1687ParseGuidBaseNameFile (\r
1688 CHAR8 *FileName\r
1689 )\r
1690/*++\r
1691\r
1692Routine Description:\r
1693\r
1694 GC_TODO: Add function description\r
1695\r
1696Arguments:\r
1697\r
1698 FileName - GC_TODO: add argument description\r
1699\r
1700Returns:\r
1701\r
1702 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
1703 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value\r
1704 EFI_SUCCESS - GC_TODO: Add description for return value\r
1705\r
1706--*/\r
1707{\r
1708 FILE *Fptr;\r
1709 CHAR8 Line[MAX_LINE_LEN];\r
1710 GUID_TO_BASENAME *GPtr;\r
1711\r
97fa0ee9 1712 if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {\r
f51461c8
LG
1713 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);\r
1714 return EFI_DEVICE_ERROR;\r
1715 }\r
1716\r
1717 while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
1718 //\r
1719 // Allocate space for another guid/basename element\r
1720 //\r
1721 GPtr = malloc (sizeof (GUID_TO_BASENAME));\r
1722 if (GPtr == NULL) {\r
1723 return EFI_OUT_OF_RESOURCES;\r
1724 }\r
1725\r
1726 memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));\r
1727 if (sscanf (Line, "%s %s", GPtr->Guid, GPtr->BaseName) == 2) {\r
1728 GPtr->Next = mGuidBaseNameList;\r
1729 mGuidBaseNameList = GPtr;\r
1730 } else {\r
1731 //\r
1732 // Some sort of error. Just continue.\r
1733 //\r
1734 free (GPtr);\r
1735 }\r
1736 }\r
1737\r
1738 fclose (Fptr);\r
1739 return EFI_SUCCESS;\r
1740}\r
1741\r
1742EFI_STATUS\r
1743FreeGuidBaseNameList (\r
1744 VOID\r
1745 )\r
1746/*++\r
1747\r
1748Routine Description:\r
1749\r
1750 GC_TODO: Add function description\r
1751\r
1752Arguments:\r
1753\r
1754 None\r
1755\r
1756Returns:\r
1757\r
1758 EFI_SUCCESS - GC_TODO: Add description for return value\r
1759\r
1760--*/\r
1761{\r
1762 GUID_TO_BASENAME *Next;\r
1763\r
1764 while (mGuidBaseNameList != NULL) {\r
1765 Next = mGuidBaseNameList->Next;\r
1766 free (mGuidBaseNameList);\r
1767 mGuidBaseNameList = Next;\r
1768 }\r
1769\r
1770 return EFI_SUCCESS;\r
1771}\r
1772\r
1773\r
1774static\r
1775VOID\r
1776LoadGuidedSectionToolsTxt (\r
1777 IN CHAR8* FirmwareVolumeFilename\r
1778 )\r
1779{\r
1780 CHAR8* PeerFilename;\r
1781 CHAR8* Places[] = {\r
1782 NULL,\r
1783 //NULL,\r
1784 };\r
1785 UINTN Index;\r
1786\r
1787 Places[0] = FirmwareVolumeFilename;\r
1788 //Places[1] = mUtilityFilename;\r
1789\r
1790 mParsedGuidedSectionTools = NULL;\r
1791\r
1792 for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {\r
1793 PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");\r
1794 //printf("Loading %s...\n", PeerFilename);\r
1795 if (OsPathExists (PeerFilename)) {\r
1796 mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);\r
1797 }\r
1798 free (PeerFilename);\r
1799 if (mParsedGuidedSectionTools != NULL) {\r
1800 return;\r
1801 }\r
1802 }\r
1803}\r
1804\r
1805\r
1806void\r
1807Usage (\r
1808 VOID\r
1809 )\r
1810/*++\r
1811\r
1812Routine Description:\r
1813\r
1814 GC_TODO: Add function description\r
1815\r
1816Arguments:\r
1817\r
1818 None\r
1819\r
1820Returns:\r
1821\r
1822 GC_TODO: add return values\r
1823\r
1824--*/\r
1825{\r
1826 //\r
1827 // Summary usage\r
1828 //\r
1829 fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);\r
1830\r
1831 //\r
1832 // Copyright declaration\r
1833 // \r
e4ac870f 1834 fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
f4260465 1835 fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");\r
f51461c8
LG
1836\r
1837 //\r
1838 // Details Option\r
1839 //\r
1840 fprintf (stdout, "Options:\n");\r
1841 fprintf (stdout, " -x xref, --xref xref\n\\r
1842 Parse basename to file-guid cross reference file(s).\n");\r
1843 fprintf (stdout, " --offset offset\n\\r
1844 Offset of file to start processing FV at.\n");\r
1845 fprintf (stdout, " -h, --help\n\\r
1846 Show this help message and exit.\n");\r
1847\r
1848}\r
1849\r