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