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