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