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