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