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