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