]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VolInfo/VolInfo.c
BaseTools/VolInfo: Provide string width in '%s' specifier in format string
[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
45258285 4Copyright (c) 1999 - 2016, 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
868c9c35
YZ
20#ifdef __GNUC__\r
21#include <unistd.h>\r
9947f576
YZ
22#else\r
23#include <direct.h>\r
868c9c35 24#endif\r
f51461c8
LG
25\r
26#include <FvLib.h>\r
27#include <Common/UefiBaseTypes.h>\r
28#include <Common/UefiCapsule.h>\r
29#include <Common/PiFirmwareFile.h>\r
30#include <Common/PiFirmwareVolume.h>\r
31#include <Guid/PiFirmwareFileSystem.h>\r
32#include <IndustryStandard/PeImage.h>\r
33#include <Protocol/GuidedSectionExtraction.h>\r
34\r
35#include "Compress.h"\r
36#include "Decompress.h"\r
37#include "VolInfo.h"\r
38#include "CommonLib.h"\r
39#include "EfiUtilityMsgs.h"\r
40#include "FirmwareVolumeBufferLib.h"\r
41#include "OsPath.h"\r
42#include "ParseGuidedSectionTools.h"\r
43#include "StringFuncs.h"\r
730ffca1 44#include "ParseInf.h"\r
9947f576 45#include "PeCoffLib.h"\r
f51461c8
LG
46\r
47//\r
48// Utility global variables\r
49//\r
50\r
51EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
52\r
45258285
LG
53#define UTILITY_MAJOR_VERSION 1\r
54#define UTILITY_MINOR_VERSION 0\r
f51461c8
LG
55\r
56#define UTILITY_NAME "VolInfo"\r
57\r
58#define EFI_SECTION_ERROR EFIERR (100)\r
59\r
60#define MAX_BASENAME_LEN 60 // not good to hardcode, but let's be reasonable\r
61\r
62//\r
63// Structure to keep a list of guid-to-basenames\r
64//\r
65typedef struct _GUID_TO_BASENAME {\r
66 struct _GUID_TO_BASENAME *Next;\r
67 INT8 Guid[PRINTED_GUID_BUFFER_SIZE];\r
68 INT8 BaseName[MAX_BASENAME_LEN];\r
69} GUID_TO_BASENAME;\r
70\r
71static GUID_TO_BASENAME *mGuidBaseNameList = NULL;\r
72\r
73//\r
74// Store GUIDed Section guid->tool mapping\r
75//\r
76EFI_HANDLE mParsedGuidedSectionTools = NULL;\r
77\r
78CHAR8* mUtilityFilename = NULL;\r
79\r
9947f576
YZ
80BOOLEAN EnableHash = FALSE;\r
81CHAR8 *OpenSslPath = NULL;\r
82\r
f51461c8
LG
83EFI_STATUS\r
84ParseGuidBaseNameFile (\r
85 CHAR8 *FileName\r
86 );\r
87\r
88EFI_STATUS\r
89FreeGuidBaseNameList (\r
90 VOID\r
91 );\r
92\r
93EFI_STATUS\r
94PrintGuidName (\r
95 IN UINT8 *GuidStr\r
96 );\r
97\r
98EFI_STATUS\r
99ParseSection (\r
100 IN UINT8 *SectionBuffer,\r
101 IN UINT32 BufferLength\r
102 );\r
103\r
104EFI_STATUS\r
105DumpDepexSection (\r
106 IN UINT8 *Ptr,\r
107 IN UINT32 SectionLength\r
108 );\r
109\r
110STATIC\r
111EFI_STATUS\r
112ReadHeader (\r
113 IN FILE *InputFile,\r
114 OUT UINT32 *FvSize,\r
115 OUT BOOLEAN *ErasePolarity\r
116 );\r
117\r
118STATIC\r
119EFI_STATUS\r
120PrintFileInfo (\r
121 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
122 EFI_FFS_FILE_HEADER *FileHeader,\r
123 BOOLEAN ErasePolarity\r
124 );\r
125\r
126static\r
127EFI_STATUS\r
128PrintFvInfo (\r
129 IN VOID *Fv,\r
130 IN BOOLEAN IsChildFv\r
131 );\r
132\r
133static\r
134VOID\r
135LoadGuidedSectionToolsTxt (\r
136 IN CHAR8* FirmwareVolumeFilename\r
137 );\r
138\r
9947f576
YZ
139EFI_STATUS\r
140CombinePath (\r
141 IN CHAR8* DefaultPath,\r
142 IN CHAR8* AppendPath,\r
143 OUT CHAR8* NewPath\r
144);\r
145\r
f51461c8
LG
146void\r
147Usage (\r
148 VOID\r
149 );\r
150\r
151int\r
152main (\r
153 int argc,\r
154 char *argv[]\r
155 )\r
156/*++\r
157\r
158Routine Description:\r
159\r
160 GC_TODO: Add function description\r
161\r
162Arguments:\r
163\r
164 argc - GC_TODO: add argument description\r
165 ] - GC_TODO: add argument description\r
166\r
167Returns:\r
168\r
169 GC_TODO: add return values\r
170\r
171--*/\r
172{\r
173 FILE *InputFile;\r
174 int BytesRead;\r
175 EFI_FIRMWARE_VOLUME_HEADER *FvImage;\r
176 UINT32 FvSize;\r
177 EFI_STATUS Status;\r
178 int Offset;\r
179 BOOLEAN ErasePolarity;\r
730ffca1 180 UINT64 LogLevel;\r
9947f576
YZ
181 CHAR8 *OpenSslEnv;\r
182 CHAR8 *OpenSslCommand;\r
f51461c8
LG
183\r
184 SetUtilityName (UTILITY_NAME);\r
185 //\r
186 // Print utility header\r
187 //\r
45258285 188 printf ("%s Version %d.%d Build %s\n",\r
f51461c8
LG
189 UTILITY_NAME,\r
190 UTILITY_MAJOR_VERSION,\r
191 UTILITY_MINOR_VERSION,\r
45258285 192 __BUILD_VERSION\r
f51461c8
LG
193 );\r
194\r
730ffca1
YZ
195 if (argc == 1) {\r
196 Usage ();\r
197 return -1;\r
198 }\r
199\r
f51461c8
LG
200 argc--;\r
201 argv++;\r
730ffca1 202 LogLevel = 0;\r
f51461c8
LG
203 Offset = 0;\r
204\r
730ffca1
YZ
205 //\r
206 // Look for help options\r
207 //\r
208 if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) ||\r
209 (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {\r
210 Usage();\r
211 return STATUS_SUCCESS;\r
212 }\r
213 //\r
214 // Version has already be printed, so just return success\r
215 //\r
216 if (strcmp(argv[0], "--version") == 0) {\r
217 return STATUS_SUCCESS;\r
218 }\r
219\r
f51461c8
LG
220 //\r
221 // If they specified -x xref guid/basename cross-reference files, process it.\r
222 // This will print the basename beside each file guid. To use it, specify\r
223 // -x xref_filename to processdsc, then use xref_filename as a parameter\r
224 // here.\r
225 //\r
730ffca1 226 while (argc > 0) {\r
f51461c8
LG
227 if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {\r
228 ParseGuidBaseNameFile (argv[1]);\r
229 printf("ParseGuidBaseNameFile: %s\n", argv[1]);\r
230 argc -= 2;\r
231 argv += 2;\r
730ffca1
YZ
232 continue;\r
233 }\r
234 if (strcmp(argv[0], "--offset") == 0) {\r
f51461c8
LG
235 //\r
236 // Hex or decimal?\r
237 //\r
238 if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {\r
239 if (sscanf (argv[1], "%x", &Offset) != 1) {\r
240 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
241 return GetUtilityStatus ();\r
242 }\r
243 } else {\r
244 if (sscanf (argv[1], "%d", &Offset) != 1) {\r
245 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);\r
246 return GetUtilityStatus ();\r
247 }\r
248 //\r
249 // See if they said something like "64K"\r
250 //\r
251 if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {\r
252 Offset *= 1024;\r
253 }\r
254 }\r
255\r
256 argc -= 2;\r
257 argv += 2;\r
730ffca1 258 continue;\r
f51461c8 259 }\r
9947f576 260 if ((stricmp (argv[0], "--hash") == 0)) {\r
85006654
HW
261 if (EnableHash == TRUE) {\r
262 //\r
263 // --hash already given in the option, ignore this one\r
264 //\r
265 argc --;\r
266 argv ++;\r
267 continue;\r
268 }\r
9947f576
YZ
269 EnableHash = TRUE;\r
270 OpenSslCommand = "openssl";\r
271 OpenSslEnv = getenv("OPENSSL_PATH");\r
272 if (OpenSslEnv == NULL) {\r
273 OpenSslPath = OpenSslCommand;\r
274 } else {\r
275 OpenSslPath = malloc(strlen(OpenSslEnv)+strlen(OpenSslCommand)+1);\r
9dd00cb6
HW
276 if (OpenSslPath == NULL) {\r
277 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
278 return GetUtilityStatus ();\r
279 }\r
9947f576
YZ
280 CombinePath(OpenSslEnv, OpenSslCommand, OpenSslPath);\r
281 }\r
282 if (OpenSslPath == NULL){\r
283 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
284 return GetUtilityStatus ();\r
285 }\r
286 argc --;\r
287 argv ++;\r
288 continue;\r
289 }\r
730ffca1
YZ
290\r
291 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
292 SetPrintLevel (VERBOSE_LOG_LEVEL);\r
293 argc --;\r
294 argv ++;\r
295 continue;\r
296 }\r
297\r
298 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
299 SetPrintLevel (KEY_LOG_LEVEL);\r
300 argc --;\r
301 argv ++;\r
302 continue;\r
303 }\r
304\r
305 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
306 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
307 if (EFI_ERROR (Status)) {\r
308 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
309 return -1;\r
310 }\r
311 if (LogLevel > 9) {\r
312 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
313 return -1;\r
314 }\r
315 SetPrintLevel (LogLevel);\r
316 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
317 argc -= 2;\r
318 argv += 2;\r
319 continue;\r
320 }\r
321\r
322 mUtilityFilename = argv[0];\r
323 argc --;\r
324 argv ++;\r
f51461c8 325 }\r
730ffca1 326\r
f51461c8
LG
327 //\r
328 // Open the file containing the FV\r
329 //\r
730ffca1
YZ
330 if (mUtilityFilename == NULL) {\r
331 Error (NULL, 0, 1001, "Missing option", "Input files are not specified");\r
332 return GetUtilityStatus ();\r
333 }\r
334 InputFile = fopen (LongFilePath (mUtilityFilename), "rb");\r
f51461c8 335 if (InputFile == NULL) {\r
730ffca1 336 Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename);\r
f51461c8
LG
337 return GetUtilityStatus ();\r
338 }\r
339 //\r
340 // Skip over pad bytes if specified. This is used if they prepend 0xff\r
341 // data to the FV image binary.\r
342 //\r
343 if (Offset != 0) {\r
344 fseek (InputFile, Offset, SEEK_SET);\r
345 }\r
346 //\r
347 // Determine size of FV\r
348 //\r
349 Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);\r
350 if (EFI_ERROR (Status)) {\r
730ffca1 351 Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename);\r
f51461c8
LG
352 fclose (InputFile);\r
353 return GetUtilityStatus ();\r
354 }\r
355 //\r
356 // Allocate a buffer for the FV image\r
357 //\r
358 FvImage = malloc (FvSize);\r
359 if (FvImage == NULL) {\r
360 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);\r
361 fclose (InputFile);\r
362 return GetUtilityStatus ();\r
363 }\r
364 //\r
365 // Seek to the start of the image, then read the entire FV to the buffer\r
366 //\r
367 fseek (InputFile, Offset, SEEK_SET);\r
368 BytesRead = fread (FvImage, 1, FvSize, InputFile);\r
369 fclose (InputFile);\r
370 if ((unsigned int) BytesRead != FvSize) {\r
730ffca1 371 Error (NULL, 0, 0004, "error reading FvImage from", mUtilityFilename);\r
f51461c8
LG
372 free (FvImage);\r
373 return GetUtilityStatus ();\r
374 }\r
375\r
730ffca1 376 LoadGuidedSectionToolsTxt (mUtilityFilename);\r
f51461c8
LG
377\r
378 PrintFvInfo (FvImage, FALSE);\r
379\r
380 //\r
381 // Clean up\r
382 //\r
383 free (FvImage);\r
384 FreeGuidBaseNameList ();\r
385 return GetUtilityStatus ();\r
386}\r
387\r
388\r
389static\r
390EFI_STATUS\r
391PrintFvInfo (\r
392 IN VOID *Fv,\r
393 IN BOOLEAN IsChildFv\r
394 )\r
395/*++\r
396\r
397Routine Description:\r
398\r
399 GC_TODO: Add function description\r
400\r
401Arguments:\r
402\r
403 Fv - Firmware Volume to print information about\r
404 IsChildFv - Flag specifies whether the input FV is a child FV.\r
405\r
406Returns:\r
407\r
408 EFI_STATUS\r
409\r
410--*/\r
411{\r
412 EFI_STATUS Status;\r
413 UINTN NumberOfFiles;\r
414 BOOLEAN ErasePolarity;\r
415 UINTN FvSize;\r
416 EFI_FFS_FILE_HEADER *CurrentFile;\r
417 UINTN Key;\r
418\r
419 Status = FvBufGetSize (Fv, &FvSize);\r
420\r
421 NumberOfFiles = 0;\r
422 ErasePolarity =\r
423 (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?\r
424 TRUE : FALSE;\r
425\r
426 //\r
427 // Get the first file\r
428 //\r
429 Key = 0;\r
430 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
431 if (EFI_ERROR (Status)) {\r
432 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");\r
433 return GetUtilityStatus ();\r
434 }\r
435 //\r
436 // Display information about files found\r
437 //\r
438 while (CurrentFile != NULL) {\r
439 //\r
440 // Increment the number of files counter\r
441 //\r
442 NumberOfFiles++;\r
443\r
444 //\r
445 // Display info about this file\r
446 //\r
447 Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);\r
448 if (EFI_ERROR (Status)) {\r
449 Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");\r
450 return GetUtilityStatus ();\r
451 }\r
452 //\r
453 // Get the next file\r
454 //\r
455 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);\r
456 if (Status == EFI_NOT_FOUND) {\r
457 CurrentFile = NULL;\r
458 } else if (EFI_ERROR (Status)) {\r
459 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");\r
460 return GetUtilityStatus ();\r
461 }\r
462 }\r
463\r
464 if (IsChildFv) {\r
465 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles);\r
466 } else {\r
467 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles);\r
468 }\r
469\r
470 return EFI_SUCCESS;\r
471}\r
472\r
473UINT32\r
474GetOccupiedSize (\r
475 IN UINT32 ActualSize,\r
476 IN UINT32 Alignment\r
477 )\r
478/*++\r
479\r
480Routine Description:\r
481\r
482 This function returns the next larger size that meets the alignment \r
483 requirement specified.\r
484\r
485Arguments:\r
486\r
487 ActualSize The size.\r
488 Alignment The desired alignment.\r
489 \r
490Returns:\r
491 \r
492 EFI_SUCCESS Function completed successfully.\r
493 EFI_ABORTED The function encountered an error.\r
494\r
495--*/\r
496{\r
497 UINT32 OccupiedSize;\r
498\r
499 OccupiedSize = ActualSize;\r
500 while ((OccupiedSize & (Alignment - 1)) != 0) {\r
501 OccupiedSize++;\r
502 }\r
503\r
504 return OccupiedSize;\r
505}\r
506\r
507static\r
508CHAR8 *\r
509SectionNameToStr (\r
510 IN EFI_SECTION_TYPE Type\r
511 )\r
512/*++\r
513\r
514Routine Description:\r
515\r
516 Converts EFI Section names to Strings\r
517\r
518Arguments:\r
519\r
520 Type - The EFI Section type\r
521\r
522Returns:\r
523\r
524 CHAR8* - Pointer to the String containing the section name.\r
525\r
526--*/\r
527{\r
528 CHAR8 *SectionStr;\r
529 CHAR8 *SectionTypeStringTable[] = {\r
530 //\r
531 // 0X00\r
532 //\r
533 "EFI_SECTION_ALL",\r
534 //\r
535 // 0x01\r
536 //\r
537 "EFI_SECTION_COMPRESSION",\r
538 //\r
539 // 0x02\r
540 //\r
541 "EFI_SECTION_GUID_DEFINED", \r
542 //\r
543 // 0x03\r
544 //\r
545 "Unknown section type - Reserved 0x03",\r
546 //\r
547 // 0x04\r
548 //\r
549 "Unknown section type - Reserved 0x04",\r
550 //\r
551 // 0x05\r
552 //\r
553 "Unknown section type - Reserved 0x05",\r
554 //\r
555 // 0x06\r
556 //\r
557 "Unknown section type - Reserved 0x06",\r
558 //\r
559 // 0x07\r
560 //\r
561 "Unknown section type - Reserved 0x07",\r
562 //\r
563 // 0x08\r
564 //\r
565 "Unknown section type - Reserved 0x08",\r
566 //\r
567 // 0x09\r
568 //\r
569 "Unknown section type - Reserved 0x09",\r
570 //\r
571 // 0x0A\r
572 //\r
573 "Unknown section type - Reserved 0x0A",\r
574 //\r
575 // 0x0B\r
576 //\r
577 "Unknown section type - Reserved 0x0B",\r
578 //\r
579 // 0x0C\r
580 //\r
581 "Unknown section type - Reserved 0x0C",\r
582 //\r
583 // 0x0D\r
584 //\r
585 "Unknown section type - Reserved 0x0D",\r
586 //\r
587 // 0x0E\r
588 //\r
589 "Unknown section type - Reserved 0x0E",\r
590 //\r
591 // 0x0F\r
592 //\r
593 "Unknown section type - Reserved 0x0E",\r
594 //\r
595 // 0x10\r
596 //\r
597 "EFI_SECTION_PE32",\r
598 //\r
599 // 0x11\r
600 //\r
601 "EFI_SECTION_PIC",\r
602 //\r
603 // 0x12\r
604 //\r
605 "EFI_SECTION_TE", \r
606 //\r
607 // 0x13\r
608 //\r
609 "EFI_SECTION_DXE_DEPEX", \r
610 //\r
611 // 0x14\r
612 //\r
613 "EFI_SECTION_VERSION",\r
614 //\r
615 // 0x15\r
616 //\r
617 "EFI_SECTION_USER_INTERFACE",\r
618 //\r
619 // 0x16\r
620 //\r
621 "EFI_SECTION_COMPATIBILITY16",\r
622 //\r
623 // 0x17\r
624 //\r
625 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",\r
626 //\r
627 // 0x18\r
628 //\r
629 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",\r
630 //\r
631 // 0x19\r
632 //\r
633 "EFI_SECTION_RAW",\r
634 //\r
635 // 0x1A\r
636 //\r
637 "Unknown section type - 0x1A",\r
638 //\r
639 // 0x1B\r
640 //\r
641 "EFI_SECTION_PEI_DEPEX",\r
642 //\r
643 // 0x1C\r
644 //\r
645 "EFI_SECTION_SMM_DEPEX",\r
646 //\r
647 // 0x1C+\r
648 //\r
649 "Unknown section type - Reserved - beyond last defined section"\r
650 };\r
651\r
652 if (Type > EFI_SECTION_LAST_SECTION_TYPE) {\r
653 Type = EFI_SECTION_LAST_SECTION_TYPE + 1;\r
654 }\r
655\r
656 SectionStr = malloc (100);\r
657 if (SectionStr == NULL) {\r
658 printf ("Error: Out of memory resources.\n");\r
659 return SectionStr;\r
660 }\r
661 strcpy (SectionStr, SectionTypeStringTable[Type]);\r
662 return SectionStr;\r
663}\r
664\r
665STATIC\r
666EFI_STATUS\r
667ReadHeader (\r
668 IN FILE *InputFile,\r
669 OUT UINT32 *FvSize,\r
670 OUT BOOLEAN *ErasePolarity\r
671 )\r
672/*++\r
673\r
674Routine Description:\r
675\r
676 This function determines the size of the FV and the erase polarity. The \r
677 erase polarity is the FALSE value for file state.\r
678\r
679Arguments:\r
680\r
681 InputFile The file that contains the FV image.\r
682 FvSize The size of the FV.\r
683 ErasePolarity The FV erase polarity.\r
684 \r
685Returns:\r
686 \r
687 EFI_SUCCESS Function completed successfully.\r
688 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.\r
689 EFI_ABORTED The function encountered an error.\r
690\r
691--*/\r
692{\r
693 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
694 EFI_FV_BLOCK_MAP_ENTRY BlockMap;\r
695 UINTN Signature[2];\r
696 UINTN BytesRead;\r
697 UINT32 Size;\r
698\r
699 BytesRead = 0;\r
700 Size = 0;\r
701 //\r
702 // Check input parameters\r
703 //\r
704 if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {\r
705 Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");\r
706 return EFI_INVALID_PARAMETER;\r
707 }\r
708 //\r
709 // Read the header\r
710 //\r
711 fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
712 BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
713 Signature[0] = VolumeHeader.Signature;\r
714 Signature[1] = 0;\r
715\r
716 //\r
717 // Print FV header information\r
718 //\r
719 printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);\r
720 printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);\r
721\r
722 if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {\r
723 printf (" EFI_FVB2_READ_DISABLED_CAP\n");\r
724 }\r
725\r
726 if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {\r
727 printf (" EFI_FVB2_READ_ENABLED_CAP\n");\r
728 }\r
729\r
730 if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {\r
731 printf (" EFI_FVB2_READ_STATUS\n");\r
732 }\r
733\r
734 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {\r
735 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");\r
736 }\r
737\r
738 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {\r
739 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");\r
740 }\r
741\r
742 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {\r
743 printf (" EFI_FVB2_WRITE_STATUS\n");\r
744 }\r
745\r
746 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {\r
747 printf (" EFI_FVB2_LOCK_CAP\n");\r
748 }\r
749\r
750 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {\r
751 printf (" EFI_FVB2_LOCK_STATUS\n");\r
752 }\r
753\r
754 if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {\r
755 printf (" EFI_FVB2_STICKY_WRITE\n");\r
756 }\r
757\r
758 if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {\r
759 printf (" EFI_FVB2_MEMORY_MAPPED\n");\r
760 }\r
761\r
762 if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {\r
763 printf (" EFI_FVB2_ERASE_POLARITY\n");\r
764 *ErasePolarity = TRUE;\r
765 }\r
766\r
767#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
768 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {\r
769 printf (" EFI_FVB2_ALIGNMENT\n");\r
770 }\r
771\r
772 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
773 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
774 }\r
775\r
776 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
777 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
778 }\r
779\r
780 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
781 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
782 }\r
783\r
784 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
785 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
786 }\r
787\r
788 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
789 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
790 }\r
791\r
792 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
793 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
794 }\r
795\r
796 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
797 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
798 }\r
799\r
800 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
801 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
802 }\r
803\r
804 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
805 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
806 }\r
807\r
808 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
809 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
810 }\r
811\r
812 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
813 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
814 }\r
815\r
816 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
817 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
818 }\r
819\r
820 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
821 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
822 }\r
823\r
824 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
825 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
826 }\r
827\r
828 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
829 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
830 }\r
831\r
832 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
833 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
834 }\r
835 \r
836#else\r
837\r
838 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {\r
839 printf (" EFI_FVB2_READ_LOCK_CAP\n");\r
840 }\r
841\r
842 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {\r
843 printf (" EFI_FVB2_READ_LOCK_STATUS\n");\r
844 }\r
845\r
846 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {\r
847 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");\r
848 }\r
849\r
850 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {\r
851 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");\r
852 }\r
853\r
854 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {\r
855 printf (" EFI_FVB2_ALIGNMENT_1\n");\r
856 }\r
857\r
858 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {\r
859 printf (" EFI_FVB2_ALIGNMENT_2\n");\r
860 }\r
861\r
862 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {\r
863 printf (" EFI_FVB2_ALIGNMENT_4\n");\r
864 }\r
865\r
866 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {\r
867 printf (" EFI_FVB2_ALIGNMENT_8\n");\r
868 }\r
869\r
870 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {\r
871 printf (" EFI_FVB2_ALIGNMENT_16\n");\r
872 }\r
873\r
874 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {\r
875 printf (" EFI_FVB2_ALIGNMENT_32\n");\r
876 }\r
877\r
878 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {\r
879 printf (" EFI_FVB2_ALIGNMENT_64\n");\r
880 }\r
881\r
882 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {\r
883 printf (" EFI_FVB2_ALIGNMENT_128\n");\r
884 }\r
885\r
886 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {\r
887 printf (" EFI_FVB2_ALIGNMENT_256\n");\r
888 }\r
889\r
890 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {\r
891 printf (" EFI_FVB2_ALIGNMENT_512\n");\r
892 }\r
893\r
894 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {\r
895 printf (" EFI_FVB2_ALIGNMENT_1K\n");\r
896 }\r
897\r
898 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {\r
899 printf (" EFI_FVB2_ALIGNMENT_2K\n");\r
900 }\r
901\r
902 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {\r
903 printf (" EFI_FVB2_ALIGNMENT_4K\n");\r
904 }\r
905\r
906 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {\r
907 printf (" EFI_FVB2_ALIGNMENT_8K\n");\r
908 }\r
909\r
910 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {\r
911 printf (" EFI_FVB2_ALIGNMENT_16K\n");\r
912 }\r
913\r
914 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {\r
915 printf (" EFI_FVB2_ALIGNMENT_32K\n");\r
916 }\r
917\r
918 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {\r
919 printf (" EFI_FVB2_ALIGNMENT_64K\n");\r
920 }\r
921\r
922 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {\r
923 printf (" EFI_FVB2_ALIGNMENT_128K\n");\r
924 }\r
925\r
926 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {\r
927 printf (" EFI_FVB2_ALIGNMENT_256K\n");\r
928 }\r
929\r
930 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) {\r
931 printf (" EFI_FVB2_ALIGNMENT_512K\n");\r
932 }\r
933\r
934 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {\r
935 printf (" EFI_FVB2_ALIGNMENT_1M\n");\r
936 }\r
937\r
938 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {\r
939 printf (" EFI_FVB2_ALIGNMENT_2M\n");\r
940 }\r
941\r
942 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {\r
943 printf (" EFI_FVB2_ALIGNMENT_4M\n");\r
944 }\r
945\r
946 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {\r
947 printf (" EFI_FVB2_ALIGNMENT_8M\n");\r
948 }\r
949\r
950 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {\r
951 printf (" EFI_FVB2_ALIGNMENT_16M\n");\r
952 }\r
953\r
954 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {\r
955 printf (" EFI_FVB2_ALIGNMENT_32M\n");\r
956 }\r
957\r
958 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
959 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
960 }\r
961\r
962 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
963 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
964 }\r
965\r
966 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {\r
967 printf (" EFI_FVB2_ALIGNMENT_64M\n");\r
968 }\r
969\r
970 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {\r
971 printf (" EFI_FVB2_ALIGNMENT_128M\n");\r
972 }\r
973\r
974 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {\r
975 printf (" EFI_FVB2_ALIGNMENT_256M\n");\r
976 }\r
977\r
978 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {\r
979 printf (" EFI_FVB2_ALIGNMENT_512M\n");\r
980 }\r
981\r
982 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {\r
983 printf (" EFI_FVB2_ALIGNMENT_1G\n");\r
984 }\r
985\r
986 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {\r
987 printf (" EFI_FVB2_ALIGNMENT_2G\n");\r
988 }\r
989\r
990#endif\r
991 printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);\r
992 printf ("File System ID: ");\r
993 PrintGuid (&VolumeHeader.FileSystemGuid);\r
994 //\r
995 // printf ("\n");\r
996 //\r
997 printf ("Revision: 0x%04X\n", VolumeHeader.Revision);\r
998\r
999 do {\r
1000 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
1001 BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
1002\r
1003 if (BlockMap.NumBlocks != 0) {\r
1004 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);\r
1005 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);\r
1006 Size += BlockMap.NumBlocks * BlockMap.Length;\r
1007 }\r
1008\r
1009 } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));\r
1010\r
1011 if (BytesRead != VolumeHeader.HeaderLength) {\r
1012 printf ("ERROR: Header length not consistent with Block Maps!\n");\r
1013 return EFI_ABORTED;\r
1014 }\r
1015\r
1016 if (VolumeHeader.FvLength != Size) {\r
1017 printf ("ERROR: Volume Size not consistant with Block Maps!\n");\r
1018 return EFI_ABORTED;\r
1019 }\r
1020\r
1021 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);\r
1022\r
1023 *FvSize = Size;\r
1024\r
1025 //\r
1026 // rewind (InputFile);\r
1027 //\r
1028 return EFI_SUCCESS;\r
1029}\r
1030\r
1031STATIC\r
1032EFI_STATUS\r
1033PrintFileInfo (\r
1034 EFI_FIRMWARE_VOLUME_HEADER *FvImage,\r
1035 EFI_FFS_FILE_HEADER *FileHeader,\r
1036 BOOLEAN ErasePolarity\r
1037 )\r
1038/*++\r
1039\r
1040Routine Description:\r
1041\r
1042 GC_TODO: Add function description\r
1043\r
1044Arguments:\r
1045\r
1046 FvImage - GC_TODO: add argument description\r
1047 FileHeader - GC_TODO: add argument description\r
1048 ErasePolarity - GC_TODO: add argument description\r
1049\r
1050Returns:\r
1051\r
1052 EFI_SUCCESS - GC_TODO: Add description for return value\r
1053 EFI_ABORTED - GC_TODO: Add description for return value\r
1054\r
1055--*/\r
1056{\r
1057 UINT32 FileLength;\r
1058 UINT8 FileState;\r
1059 UINT8 Checksum;\r
e4ac870f 1060 EFI_FFS_FILE_HEADER2 BlankHeader;\r
f51461c8
LG
1061 EFI_STATUS Status;\r
1062 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
e4ac870f 1063 UINT32 HeaderSize;\r
f51461c8
LG
1064#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
1065 UINT16 *Tail;\r
1066#endif\r
1067 //\r
1068 // Check if we have free space\r
1069 //\r
e4ac870f 1070 HeaderSize = FvBufGetFfsHeaderSize(FileHeader);\r
f51461c8 1071 if (ErasePolarity) {\r
e4ac870f 1072 memset (&BlankHeader, -1, HeaderSize);\r
f51461c8 1073 } else {\r
e4ac870f 1074 memset (&BlankHeader, 0, HeaderSize);\r
f51461c8
LG
1075 }\r
1076\r
e4ac870f 1077 if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {\r
f51461c8
LG
1078 return EFI_SUCCESS;\r
1079 }\r
1080 //\r
1081 // Print file information.\r
1082 //\r
1083 printf ("============================================================\n");\r
1084\r
1085 printf ("File Name: ");\r
1086 PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);\r
1087 printf ("%s ", GuidBuffer);\r
1088 PrintGuidName (GuidBuffer);\r
1089 printf ("\n");\r
1090\r
1091 //\r
1092 // PrintGuid (&FileHeader->Name);\r
1093 // printf ("\n");\r
1094 //\r
e4ac870f 1095 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1096 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));\r
1097 printf ("File Length: 0x%08X\n", (unsigned) FileLength);\r
1098 printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);\r
1099 printf ("File State: 0x%02X\n", FileHeader->State);\r
1100\r
1101 //\r
1102 // Print file state\r
1103 //\r
1104 FileState = GetFileState (ErasePolarity, FileHeader);\r
1105\r
1106 switch (FileState) {\r
1107\r
1108 case EFI_FILE_HEADER_CONSTRUCTION:\r
1109 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");\r
1110 return EFI_SUCCESS;\r
1111\r
1112 case EFI_FILE_HEADER_INVALID:\r
1113 printf (" EFI_FILE_HEADER_INVALID\n");\r
1114 return EFI_SUCCESS;\r
1115\r
1116 case EFI_FILE_HEADER_VALID:\r
1117 printf (" EFI_FILE_HEADER_VALID\n");\r
e4ac870f 1118 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1119 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1120 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1121 if (Checksum != 0) {\r
1122 printf ("ERROR: Header checksum invalid.\n");\r
1123 return EFI_ABORTED;\r
1124 }\r
1125\r
1126 return EFI_SUCCESS;\r
1127\r
1128 case EFI_FILE_DELETED:\r
1129 printf (" EFI_FILE_DELETED\n");\r
1130\r
1131 case EFI_FILE_MARKED_FOR_UPDATE:\r
1132 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");\r
1133\r
1134 case EFI_FILE_DATA_VALID:\r
1135 printf (" EFI_FILE_DATA_VALID\n");\r
1136\r
1137 //\r
1138 // Calculate header checksum\r
1139 //\r
e4ac870f 1140 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);\r
f51461c8
LG
1141 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
1142 Checksum = (UINT8) (Checksum - FileHeader->State);\r
1143 if (Checksum != 0) {\r
1144 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);\r
1145 return EFI_ABORTED;\r
1146 }\r
1147\r
e4ac870f 1148 FileLength = FvBufGetFfsFileSize (FileHeader);\r
f51461c8
LG
1149\r
1150 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
1151 //\r
1152 // Calculate file checksum\r
1153 //\r
e4ac870f 1154 Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);\r
f51461c8
LG
1155 Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;\r
1156 if (Checksum != 0) {\r
1157 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);\r
1158 return EFI_ABORTED;\r
1159 }\r
1160 } else {\r
1161 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
1162 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
1163 return EFI_ABORTED;\r
1164 }\r
1165 }\r
1166#if (PI_SPECIFICATION_VERSION < 0x00010000) \r
1167 //\r
1168 // Verify tail if present\r
1169 //\r
1170 if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
1171 //\r
1172 // Verify tail is complement of integrity check field in the header.\r
1173 //\r
1174 Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));\r
1175 if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {\r
1176 Error (NULL, 0, 0003, "error parsing FFS file", \\r
1177 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);\r
1178 return EFI_ABORTED;\r
1179 }\r
1180 }\r
1181 #endif \r
1182 break;\r
1183\r
1184 default:\r
1185 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);\r
1186 return EFI_ABORTED;\r
1187 }\r
1188\r
1189 printf ("File Type: 0x%02X ", FileHeader->Type);\r
1190\r
1191 switch (FileHeader->Type) {\r
1192\r
1193 case EFI_FV_FILETYPE_RAW:\r
1194 printf ("EFI_FV_FILETYPE_RAW\n");\r
1195 break;\r
1196\r
1197 case EFI_FV_FILETYPE_FREEFORM:\r
1198 printf ("EFI_FV_FILETYPE_FREEFORM\n");\r
1199 break;\r
1200\r
1201 case EFI_FV_FILETYPE_SECURITY_CORE:\r
1202 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");\r
1203 break;\r
1204\r
1205 case EFI_FV_FILETYPE_PEI_CORE:\r
1206 printf ("EFI_FV_FILETYPE_PEI_CORE\n");\r
1207 break;\r
1208\r
1209 case EFI_FV_FILETYPE_DXE_CORE:\r
1210 printf ("EFI_FV_FILETYPE_DXE_CORE\n");\r
1211 break;\r
1212\r
1213 case EFI_FV_FILETYPE_PEIM:\r
1214 printf ("EFI_FV_FILETYPE_PEIM\n");\r
1215 break;\r
1216\r
1217 case EFI_FV_FILETYPE_DRIVER:\r
1218 printf ("EFI_FV_FILETYPE_DRIVER\n");\r
1219 break;\r
1220\r
1221 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
1222 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");\r
1223 break;\r
1224\r
1225 case EFI_FV_FILETYPE_APPLICATION:\r
1226 printf ("EFI_FV_FILETYPE_APPLICATION\n");\r
1227 break;\r
1228\r
1229 case EFI_FV_FILETYPE_SMM:\r
1230 printf ("EFI_FV_FILETYPE_SMM\n");\r
1231 break;\r
1232\r
1233 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
1234 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");\r
1235 break;\r
1236\r
1237 case EFI_FV_FILETYPE_COMBINED_SMM_DXE:\r
1238 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");\r
1239 break;\r
1240\r
1241 case EFI_FV_FILETYPE_SMM_CORE:\r
1242 printf ("EFI_FV_FILETYPE_SMM_CORE\n");\r
1243 break;\r
1244\r
1245 case EFI_FV_FILETYPE_FFS_PAD:\r
1246 printf ("EFI_FV_FILETYPE_FFS_PAD\n");\r
1247 break;\r
1248\r
1249 default:\r
1250 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);\r
1251 return EFI_ABORTED;\r
1252 break;\r
1253 }\r
1254\r
1255 switch (FileHeader->Type) {\r
1256\r
1257 case EFI_FV_FILETYPE_ALL:\r
1258 case EFI_FV_FILETYPE_RAW:\r
1259 case EFI_FV_FILETYPE_FFS_PAD:\r
1260 break;\r
1261\r
1262 default:\r
1263 //\r
1264 // All other files have sections\r
1265 //\r
1266 Status = ParseSection (\r
e4ac870f
LG
1267 (UINT8 *) ((UINTN) FileHeader + HeaderSize),\r
1268 FvBufGetFfsFileSize (FileHeader) - HeaderSize\r
f51461c8
LG
1269 );\r
1270 if (EFI_ERROR (Status)) {\r
1271 //\r
1272 // printf ("ERROR: Parsing the FFS file.\n");\r
1273 //\r
1274 return EFI_ABORTED;\r
1275 }\r
1276 break;\r
1277 }\r
1278\r
1279 return EFI_SUCCESS;\r
1280}\r
1281\r
9947f576
YZ
1282EFI_STATUS\r
1283RebaseImageRead (\r
1284 IN VOID *FileHandle,\r
1285 IN UINTN FileOffset,\r
1286 IN OUT UINT32 *ReadSize,\r
1287 OUT VOID *Buffer\r
1288 )\r
1289/*++\r
1290\r
1291Routine Description:\r
1292\r
1293 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
1294\r
1295Arguments:\r
1296\r
1297 FileHandle - The handle to the PE/COFF file\r
1298\r
1299 FileOffset - The offset, in bytes, into the file to read\r
1300\r
1301 ReadSize - The number of bytes to read from the file starting at FileOffset\r
1302\r
1303 Buffer - A pointer to the buffer to read the data into.\r
1304\r
1305Returns:\r
1306\r
1307 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
1308\r
1309--*/\r
1310{\r
1311 CHAR8 *Destination8;\r
1312 CHAR8 *Source8;\r
1313 UINT32 Length;\r
1314\r
1315 Destination8 = Buffer;\r
1316 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
1317 Length = *ReadSize;\r
1318 while (Length--) {\r
1319 *(Destination8++) = *(Source8++);\r
1320 }\r
1321\r
1322 return EFI_SUCCESS;\r
1323}\r
1324\r
1325EFI_STATUS\r
1326SetAddressToSectionHeader (\r
1327 IN CHAR8 *FileName,\r
1328 IN OUT UINT8 *FileBuffer,\r
1329 IN UINT64 NewPe32BaseAddress\r
1330 )\r
1331/*++\r
1332\r
1333Routine Description:\r
1334\r
1335 Set new base address into the section header of PeImage\r
1336\r
1337Arguments:\r
1338\r
1339 FileName - Name of file\r
1340 FileBuffer - Pointer to PeImage.\r
1341 NewPe32BaseAddress - New Base Address for PE image.\r
1342\r
1343Returns:\r
1344\r
1345 EFI_SUCCESS Set new base address into this image successfully.\r
1346\r
1347--*/\r
1348{\r
1349 EFI_STATUS Status;\r
1350 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1351 UINTN Index;\r
1352 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1353 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1354\r
1355 //\r
1356 // Initialize context\r
1357 //\r
1358 memset (&ImageContext, 0, sizeof (ImageContext));\r
1359 ImageContext.Handle = (VOID *) FileBuffer;\r
1360 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1361 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1362 if (EFI_ERROR (Status)) {\r
1363 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1364 return Status;\r
1365 }\r
1366\r
1367 if (ImageContext.RelocationsStripped) {\r
1368 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1369 return Status;\r
1370 }\r
1371\r
1372 //\r
1373 // Get PeHeader pointer\r
1374 //\r
1375 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1376\r
1377 //\r
1378 // Get section header list\r
1379 //\r
1380 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1381 (UINTN) ImgHdr +\r
1382 sizeof (UINT32) +\r
1383 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1384 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1385 );\r
1386\r
1387 //\r
1388 // Set base address into the first section header that doesn't point to code section.\r
1389 //\r
1390 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1391 if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
1392 *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;\r
1393 break;\r
1394 }\r
1395 }\r
1396\r
9947f576
YZ
1397 //\r
1398 // BaseAddress is set to section header.\r
1399 //\r
1400 return EFI_SUCCESS;\r
1401}\r
1402\r
1403EFI_STATUS\r
1404RebaseImage (\r
1405 IN CHAR8 *FileName,\r
1406 IN OUT UINT8 *FileBuffer,\r
1407 IN UINT64 NewPe32BaseAddress\r
1408 )\r
1409/*++\r
1410\r
1411Routine Description:\r
1412\r
1413 Set new base address into PeImage, and fix up PeImage based on new address.\r
1414\r
1415Arguments:\r
1416\r
1417 FileName - Name of file\r
1418 FileBuffer - Pointer to PeImage.\r
1419 NewPe32BaseAddress - New Base Address for PE image.\r
1420\r
1421Returns:\r
1422\r
1423 EFI_INVALID_PARAMETER - BaseAddress is not valid.\r
1424 EFI_SUCCESS - Update PeImage is correctly.\r
1425\r
1426--*/\r
1427{\r
1428 EFI_STATUS Status;\r
1429 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
1430 UINTN Index;\r
1431 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
1432 UINT8 *MemoryImagePointer;\r
1433 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1434\r
1435 //\r
1436 // Initialize context\r
1437 //\r
1438 memset (&ImageContext, 0, sizeof (ImageContext));\r
1439 ImageContext.Handle = (VOID *) FileBuffer;\r
1440 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
1441 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
1442 if (EFI_ERROR (Status)) {\r
1443 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
1444 return Status;\r
1445 }\r
1446\r
1447 if (ImageContext.RelocationsStripped) {\r
1448 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
1449 return Status;\r
1450 }\r
1451\r
1452 //\r
1453 // Get PeHeader pointer\r
1454 //\r
1455 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
1456\r
1457 //\r
1458 // Load and Relocate Image Data\r
1459 //\r
1460 MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1461 if (MemoryImagePointer == NULL) {\r
1462 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
1463 return EFI_OUT_OF_RESOURCES;\r
1464 }\r
1465 memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
1466 ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
1467\r
1468 Status = PeCoffLoaderLoadImage (&ImageContext);\r
1469 if (EFI_ERROR (Status)) {\r
1470 Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
1471 free ((VOID *) MemoryImagePointer);\r
1472 return Status;\r
1473 }\r
1474\r
1475 ImageContext.DestinationAddress = NewPe32BaseAddress;\r
1476 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
1477 if (EFI_ERROR (Status)) {\r
1478 Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
1479 free ((VOID *) MemoryImagePointer);\r
1480 return Status;\r
1481 }\r
1482\r
1483 //\r
1484 // Copy Relocated data to raw image file.\r
1485 //\r
1486 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
1487 (UINTN) ImgHdr +\r
1488 sizeof (UINT32) +\r
1489 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1490 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1491 );\r
1492\r
1493 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1494 CopyMem (\r
1495 FileBuffer + SectionHeader->PointerToRawData,\r
1496 (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),\r
1497 SectionHeader->SizeOfRawData\r
1498 );\r
1499 }\r
1500\r
1501 free ((VOID *) MemoryImagePointer);\r
1502\r
1503 //\r
1504 // Update Image Base Address\r
1505 //\r
1506 if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
1507 ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
1508 } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
1509 ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
1510 } else {\r
1511 Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
1512 ImgHdr->Pe32.OptionalHeader.Magic,\r
1513 FileName\r
1514 );\r
1515 return EFI_ABORTED;\r
1516 }\r
1517\r
1518 //\r
1519 // Set new base address into section header\r
1520 //\r
1521 Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);\r
1522\r
1523 return Status;\r
1524}\r
1525\r
1526EFI_STATUS\r
1527CombinePath (\r
1528 IN CHAR8* DefaultPath,\r
1529 IN CHAR8* AppendPath,\r
1530 OUT CHAR8* NewPath\r
1531)\r
1532{\r
1533 UINT32 DefaultPathLen;\r
1534 DefaultPathLen = strlen(DefaultPath);\r
1535 strcpy(NewPath, DefaultPath);\r
1536 UINT64 Index = 0;\r
1537 for (; Index < DefaultPathLen; Index ++) {\r
1538 if (NewPath[Index] == '\\' || NewPath[Index] == '/') {\r
1539 if (NewPath[Index + 1] != '\0') {\r
1540 NewPath[Index] = '/';\r
1541 }\r
1542 }\r
1543 }\r
1544 if (NewPath[Index -1] != '/') {\r
1545 NewPath[Index] = '/';\r
1546 NewPath[Index + 1] = '\0';\r
1547 }\r
1548 strcat(NewPath, AppendPath);\r
1549 return EFI_SUCCESS;\r
1550}\r
1551\r
f51461c8
LG
1552EFI_STATUS\r
1553ParseSection (\r
1554 IN UINT8 *SectionBuffer,\r
1555 IN UINT32 BufferLength\r
1556 )\r
1557/*++\r
1558\r
1559Routine Description:\r
1560\r
1561 Parses EFI Sections\r
1562\r
1563Arguments:\r
1564\r
1565 SectionBuffer - Buffer containing the section to parse.\r
1566 BufferLength - Length of SectionBuffer\r
1567\r
1568Returns:\r
1569\r
1570 EFI_SECTION_ERROR - Problem with section parsing.\r
1571 (a) compression errors\r
1572 (b) unrecognized section \r
1573 EFI_UNSUPPORTED - Do not know how to parse the section.\r
1574 EFI_SUCCESS - Section successfully parsed.\r
1575 EFI_OUT_OF_RESOURCES - Memory allocation failed.\r
1576\r
1577--*/\r
1578{\r
1579 EFI_SECTION_TYPE Type;\r
1580 UINT8 *Ptr;\r
1581 UINT32 SectionLength;\r
e4ac870f 1582 UINT32 SectionHeaderLen;\r
f51461c8
LG
1583 CHAR8 *SectionName;\r
1584 EFI_STATUS Status;\r
1585 UINT32 ParsedLength;\r
1586 UINT8 *CompressedBuffer;\r
1587 UINT32 CompressedLength;\r
1588 UINT8 *UncompressedBuffer;\r
1589 UINT32 UncompressedLength;\r
1590 UINT8 *ToolOutputBuffer;\r
1591 UINT32 ToolOutputLength;\r
1592 UINT8 CompressionType;\r
1593 UINT32 DstSize;\r
1594 UINT32 ScratchSize;\r
1595 UINT8 *ScratchBuffer;\r
1596 DECOMPRESS_FUNCTION DecompressFunction;\r
1597 GETINFO_FUNCTION GetInfoFunction;\r
1598 // CHAR16 *name;\r
1599 CHAR8 *ExtractionTool;\r
1600 CHAR8 *ToolInputFile;\r
1601 CHAR8 *ToolOutputFile;\r
1602 CHAR8 *SystemCommandFormatString;\r
1603 CHAR8 *SystemCommand;\r
e4ac870f
LG
1604 EFI_GUID *EfiGuid;\r
1605 UINT16 DataOffset;\r
1606 UINT16 Attributes;\r
1607 UINT32 RealHdrLen;\r
9947f576
YZ
1608 CHAR8 *ToolInputFileName;\r
1609 CHAR8 *ToolOutputFileName;\r
f51461c8
LG
1610\r
1611 ParsedLength = 0;\r
9947f576
YZ
1612 ToolInputFileName = NULL;\r
1613 ToolOutputFileName = NULL;\r
1614\r
f51461c8
LG
1615 while (ParsedLength < BufferLength) {\r
1616 Ptr = SectionBuffer + ParsedLength;\r
1617\r
1618 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);\r
1619 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;\r
1620\r
1621 //\r
1622 // This is sort of an odd check, but is necessary because FFS files are\r
1623 // padded to a QWORD boundary, meaning there is potentially a whole section\r
1624 // header worth of 0xFF bytes.\r
1625 //\r
1626 if (SectionLength == 0xffffff && Type == 0xff) {\r
1627 ParsedLength += 4;\r
1628 continue;\r
1629 }\r
1630\r
e4ac870f
LG
1631 //\r
1632 // Get real section file size\r
1633 //\r
1634 SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);\r
1635 SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
1636\r
f51461c8 1637 SectionName = SectionNameToStr (Type);\r
9dd00cb6
HW
1638 if (SectionName != NULL) {\r
1639 printf ("------------------------------------------------------------\n");\r
1640 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);\r
1641 free (SectionName);\r
1642 }\r
f51461c8
LG
1643\r
1644 switch (Type) {\r
1645 case EFI_SECTION_RAW:\r
f51461c8
LG
1646 case EFI_SECTION_PIC:\r
1647 case EFI_SECTION_TE:\r
1648 // default is no more information\r
1649 break;\r
1650\r
9947f576
YZ
1651 case EFI_SECTION_PE32:\r
1652 if (EnableHash) {\r
1653 ToolInputFileName = "edk2Temp_InputEfi.tmp";\r
1654 ToolOutputFileName = "edk2Temp_OutputHash.tmp";\r
1655 RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);\r
1656 PutFileImage (\r
1657 ToolInputFileName,\r
1658 (CHAR8*)Ptr + SectionHeaderLen,\r
1659 SectionLength - SectionHeaderLen\r
1660 );\r
1661\r
1662 SystemCommandFormatString = "%s sha1 -out %s %s";\r
1663 SystemCommand = malloc (\r
1664 strlen (SystemCommandFormatString) +\r
1665 strlen (OpenSslPath) +\r
1666 strlen (ToolInputFileName) +\r
1667 strlen (ToolOutputFileName) +\r
1668 1\r
1669 );\r
9dd00cb6
HW
1670 if (SystemCommand == NULL) {\r
1671 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1672 return EFI_OUT_OF_RESOURCES;\r
1673 }\r
9947f576
YZ
1674 sprintf (\r
1675 SystemCommand,\r
1676 SystemCommandFormatString,\r
1677 OpenSslPath,\r
1678 ToolOutputFileName,\r
1679 ToolInputFileName\r
1680 );\r
1681\r
1682 if (system (SystemCommand) != EFI_SUCCESS) {\r
1683 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);\r
1684 }\r
1685 else {\r
1686 FILE *fp;\r
1687 CHAR8 *StrLine;\r
1688 CHAR8 *NewStr;\r
1689 UINT32 nFileLen;\r
1690 if((fp = fopen(ToolOutputFileName,"r")) == NULL) {\r
1691 Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);\r
1692 }\r
1693 else {\r
1694 fseek(fp,0,SEEK_SET);\r
1695 fseek(fp,0,SEEK_END);\r
1696 nFileLen = ftell(fp);\r
1697 fseek(fp,0,SEEK_SET);\r
1698 StrLine = malloc(nFileLen);\r
9dd00cb6
HW
1699 if (StrLine == NULL) {\r
1700 fclose(fp);\r
1701 free (SystemCommand);\r
1702 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1703 return EFI_OUT_OF_RESOURCES;\r
1704 }\r
9947f576
YZ
1705 fgets(StrLine, nFileLen, fp);\r
1706 NewStr = strrchr (StrLine, '=');\r
1707 printf (" SHA1: %s\n", NewStr + 1);\r
1708 free (StrLine);\r
9dd00cb6 1709 fclose(fp);\r
9947f576 1710 }\r
9947f576
YZ
1711 }\r
1712 remove(ToolInputFileName);\r
1713 remove(ToolOutputFileName);\r
1714 free (SystemCommand);\r
1715 }\r
1716 break;\r
1717\r
f51461c8 1718 case EFI_SECTION_USER_INTERFACE:\r
ed9ff268 1719 printf (" String: %ls\n", (wchar_t *) &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString);\r
f51461c8
LG
1720 break;\r
1721\r
1722 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:\r
e4ac870f 1723 Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);\r
f51461c8
LG
1724 if (EFI_ERROR (Status)) {\r
1725 Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);\r
1726 return EFI_SECTION_ERROR;\r
1727 }\r
1728 break;\r
1729\r
1730 case EFI_SECTION_COMPATIBILITY16:\r
1731 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
1732 //\r
1733 // Section does not contain any further header information.\r
1734 //\r
1735 break;\r
1736\r
1737 case EFI_SECTION_PEI_DEPEX:\r
1738 case EFI_SECTION_DXE_DEPEX:\r
1739 case EFI_SECTION_SMM_DEPEX:\r
1740 DumpDepexSection (Ptr, SectionLength);\r
1741 break;\r
1742\r
1743 case EFI_SECTION_VERSION:\r
e4ac870f
LG
1744 printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));\r
1745 printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));\r
f51461c8
LG
1746 break;\r
1747\r
1748 case EFI_SECTION_COMPRESSION:\r
1749 UncompressedBuffer = NULL;\r
e4ac870f
LG
1750 if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {\r
1751 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);\r
1752 UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;\r
1753 CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;\r
1754 } else {\r
1755 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);\r
1756 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;\r
1757 CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;\r
1758 }\r
1759 CompressedLength = SectionLength - RealHdrLen;\r
f51461c8
LG
1760 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);\r
1761\r
1762 if (CompressionType == EFI_NOT_COMPRESSED) {\r
1763 printf (" Compression Type: EFI_NOT_COMPRESSED\n");\r
1764 if (CompressedLength != UncompressedLength) {\r
1765 Error (\r
1766 NULL,\r
1767 0,\r
1768 0,\r
1769 "file is not compressed, but the compressed length does not match the uncompressed length",\r
1770 NULL\r
1771 );\r
1772 return EFI_SECTION_ERROR;\r
1773 }\r
1774\r
e4ac870f 1775 UncompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1776 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1777 GetInfoFunction = EfiGetInfo;\r
1778 DecompressFunction = EfiDecompress;\r
1779 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");\r
1780\r
e4ac870f 1781 CompressedBuffer = Ptr + RealHdrLen;\r
f51461c8
LG
1782\r
1783 Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);\r
1784 if (EFI_ERROR (Status)) {\r
1785 Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);\r
1786 return EFI_SECTION_ERROR;\r
1787 }\r
1788\r
1789 if (DstSize != UncompressedLength) {\r
1790 Error (NULL, 0, 0003, "compression error in the compression section", NULL);\r
1791 return EFI_SECTION_ERROR;\r
1792 }\r
1793\r
1794 ScratchBuffer = malloc (ScratchSize);\r
85006654
HW
1795 if (ScratchBuffer == NULL) {\r
1796 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1797 return EFI_OUT_OF_RESOURCES;\r
1798 }\r
f51461c8 1799 UncompressedBuffer = malloc (UncompressedLength);\r
85006654
HW
1800 if (UncompressedBuffer == NULL) {\r
1801 free (ScratchBuffer);\r
1802 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
f51461c8
LG
1803 return EFI_OUT_OF_RESOURCES;\r
1804 }\r
1805 Status = DecompressFunction (\r
1806 CompressedBuffer,\r
1807 CompressedLength,\r
1808 UncompressedBuffer,\r
1809 UncompressedLength,\r
1810 ScratchBuffer,\r
1811 ScratchSize\r
1812 );\r
1813 free (ScratchBuffer);\r
1814 if (EFI_ERROR (Status)) {\r
1815 Error (NULL, 0, 0003, "decompress failed", NULL);\r
1816 free (UncompressedBuffer);\r
1817 return EFI_SECTION_ERROR;\r
1818 }\r
1819 } else {\r
1820 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);\r
1821 return EFI_SECTION_ERROR;\r
1822 }\r
1823\r
1824 Status = ParseSection (UncompressedBuffer, UncompressedLength);\r
1825\r
1826 if (CompressionType == EFI_STANDARD_COMPRESSION) {\r
1827 //\r
1828 // We need to deallocate Buffer\r
1829 //\r
1830 free (UncompressedBuffer);\r
1831 }\r
1832\r
1833 if (EFI_ERROR (Status)) {\r
1834 Error (NULL, 0, 0003, "failed to parse section", NULL);\r
1835 return EFI_SECTION_ERROR;\r
1836 }\r
1837 break;\r
1838\r
1839 case EFI_SECTION_GUID_DEFINED:\r
e4ac870f
LG
1840 if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {\r
1841 EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;\r
1842 DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;\r
1843 Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;\r
1844 } else {\r
1845 EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;\r
1846 DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;\r
1847 Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;\r
1848 }\r
f51461c8 1849 printf (" SectionDefinitionGuid: ");\r
e4ac870f 1850 PrintGuid (EfiGuid);\r
f51461c8 1851 printf ("\n");\r
e4ac870f
LG
1852 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);\r
1853 printf (" Attributes: 0x%04X\n", (unsigned) Attributes);\r
f51461c8
LG
1854\r
1855 ExtractionTool =\r
1856 LookupGuidedSectionToolPath (\r
1857 mParsedGuidedSectionTools,\r
e4ac870f 1858 EfiGuid\r
f51461c8
LG
1859 );\r
1860\r
1861 if (ExtractionTool != NULL) {\r
868c9c35 1862 #ifndef __GNUC__\r
f51461c8
LG
1863 ToolInputFile = CloneString (tmpnam (NULL));\r
1864 ToolOutputFile = CloneString (tmpnam (NULL));\r
868c9c35
YZ
1865 #else\r
1866 char tmp1[] = "/tmp/fileXXXXXX";\r
1867 char tmp2[] = "/tmp/fileXXXXXX";\r
1868 int fd1;\r
1869 int fd2;\r
1870 fd1 = mkstemp(tmp1);\r
1871 fd2 = mkstemp(tmp2);\r
1872 ToolInputFile = CloneString(tmp1);\r
1873 ToolOutputFile = CloneString(tmp2);\r
1874 close(fd1);\r
1875 close(fd2);\r
1876 #endif\r
f51461c8 1877\r
9dd00cb6
HW
1878 if ((ToolInputFile == NULL) || (ToolOutputFile == NULL)) {\r
1879 if (ToolInputFile != NULL) {\r
1880 free (ToolInputFile);\r
1881 }\r
1882 if (ToolOutputFile != NULL) {\r
1883 free (ToolOutputFile);\r
1884 }\r
1885 free (ExtractionTool);\r
1886\r
1887 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1888 return EFI_OUT_OF_RESOURCES;\r
1889 }\r
1890\r
f51461c8
LG
1891 //\r
1892 // Construction 'system' command string\r
1893 //\r
1894 SystemCommandFormatString = "%s -d -o %s %s";\r
1895 SystemCommand = malloc (\r
1896 strlen (SystemCommandFormatString) +\r
1897 strlen (ExtractionTool) +\r
1898 strlen (ToolInputFile) +\r
1899 strlen (ToolOutputFile) +\r
1900 1\r
1901 );\r
9dd00cb6
HW
1902 if (SystemCommand == NULL) {\r
1903 free (ToolInputFile);\r
1904 free (ToolOutputFile);\r
1905 free (ExtractionTool);\r
1906\r
1907 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1908 return EFI_OUT_OF_RESOURCES;\r
1909 }\r
f51461c8
LG
1910 sprintf (\r
1911 SystemCommand,\r
1912 SystemCommandFormatString,\r
1913 ExtractionTool,\r
1914 ToolOutputFile,\r
1915 ToolInputFile\r
1916 );\r
1917 free (ExtractionTool);\r
1918\r
1919 Status =\r
1920 PutFileImage (\r
1921 ToolInputFile,\r
e4ac870f
LG
1922 (CHAR8*) SectionBuffer + DataOffset,\r
1923 BufferLength - DataOffset\r
f51461c8
LG
1924 );\r
1925\r
1926 system (SystemCommand);\r
1927 remove (ToolInputFile);\r
1928 free (ToolInputFile);\r
1929\r
1930 Status =\r
1931 GetFileImage (\r
1932 ToolOutputFile,\r
1933 (CHAR8 **)&ToolOutputBuffer,\r
1934 &ToolOutputLength\r
1935 );\r
1936 remove (ToolOutputFile);\r
1937 free (ToolOutputFile);\r
9dd00cb6 1938 free (SystemCommand);\r
f51461c8
LG
1939 if (EFI_ERROR (Status)) {\r
1940 Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);\r
1941 return EFI_SECTION_ERROR;\r
1942 }\r
1943\r
1944 Status = ParseSection (\r
1945 ToolOutputBuffer,\r
1946 ToolOutputLength\r
1947 );\r
1948 if (EFI_ERROR (Status)) {\r
1949 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);\r
1950 return EFI_SECTION_ERROR;\r
1951 }\r
1952\r
1953 //\r
1954 // Check for CRC32 sections which we can handle internally if needed.\r
1955 //\r
1956 } else if (!CompareGuid (\r
e4ac870f 1957 EfiGuid,\r
f51461c8
LG
1958 &gEfiCrc32GuidedSectionExtractionProtocolGuid\r
1959 )\r
1960 ) {\r
1961 //\r
1962 // CRC32 guided section\r
1963 //\r
1964 Status = ParseSection (\r
e4ac870f
LG
1965 SectionBuffer + DataOffset,\r
1966 BufferLength - DataOffset\r
f51461c8
LG
1967 );\r
1968 if (EFI_ERROR (Status)) {\r
1969 Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);\r
1970 return EFI_SECTION_ERROR;\r
1971 }\r
1972 } else {\r
1973 //\r
1974 // We don't know how to parse it now.\r
1975 //\r
1976 Error (NULL, 0, 0003, "Error parsing section", \\r
1977 "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
1978 return EFI_UNSUPPORTED;\r
1979 }\r
1980 break;\r
1981\r
1982 default:\r
1983 //\r
1984 // Unknown section, return error\r
1985 //\r
1986 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);\r
1987 return EFI_SECTION_ERROR;\r
1988 }\r
1989\r
1990 ParsedLength += SectionLength;\r
1991 //\r
1992 // We make then next section begin on a 4-byte boundary\r
1993 //\r
1994 ParsedLength = GetOccupiedSize (ParsedLength, 4);\r
1995 }\r
1996\r
1997 if (ParsedLength < BufferLength) {\r
1998 Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);\r
1999 return EFI_SECTION_ERROR;\r
2000 }\r
2001\r
2002 return EFI_SUCCESS;\r
2003}\r
2004\r
2005EFI_STATUS\r
2006DumpDepexSection (\r
2007 IN UINT8 *Ptr,\r
2008 IN UINT32 SectionLength\r
2009 )\r
2010/*++\r
2011\r
2012Routine Description:\r
2013\r
2014 GC_TODO: Add function description\r
2015\r
2016Arguments:\r
2017\r
2018 Ptr - GC_TODO: add argument description\r
2019 SectionLength - GC_TODO: add argument description\r
2020\r
2021Returns:\r
2022\r
2023 EFI_SUCCESS - GC_TODO: Add description for return value\r
2024\r
2025--*/\r
2026{\r
2027 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];\r
2028\r
2029 //\r
2030 // Need at least a section header + data\r
2031 //\r
2032 if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {\r
2033 return EFI_SUCCESS;\r
2034 }\r
2035\r
e4ac870f
LG
2036 Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
2037 SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);\r
f51461c8
LG
2038 while (SectionLength > 0) {\r
2039 printf (" ");\r
2040 switch (*Ptr) {\r
2041 case EFI_DEP_BEFORE:\r
2042 printf ("BEFORE\n");\r
2043 Ptr++;\r
2044 SectionLength--;\r
2045 break;\r
2046\r
2047 case EFI_DEP_AFTER:\r
2048 printf ("AFTER\n");\r
2049 Ptr++;\r
2050 SectionLength--;\r
2051 break;\r
2052\r
2053 case EFI_DEP_PUSH:\r
2054 printf ("PUSH\n ");\r
2055 PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);\r
2056 printf ("%s ", GuidBuffer);\r
2057 PrintGuidName (GuidBuffer);\r
2058 printf ("\n");\r
2059 //\r
2060 // PrintGuid ((EFI_GUID *)(Ptr + 1));\r
2061 //\r
2062 Ptr += 17;\r
2063 SectionLength -= 17;\r
2064 break;\r
2065\r
2066 case EFI_DEP_AND:\r
2067 printf ("AND\n");\r
2068 Ptr++;\r
2069 SectionLength--;\r
2070 break;\r
2071\r
2072 case EFI_DEP_OR:\r
2073 printf ("OR\n");\r
2074 Ptr++;\r
2075 SectionLength--;\r
2076 break;\r
2077\r
2078 case EFI_DEP_NOT:\r
2079 printf ("NOT\n");\r
2080 Ptr++;\r
2081 SectionLength--;\r
2082 break;\r
2083\r
2084 case EFI_DEP_TRUE:\r
2085 printf ("TRUE\n");\r
2086 Ptr++;\r
2087 SectionLength--;\r
2088 break;\r
2089\r
2090 case EFI_DEP_FALSE:\r
2091 printf ("FALSE\n");\r
2092 Ptr++;\r
2093 SectionLength--;\r
2094 break;\r
2095\r
2096 case EFI_DEP_END:\r
2097 printf ("END DEPEX\n");\r
2098 Ptr++;\r
2099 SectionLength--;\r
2100 break;\r
2101\r
2102 case EFI_DEP_SOR:\r
2103 printf ("SOR\n");\r
2104 Ptr++;\r
2105 SectionLength--;\r
2106 break;\r
2107\r
2108 default:\r
2109 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);\r
2110 return EFI_SUCCESS;\r
2111 }\r
2112 }\r
2113\r
2114 return EFI_SUCCESS;\r
2115}\r
2116\r
2117EFI_STATUS\r
2118PrintGuidName (\r
2119 IN UINT8 *GuidStr\r
2120 )\r
2121/*++\r
2122\r
2123Routine Description:\r
2124\r
2125 GC_TODO: Add function description\r
2126\r
2127Arguments:\r
2128\r
2129 GuidStr - GC_TODO: add argument description\r
2130\r
2131Returns:\r
2132\r
2133 EFI_SUCCESS - GC_TODO: Add description for return value\r
2134 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
2135\r
2136--*/\r
2137{\r
2138 GUID_TO_BASENAME *GPtr;\r
2139 //\r
2140 // If we have a list of guid-to-basenames, then go through the list to\r
2141 // look for a guid string match. If found, print the basename to stdout,\r
2142 // otherwise return a failure.\r
2143 //\r
2144 GPtr = mGuidBaseNameList;\r
2145 while (GPtr != NULL) {\r
2146 if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {\r
2147 printf ("%s", GPtr->BaseName);\r
2148 return EFI_SUCCESS;\r
2149 }\r
2150\r
2151 GPtr = GPtr->Next;\r
2152 }\r
2153\r
2154 return EFI_INVALID_PARAMETER;\r
2155}\r
2156\r
2157EFI_STATUS\r
2158ParseGuidBaseNameFile (\r
2159 CHAR8 *FileName\r
2160 )\r
2161/*++\r
2162\r
2163Routine Description:\r
2164\r
2165 GC_TODO: Add function description\r
2166\r
2167Arguments:\r
2168\r
2169 FileName - GC_TODO: add argument description\r
2170\r
2171Returns:\r
2172\r
2173 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
2174 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value\r
2175 EFI_SUCCESS - GC_TODO: Add description for return value\r
2176\r
2177--*/\r
2178{\r
2179 FILE *Fptr;\r
2180 CHAR8 Line[MAX_LINE_LEN];\r
d6a1ce3b
HW
2181 CHAR8 *FormatString;\r
2182 INTN FormatLength;\r
f51461c8
LG
2183 GUID_TO_BASENAME *GPtr;\r
2184\r
97fa0ee9 2185 if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {\r
f51461c8
LG
2186 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);\r
2187 return EFI_DEVICE_ERROR;\r
2188 }\r
2189\r
d6a1ce3b
HW
2190 //\r
2191 // Generate the format string for fscanf\r
2192 //\r
2193 FormatLength = snprintf (\r
2194 NULL,\r
2195 0,\r
2196 "%%%us %%%us",\r
2197 (unsigned) sizeof (GPtr->Guid) - 1,\r
2198 (unsigned) sizeof (GPtr->BaseName) - 1\r
2199 ) + 1;\r
2200\r
2201 FormatString = (CHAR8 *) malloc (FormatLength);\r
2202 if (FormatString == NULL) {\r
2203 fclose (Fptr);\r
2204 return EFI_OUT_OF_RESOURCES;\r
2205 }\r
2206\r
2207 snprintf (\r
2208 FormatString,\r
2209 FormatLength,\r
2210 "%%%us %%%us",\r
2211 (unsigned) sizeof (GPtr->Guid) - 1,\r
2212 (unsigned) sizeof (GPtr->BaseName) - 1\r
2213 );\r
2214\r
f51461c8
LG
2215 while (fgets (Line, sizeof (Line), Fptr) != NULL) {\r
2216 //\r
2217 // Allocate space for another guid/basename element\r
2218 //\r
2219 GPtr = malloc (sizeof (GUID_TO_BASENAME));\r
2220 if (GPtr == NULL) {\r
d6a1ce3b 2221 free (FormatString);\r
2a9afe80 2222 fclose (Fptr);\r
f51461c8
LG
2223 return EFI_OUT_OF_RESOURCES;\r
2224 }\r
2225\r
2226 memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));\r
d6a1ce3b 2227 if (sscanf (Line, FormatString, GPtr->Guid, GPtr->BaseName) == 2) {\r
f51461c8
LG
2228 GPtr->Next = mGuidBaseNameList;\r
2229 mGuidBaseNameList = GPtr;\r
2230 } else {\r
2231 //\r
2232 // Some sort of error. Just continue.\r
2233 //\r
2234 free (GPtr);\r
2235 }\r
2236 }\r
2237\r
d6a1ce3b 2238 free (FormatString);\r
f51461c8
LG
2239 fclose (Fptr);\r
2240 return EFI_SUCCESS;\r
2241}\r
2242\r
2243EFI_STATUS\r
2244FreeGuidBaseNameList (\r
2245 VOID\r
2246 )\r
2247/*++\r
2248\r
2249Routine Description:\r
2250\r
2251 GC_TODO: Add function description\r
2252\r
2253Arguments:\r
2254\r
2255 None\r
2256\r
2257Returns:\r
2258\r
2259 EFI_SUCCESS - GC_TODO: Add description for return value\r
2260\r
2261--*/\r
2262{\r
2263 GUID_TO_BASENAME *Next;\r
2264\r
2265 while (mGuidBaseNameList != NULL) {\r
2266 Next = mGuidBaseNameList->Next;\r
2267 free (mGuidBaseNameList);\r
2268 mGuidBaseNameList = Next;\r
2269 }\r
2270\r
2271 return EFI_SUCCESS;\r
2272}\r
2273\r
2274\r
2275static\r
2276VOID\r
2277LoadGuidedSectionToolsTxt (\r
2278 IN CHAR8* FirmwareVolumeFilename\r
2279 )\r
2280{\r
2281 CHAR8* PeerFilename;\r
2282 CHAR8* Places[] = {\r
2283 NULL,\r
2284 //NULL,\r
2285 };\r
2286 UINTN Index;\r
2287\r
2288 Places[0] = FirmwareVolumeFilename;\r
2289 //Places[1] = mUtilityFilename;\r
2290\r
2291 mParsedGuidedSectionTools = NULL;\r
2292\r
2293 for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {\r
2294 PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");\r
2295 //printf("Loading %s...\n", PeerFilename);\r
2296 if (OsPathExists (PeerFilename)) {\r
2297 mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);\r
2298 }\r
2299 free (PeerFilename);\r
2300 if (mParsedGuidedSectionTools != NULL) {\r
2301 return;\r
2302 }\r
2303 }\r
2304}\r
2305\r
2306\r
2307void\r
2308Usage (\r
2309 VOID\r
2310 )\r
2311/*++\r
2312\r
2313Routine Description:\r
2314\r
2315 GC_TODO: Add function description\r
2316\r
2317Arguments:\r
2318\r
2319 None\r
2320\r
2321Returns:\r
2322\r
2323 GC_TODO: add return values\r
2324\r
2325--*/\r
2326{\r
2327 //\r
2328 // Summary usage\r
2329 //\r
2330 fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);\r
2331\r
2332 //\r
2333 // Copyright declaration\r
2334 // \r
45258285 2335 fprintf (stdout, "Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.\n\n");\r
f4260465 2336 fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");\r
f51461c8
LG
2337\r
2338 //\r
2339 // Details Option\r
2340 //\r
730ffca1 2341 fprintf (stdout, "optional arguments:\n");\r
f51461c8 2342 fprintf (stdout, " -h, --help\n\\r
730ffca1
YZ
2343 Show this help message and exit\n");\r
2344 fprintf (stdout, " --version\n\\r
2345 Show program's version number and exit\n");\r
2346 fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\\r
2347 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");\r
2348 fprintf (stdout, " -v, --verbose\n\\r
2349 Print informational statements\n");\r
2350 fprintf (stdout, " -q, --quiet\n\\r
2351 Returns the exit code, error messages will be displayed\n");\r
2352 fprintf (stdout, " -s, --silent\n\\r
2353 Returns only the exit code; informational and error\n\\r
2354 messages are not displayed\n");\r
2355 fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\\r
2356 Parse the basename to file-guid cross reference file(s)\n");\r
2357 fprintf (stdout, " -f OFFSET, --offset OFFSET\n\\r
2358 The offset from the start of the input file to start \n\\r
2359 processing an FV\n");\r
9947f576
YZ
2360 fprintf (stdout, " --hash\n\\r
2361 Generate HASH value of the entire PE image\n");\r
730ffca1
YZ
2362 fprintf (stdout, " --sfo\n\\r
2363 Reserved for future use\n");\r
f51461c8
LG
2364}\r
2365\r