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