]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VolInfo/VolInfo.c
Sync tool code to BuildTools project r1783.
[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 //
a709adfa 206 if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {
30fdf114
LG
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 //
a709adfa 219 if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {
30fdf114
LG
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[] = {
30fdf114
LG
440 //
441 // 0X00
442 //
b303ea72 443 "EFI_SECTION_ALL",
30fdf114
LG
444 //
445 // 0x01
446 //
b303ea72 447 "EFI_SECTION_COMPRESSION",
30fdf114
LG
448 //
449 // 0x02
450 //
b303ea72 451 "EFI_SECTION_GUID_DEFINED",
30fdf114
LG
452 //
453 // 0x03
454 //
b303ea72 455 "Unknown section type - Reserved 0x03",
30fdf114
LG
456 //
457 // 0x04
458 //
b303ea72 459 "Unknown section type - Reserved 0x04",
30fdf114
LG
460 //
461 // 0x05
462 //
b303ea72 463 "Unknown section type - Reserved 0x05",
30fdf114
LG
464 //
465 // 0x06
466 //
b303ea72 467 "Unknown section type - Reserved 0x06",
30fdf114
LG
468 //
469 // 0x07
470 //
b303ea72 471 "Unknown section type - Reserved 0x07",
30fdf114
LG
472 //
473 // 0x08
474 //
b303ea72 475 "Unknown section type - Reserved 0x08",
30fdf114
LG
476 //
477 // 0x09
478 //
b303ea72 479 "Unknown section type - Reserved 0x09",
30fdf114
LG
480 //
481 // 0x0A
482 //
b303ea72 483 "Unknown section type - Reserved 0x0A",
30fdf114
LG
484 //
485 // 0x0B
486 //
b303ea72 487 "Unknown section type - Reserved 0x0B",
30fdf114
LG
488 //
489 // 0x0C
490 //
b303ea72 491 "Unknown section type - Reserved 0x0C",
30fdf114
LG
492 //
493 // 0x0D
494 //
b303ea72 495 "Unknown section type - Reserved 0x0D",
30fdf114
LG
496 //
497 // 0x0E
498 //
b303ea72 499 "Unknown section type - Reserved 0x0E",
30fdf114
LG
500 //
501 // 0x0F
502 //
b303ea72 503 "Unknown section type - Reserved 0x0E",
30fdf114
LG
504 //
505 // 0x10
506 //
b303ea72 507 "EFI_SECTION_PE32",
30fdf114
LG
508 //
509 // 0x11
510 //
b303ea72 511 "EFI_SECTION_PIC",
30fdf114
LG
512 //
513 // 0x12
514 //
b303ea72 515 "EFI_SECTION_TE",
30fdf114
LG
516 //
517 // 0x13
518 //
b303ea72 519 "EFI_SECTION_DXE_DEPEX",
30fdf114
LG
520 //
521 // 0x14
522 //
b303ea72 523 "EFI_SECTION_VERSION",
30fdf114
LG
524 //
525 // 0x15
526 //
b303ea72 527 "EFI_SECTION_USER_INTERFACE",
30fdf114
LG
528 //
529 // 0x16
530 //
b303ea72 531 "EFI_SECTION_COMPATIBILITY16",
30fdf114
LG
532 //
533 // 0x17
534 //
b303ea72 535 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
30fdf114
LG
536 //
537 // 0x18
538 //
b303ea72 539 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
30fdf114
LG
540 //
541 // 0x19
542 //
b303ea72 543 "EFI_SECTION_RAW",
30fdf114
LG
544 //
545 // 0x1A
546 //
b303ea72 547 "Unknown section type - 0x1A",
30fdf114
LG
548 //
549 // 0x1B
550 //
b303ea72
LG
551 "EFI_SECTION_PEI_DEPEX",
552 //
553 // 0x1C
554 //
555 "EFI_SECTION_SMM_DEPEX",
30fdf114
LG
556 //
557 // 0x1C+
558 //
b303ea72 559 "Unknown section type - Reserved - beyond last defined section"
30fdf114
LG
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
575STATIC
576EFI_STATUS
577ReadHeader (
578 IN FILE *InputFile,
579 OUT UINT32 *FvSize,
580 OUT BOOLEAN *ErasePolarity
581 )
582/*++
583
584Routine 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
589Arguments:
590
591 InputFile The file that contains the FV image.
592 FvSize The size of the FV.
593 ErasePolarity The FV erase polarity.
594
595Returns:
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 //
fd171542 629 printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);
630 printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);
30fdf114
LG
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) {
fd171542 914 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);
915 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);
30fdf114
LG
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
fd171542 931 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);
30fdf114
LG
932
933 *FvSize = Size;
934
935 //
936 // rewind (InputFile);
937 //
938 return EFI_SUCCESS;
939}
940
941STATIC
942EFI_STATUS
943PrintFileInfo (
944 EFI_FIRMWARE_VOLUME_HEADER *FvImage,
945 EFI_FFS_FILE_HEADER *FileHeader,
946 BOOLEAN ErasePolarity
947 )
948/*++
949
950Routine Description:
951
952 GC_TODO: Add function description
953
954Arguments:
955
956 FvImage - GC_TODO: add argument description
957 FileHeader - GC_TODO: add argument description
958 ErasePolarity - GC_TODO: add argument description
959
960Returns:
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));
fd171542 1005 printf ("File Length: 0x%08X\n", (unsigned) FileLength);
30fdf114
LG
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 //
b303ea72
LG
1062 Checksum = CalculateSum8 ((UINT8 *) (FileHeader + 1), FileLength - sizeof (EFI_FFS_FILE_HEADER));
1063 Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;
30fdf114
LG
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) {
b303ea72 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);
30fdf114
LG
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
b303ea72
LG
1137 case EFI_FV_FILETYPE_SMM:
1138 printf ("EFI_FV_FILETYPE_SMM\n");
1139 break;
1140
30fdf114
LG
1141 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
1142 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1143 break;
1144
b303ea72
LG
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
30fdf114
LG
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
1190EFI_STATUS
1191ParseSection (
1192 IN UINT8 *SectionBuffer,
1193 IN UINT32 BufferLength
1194 )
1195/*++
1196
1197Routine Description:
1198
1199 Parses EFI Sections
1200
1201Arguments:
1202
1203 SectionBuffer - Buffer containing the section to parse.
1204 BufferLength - Length of SectionBuffer
1205
1206Returns:
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");
fd171542 1261 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);
30fdf114
LG
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
30fdf114 1292 case EFI_SECTION_PEI_DEPEX:
b303ea72
LG
1293 case EFI_SECTION_DXE_DEPEX:
1294 case EFI_SECTION_SMM_DEPEX:
30fdf114
LG
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;
fd171542 1308 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);
30fdf114
LG
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 {
fd171542 1362 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);
30fdf114
LG
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");
fd171542 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);
30fdf114
LG
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 //
fd171542 1485 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);
30fdf114
LG
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
1504EFI_STATUS
1505DumpDepexSection (
1506 IN UINT8 *Ptr,
1507 IN UINT32 SectionLength
1508 )
1509/*++
1510
1511Routine Description:
1512
1513 GC_TODO: Add function description
1514
1515Arguments:
1516
1517 Ptr - GC_TODO: add argument description
1518 SectionLength - GC_TODO: add argument description
1519
1520Returns:
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:
fd171542 1608 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);
30fdf114
LG
1609 return EFI_SUCCESS;
1610 }
1611 }
1612
1613 return EFI_SUCCESS;
1614}
1615
1616EFI_STATUS
1617PrintGuidName (
1618 IN UINT8 *GuidStr
1619 )
1620/*++
1621
1622Routine Description:
1623
1624 GC_TODO: Add function description
1625
1626Arguments:
1627
1628 GuidStr - GC_TODO: add argument description
1629
1630Returns:
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
1656EFI_STATUS
1657ParseGuidBaseNameFile (
1658 CHAR8 *FileName
1659 )
1660/*++
1661
1662Routine Description:
1663
1664 GC_TODO: Add function description
1665
1666Arguments:
1667
1668 FileName - GC_TODO: add argument description
1669
1670Returns:
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
1712EFI_STATUS
1713FreeGuidBaseNameList (
1714 VOID
1715 )
1716/*++
1717
1718Routine Description:
1719
1720 GC_TODO: Add function description
1721
1722Arguments:
1723
1724 None
1725
1726Returns:
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
1744static
1745VOID
1746LoadGuidedSectionToolsTxt (
1747 IN CHAR8* FirmwareVolumeFilename
1748 )
1749{
1750 CHAR8* PeerFilename;
1751 CHAR8* Places[] = {
fd171542 1752 NULL,
1753 //NULL,
30fdf114
LG
1754 };
1755 UINTN Index;
1756
fd171542 1757 Places[0] = FirmwareVolumeFilename;
1758 //Places[1] = mUtilityFilename;
1759
30fdf114
LG
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
1776void
1777Usage (
1778 VOID
1779 )
1780/*++
1781
1782Routine Description:
1783
1784 GC_TODO: Add function description
1785
1786Arguments:
1787
1788 None
1789
1790Returns:
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