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