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