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