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