]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VolInfo/VolInfo.c
BaseTools/VolInfo: generate HASH value for each PE image
[mirror_edk2.git] / BaseTools / Source / C / VolInfo / VolInfo.c
1 /** @file
2 The tool dumps the contents of a firmware volume
3
4 Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <assert.h>
20 #ifdef __GNUC__
21 #include <unistd.h>
22 #else
23 #include <direct.h>
24 #endif
25
26 #include <FvLib.h>
27 #include <Common/UefiBaseTypes.h>
28 #include <Common/UefiCapsule.h>
29 #include <Common/PiFirmwareFile.h>
30 #include <Common/PiFirmwareVolume.h>
31 #include <Guid/PiFirmwareFileSystem.h>
32 #include <IndustryStandard/PeImage.h>
33 #include <Protocol/GuidedSectionExtraction.h>
34
35 #include "Compress.h"
36 #include "Decompress.h"
37 #include "VolInfo.h"
38 #include "CommonLib.h"
39 #include "EfiUtilityMsgs.h"
40 #include "FirmwareVolumeBufferLib.h"
41 #include "OsPath.h"
42 #include "ParseGuidedSectionTools.h"
43 #include "StringFuncs.h"
44 #include "ParseInf.h"
45 #include "PeCoffLib.h"
46
47 //
48 // Utility global variables
49 //
50
51 EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
52
53 #define UTILITY_MAJOR_VERSION 1
54 #define UTILITY_MINOR_VERSION 0
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 //
65 typedef 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
71 static GUID_TO_BASENAME *mGuidBaseNameList = NULL;
72
73 //
74 // Store GUIDed Section guid->tool mapping
75 //
76 EFI_HANDLE mParsedGuidedSectionTools = NULL;
77
78 CHAR8* mUtilityFilename = NULL;
79
80 BOOLEAN EnableHash = FALSE;
81 CHAR8 *OpenSslPath = NULL;
82
83 EFI_STATUS
84 ParseGuidBaseNameFile (
85 CHAR8 *FileName
86 );
87
88 EFI_STATUS
89 FreeGuidBaseNameList (
90 VOID
91 );
92
93 EFI_STATUS
94 PrintGuidName (
95 IN UINT8 *GuidStr
96 );
97
98 EFI_STATUS
99 ParseSection (
100 IN UINT8 *SectionBuffer,
101 IN UINT32 BufferLength
102 );
103
104 EFI_STATUS
105 DumpDepexSection (
106 IN UINT8 *Ptr,
107 IN UINT32 SectionLength
108 );
109
110 STATIC
111 EFI_STATUS
112 ReadHeader (
113 IN FILE *InputFile,
114 OUT UINT32 *FvSize,
115 OUT BOOLEAN *ErasePolarity
116 );
117
118 STATIC
119 EFI_STATUS
120 PrintFileInfo (
121 EFI_FIRMWARE_VOLUME_HEADER *FvImage,
122 EFI_FFS_FILE_HEADER *FileHeader,
123 BOOLEAN ErasePolarity
124 );
125
126 static
127 EFI_STATUS
128 PrintFvInfo (
129 IN VOID *Fv,
130 IN BOOLEAN IsChildFv
131 );
132
133 static
134 VOID
135 LoadGuidedSectionToolsTxt (
136 IN CHAR8* FirmwareVolumeFilename
137 );
138
139 EFI_STATUS
140 CombinePath (
141 IN CHAR8* DefaultPath,
142 IN CHAR8* AppendPath,
143 OUT CHAR8* NewPath
144 );
145
146 void
147 Usage (
148 VOID
149 );
150
151 int
152 main (
153 int argc,
154 char *argv[]
155 )
156 /*++
157
158 Routine Description:
159
160 GC_TODO: Add function description
161
162 Arguments:
163
164 argc - GC_TODO: add argument description
165 ] - GC_TODO: add argument description
166
167 Returns:
168
169 GC_TODO: add return values
170
171 --*/
172 {
173 FILE *InputFile;
174 int BytesRead;
175 EFI_FIRMWARE_VOLUME_HEADER *FvImage;
176 UINT32 FvSize;
177 EFI_STATUS Status;
178 int Offset;
179 BOOLEAN ErasePolarity;
180 UINT64 LogLevel;
181 CHAR8 *OpenSslEnv;
182 CHAR8 *OpenSslCommand;
183
184 SetUtilityName (UTILITY_NAME);
185 //
186 // Print utility header
187 //
188 printf ("%s Version %d.%d Build %s\n",
189 UTILITY_NAME,
190 UTILITY_MAJOR_VERSION,
191 UTILITY_MINOR_VERSION,
192 __BUILD_VERSION
193 );
194
195 if (argc == 1) {
196 Usage ();
197 return -1;
198 }
199
200 argc--;
201 argv++;
202 LogLevel = 0;
203 Offset = 0;
204
205 //
206 // Look for help options
207 //
208 if ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "--help") == 0) ||
209 (strcmp(argv[0], "-?") == 0) || (strcmp(argv[0], "/?") == 0)) {
210 Usage();
211 return STATUS_SUCCESS;
212 }
213 //
214 // Version has already be printed, so just return success
215 //
216 if (strcmp(argv[0], "--version") == 0) {
217 return STATUS_SUCCESS;
218 }
219
220 //
221 // If they specified -x xref guid/basename cross-reference files, process it.
222 // This will print the basename beside each file guid. To use it, specify
223 // -x xref_filename to processdsc, then use xref_filename as a parameter
224 // here.
225 //
226 while (argc > 0) {
227 if ((strcmp(argv[0], "-x") == 0) || (strcmp(argv[0], "--xref") == 0)) {
228 ParseGuidBaseNameFile (argv[1]);
229 printf("ParseGuidBaseNameFile: %s\n", argv[1]);
230 argc -= 2;
231 argv += 2;
232 continue;
233 }
234 if (strcmp(argv[0], "--offset") == 0) {
235 //
236 // Hex or decimal?
237 //
238 if ((argv[1][0] == '0') && (tolower ((int)argv[1][1]) == 'x')) {
239 if (sscanf (argv[1], "%x", &Offset) != 1) {
240 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);
241 return GetUtilityStatus ();
242 }
243 } else {
244 if (sscanf (argv[1], "%d", &Offset) != 1) {
245 Error (NULL, 0, 1003, "Invalid option value", "Offset = %s", argv[1]);
246 return GetUtilityStatus ();
247 }
248 //
249 // See if they said something like "64K"
250 //
251 if (tolower ((int)argv[1][strlen (argv[1]) - 1]) == 'k') {
252 Offset *= 1024;
253 }
254 }
255
256 argc -= 2;
257 argv += 2;
258 continue;
259 }
260 if ((stricmp (argv[0], "--hash") == 0)) {
261 EnableHash = TRUE;
262 OpenSslCommand = "openssl";
263 OpenSslEnv = getenv("OPENSSL_PATH");
264 if (OpenSslEnv == NULL) {
265 OpenSslPath = OpenSslCommand;
266 } else {
267 OpenSslPath = malloc(strlen(OpenSslEnv)+strlen(OpenSslCommand)+1);
268 CombinePath(OpenSslEnv, OpenSslCommand, OpenSslPath);
269 }
270 if (OpenSslPath == NULL){
271 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);
272 return GetUtilityStatus ();
273 }
274 argc --;
275 argv ++;
276 continue;
277 }
278
279 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {
280 SetPrintLevel (VERBOSE_LOG_LEVEL);
281 argc --;
282 argv ++;
283 continue;
284 }
285
286 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
287 SetPrintLevel (KEY_LOG_LEVEL);
288 argc --;
289 argv ++;
290 continue;
291 }
292
293 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
294 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);
295 if (EFI_ERROR (Status)) {
296 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
297 return -1;
298 }
299 if (LogLevel > 9) {
300 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);
301 return -1;
302 }
303 SetPrintLevel (LogLevel);
304 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);
305 argc -= 2;
306 argv += 2;
307 continue;
308 }
309
310 mUtilityFilename = argv[0];
311 argc --;
312 argv ++;
313 }
314
315 //
316 // Open the file containing the FV
317 //
318 if (mUtilityFilename == NULL) {
319 Error (NULL, 0, 1001, "Missing option", "Input files are not specified");
320 return GetUtilityStatus ();
321 }
322 InputFile = fopen (LongFilePath (mUtilityFilename), "rb");
323 if (InputFile == NULL) {
324 Error (NULL, 0, 0001, "Error opening the input file", mUtilityFilename);
325 return GetUtilityStatus ();
326 }
327 //
328 // Skip over pad bytes if specified. This is used if they prepend 0xff
329 // data to the FV image binary.
330 //
331 if (Offset != 0) {
332 fseek (InputFile, Offset, SEEK_SET);
333 }
334 //
335 // Determine size of FV
336 //
337 Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);
338 if (EFI_ERROR (Status)) {
339 Error (NULL, 0, 0003, "error parsing FV image", "%s Header is invalid", mUtilityFilename);
340 fclose (InputFile);
341 return GetUtilityStatus ();
342 }
343 //
344 // Allocate a buffer for the FV image
345 //
346 FvImage = malloc (FvSize);
347 if (FvImage == NULL) {
348 Error (NULL, 0, 4001, "Resource: Memory can't be allocated", NULL);
349 fclose (InputFile);
350 return GetUtilityStatus ();
351 }
352 //
353 // Seek to the start of the image, then read the entire FV to the buffer
354 //
355 fseek (InputFile, Offset, SEEK_SET);
356 BytesRead = fread (FvImage, 1, FvSize, InputFile);
357 fclose (InputFile);
358 if ((unsigned int) BytesRead != FvSize) {
359 Error (NULL, 0, 0004, "error reading FvImage from", mUtilityFilename);
360 free (FvImage);
361 return GetUtilityStatus ();
362 }
363
364 LoadGuidedSectionToolsTxt (mUtilityFilename);
365
366 PrintFvInfo (FvImage, FALSE);
367
368 //
369 // Clean up
370 //
371 free (FvImage);
372 FreeGuidBaseNameList ();
373 return GetUtilityStatus ();
374 }
375
376
377 static
378 EFI_STATUS
379 PrintFvInfo (
380 IN VOID *Fv,
381 IN BOOLEAN IsChildFv
382 )
383 /*++
384
385 Routine Description:
386
387 GC_TODO: Add function description
388
389 Arguments:
390
391 Fv - Firmware Volume to print information about
392 IsChildFv - Flag specifies whether the input FV is a child FV.
393
394 Returns:
395
396 EFI_STATUS
397
398 --*/
399 {
400 EFI_STATUS Status;
401 UINTN NumberOfFiles;
402 BOOLEAN ErasePolarity;
403 UINTN FvSize;
404 EFI_FFS_FILE_HEADER *CurrentFile;
405 UINTN Key;
406
407 Status = FvBufGetSize (Fv, &FvSize);
408
409 NumberOfFiles = 0;
410 ErasePolarity =
411 (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Attributes & EFI_FVB2_ERASE_POLARITY) ?
412 TRUE : FALSE;
413
414 //
415 // Get the first file
416 //
417 Key = 0;
418 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
419 if (EFI_ERROR (Status)) {
420 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the first file in the FV image");
421 return GetUtilityStatus ();
422 }
423 //
424 // Display information about files found
425 //
426 while (CurrentFile != NULL) {
427 //
428 // Increment the number of files counter
429 //
430 NumberOfFiles++;
431
432 //
433 // Display info about this file
434 //
435 Status = PrintFileInfo (Fv, CurrentFile, ErasePolarity);
436 if (EFI_ERROR (Status)) {
437 Error (NULL, 0, 0003, "error parsing FV image", "failed to parse a file in the FV");
438 return GetUtilityStatus ();
439 }
440 //
441 // Get the next file
442 //
443 Status = FvBufFindNextFile (Fv, &Key, (VOID **) &CurrentFile);
444 if (Status == EFI_NOT_FOUND) {
445 CurrentFile = NULL;
446 } else if (EFI_ERROR (Status)) {
447 Error (NULL, 0, 0003, "error parsing FV image", "cannot find the next file in the FV image");
448 return GetUtilityStatus ();
449 }
450 }
451
452 if (IsChildFv) {
453 printf ("There are a total of %d files in the child FV\n", (int) NumberOfFiles);
454 } else {
455 printf ("There are a total of %d files in this FV\n", (int) NumberOfFiles);
456 }
457
458 return EFI_SUCCESS;
459 }
460
461 UINT32
462 GetOccupiedSize (
463 IN UINT32 ActualSize,
464 IN UINT32 Alignment
465 )
466 /*++
467
468 Routine Description:
469
470 This function returns the next larger size that meets the alignment
471 requirement specified.
472
473 Arguments:
474
475 ActualSize The size.
476 Alignment The desired alignment.
477
478 Returns:
479
480 EFI_SUCCESS Function completed successfully.
481 EFI_ABORTED The function encountered an error.
482
483 --*/
484 {
485 UINT32 OccupiedSize;
486
487 OccupiedSize = ActualSize;
488 while ((OccupiedSize & (Alignment - 1)) != 0) {
489 OccupiedSize++;
490 }
491
492 return OccupiedSize;
493 }
494
495 static
496 CHAR8 *
497 SectionNameToStr (
498 IN EFI_SECTION_TYPE Type
499 )
500 /*++
501
502 Routine Description:
503
504 Converts EFI Section names to Strings
505
506 Arguments:
507
508 Type - The EFI Section type
509
510 Returns:
511
512 CHAR8* - Pointer to the String containing the section name.
513
514 --*/
515 {
516 CHAR8 *SectionStr;
517 CHAR8 *SectionTypeStringTable[] = {
518 //
519 // 0X00
520 //
521 "EFI_SECTION_ALL",
522 //
523 // 0x01
524 //
525 "EFI_SECTION_COMPRESSION",
526 //
527 // 0x02
528 //
529 "EFI_SECTION_GUID_DEFINED",
530 //
531 // 0x03
532 //
533 "Unknown section type - Reserved 0x03",
534 //
535 // 0x04
536 //
537 "Unknown section type - Reserved 0x04",
538 //
539 // 0x05
540 //
541 "Unknown section type - Reserved 0x05",
542 //
543 // 0x06
544 //
545 "Unknown section type - Reserved 0x06",
546 //
547 // 0x07
548 //
549 "Unknown section type - Reserved 0x07",
550 //
551 // 0x08
552 //
553 "Unknown section type - Reserved 0x08",
554 //
555 // 0x09
556 //
557 "Unknown section type - Reserved 0x09",
558 //
559 // 0x0A
560 //
561 "Unknown section type - Reserved 0x0A",
562 //
563 // 0x0B
564 //
565 "Unknown section type - Reserved 0x0B",
566 //
567 // 0x0C
568 //
569 "Unknown section type - Reserved 0x0C",
570 //
571 // 0x0D
572 //
573 "Unknown section type - Reserved 0x0D",
574 //
575 // 0x0E
576 //
577 "Unknown section type - Reserved 0x0E",
578 //
579 // 0x0F
580 //
581 "Unknown section type - Reserved 0x0E",
582 //
583 // 0x10
584 //
585 "EFI_SECTION_PE32",
586 //
587 // 0x11
588 //
589 "EFI_SECTION_PIC",
590 //
591 // 0x12
592 //
593 "EFI_SECTION_TE",
594 //
595 // 0x13
596 //
597 "EFI_SECTION_DXE_DEPEX",
598 //
599 // 0x14
600 //
601 "EFI_SECTION_VERSION",
602 //
603 // 0x15
604 //
605 "EFI_SECTION_USER_INTERFACE",
606 //
607 // 0x16
608 //
609 "EFI_SECTION_COMPATIBILITY16",
610 //
611 // 0x17
612 //
613 "EFI_SECTION_FIRMWARE_VOLUME_IMAGE ",
614 //
615 // 0x18
616 //
617 "EFI_SECTION_FREEFORM_SUBTYPE_GUID ",
618 //
619 // 0x19
620 //
621 "EFI_SECTION_RAW",
622 //
623 // 0x1A
624 //
625 "Unknown section type - 0x1A",
626 //
627 // 0x1B
628 //
629 "EFI_SECTION_PEI_DEPEX",
630 //
631 // 0x1C
632 //
633 "EFI_SECTION_SMM_DEPEX",
634 //
635 // 0x1C+
636 //
637 "Unknown section type - Reserved - beyond last defined section"
638 };
639
640 if (Type > EFI_SECTION_LAST_SECTION_TYPE) {
641 Type = EFI_SECTION_LAST_SECTION_TYPE + 1;
642 }
643
644 SectionStr = malloc (100);
645 if (SectionStr == NULL) {
646 printf ("Error: Out of memory resources.\n");
647 return SectionStr;
648 }
649 strcpy (SectionStr, SectionTypeStringTable[Type]);
650 return SectionStr;
651 }
652
653 STATIC
654 EFI_STATUS
655 ReadHeader (
656 IN FILE *InputFile,
657 OUT UINT32 *FvSize,
658 OUT BOOLEAN *ErasePolarity
659 )
660 /*++
661
662 Routine Description:
663
664 This function determines the size of the FV and the erase polarity. The
665 erase polarity is the FALSE value for file state.
666
667 Arguments:
668
669 InputFile The file that contains the FV image.
670 FvSize The size of the FV.
671 ErasePolarity The FV erase polarity.
672
673 Returns:
674
675 EFI_SUCCESS Function completed successfully.
676 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
677 EFI_ABORTED The function encountered an error.
678
679 --*/
680 {
681 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
682 EFI_FV_BLOCK_MAP_ENTRY BlockMap;
683 UINTN Signature[2];
684 UINTN BytesRead;
685 UINT32 Size;
686
687 BytesRead = 0;
688 Size = 0;
689 //
690 // Check input parameters
691 //
692 if (InputFile == NULL || FvSize == NULL || ErasePolarity == NULL) {
693 Error (__FILE__, __LINE__, 0, "application error", "invalid parameter to function");
694 return EFI_INVALID_PARAMETER;
695 }
696 //
697 // Read the header
698 //
699 fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
700 BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
701 Signature[0] = VolumeHeader.Signature;
702 Signature[1] = 0;
703
704 //
705 // Print FV header information
706 //
707 printf ("Signature: %s (%X)\n", (char *) Signature, (unsigned) VolumeHeader.Signature);
708 printf ("Attributes: %X\n", (unsigned) VolumeHeader.Attributes);
709
710 if (VolumeHeader.Attributes & EFI_FVB2_READ_DISABLED_CAP) {
711 printf (" EFI_FVB2_READ_DISABLED_CAP\n");
712 }
713
714 if (VolumeHeader.Attributes & EFI_FVB2_READ_ENABLED_CAP) {
715 printf (" EFI_FVB2_READ_ENABLED_CAP\n");
716 }
717
718 if (VolumeHeader.Attributes & EFI_FVB2_READ_STATUS) {
719 printf (" EFI_FVB2_READ_STATUS\n");
720 }
721
722 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_DISABLED_CAP) {
723 printf (" EFI_FVB2_WRITE_DISABLED_CAP\n");
724 }
725
726 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_ENABLED_CAP) {
727 printf (" EFI_FVB2_WRITE_ENABLED_CAP\n");
728 }
729
730 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_STATUS) {
731 printf (" EFI_FVB2_WRITE_STATUS\n");
732 }
733
734 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_CAP) {
735 printf (" EFI_FVB2_LOCK_CAP\n");
736 }
737
738 if (VolumeHeader.Attributes & EFI_FVB2_LOCK_STATUS) {
739 printf (" EFI_FVB2_LOCK_STATUS\n");
740 }
741
742 if (VolumeHeader.Attributes & EFI_FVB2_STICKY_WRITE) {
743 printf (" EFI_FVB2_STICKY_WRITE\n");
744 }
745
746 if (VolumeHeader.Attributes & EFI_FVB2_MEMORY_MAPPED) {
747 printf (" EFI_FVB2_MEMORY_MAPPED\n");
748 }
749
750 if (VolumeHeader.Attributes & EFI_FVB2_ERASE_POLARITY) {
751 printf (" EFI_FVB2_ERASE_POLARITY\n");
752 *ErasePolarity = TRUE;
753 }
754
755 #if (PI_SPECIFICATION_VERSION < 0x00010000)
756 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT) {
757 printf (" EFI_FVB2_ALIGNMENT\n");
758 }
759
760 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {
761 printf (" EFI_FVB2_ALIGNMENT_2\n");
762 }
763
764 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {
765 printf (" EFI_FVB2_ALIGNMENT_4\n");
766 }
767
768 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {
769 printf (" EFI_FVB2_ALIGNMENT_8\n");
770 }
771
772 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {
773 printf (" EFI_FVB2_ALIGNMENT_16\n");
774 }
775
776 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {
777 printf (" EFI_FVB2_ALIGNMENT_32\n");
778 }
779
780 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {
781 printf (" EFI_FVB2_ALIGNMENT_64\n");
782 }
783
784 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {
785 printf (" EFI_FVB2_ALIGNMENT_128\n");
786 }
787
788 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {
789 printf (" EFI_FVB2_ALIGNMENT_256\n");
790 }
791
792 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {
793 printf (" EFI_FVB2_ALIGNMENT_512\n");
794 }
795
796 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {
797 printf (" EFI_FVB2_ALIGNMENT_1K\n");
798 }
799
800 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {
801 printf (" EFI_FVB2_ALIGNMENT_2K\n");
802 }
803
804 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {
805 printf (" EFI_FVB2_ALIGNMENT_4K\n");
806 }
807
808 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {
809 printf (" EFI_FVB2_ALIGNMENT_8K\n");
810 }
811
812 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {
813 printf (" EFI_FVB2_ALIGNMENT_16K\n");
814 }
815
816 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {
817 printf (" EFI_FVB2_ALIGNMENT_32K\n");
818 }
819
820 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {
821 printf (" EFI_FVB2_ALIGNMENT_64K\n");
822 }
823
824 #else
825
826 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_CAP) {
827 printf (" EFI_FVB2_READ_LOCK_CAP\n");
828 }
829
830 if (VolumeHeader.Attributes & EFI_FVB2_READ_LOCK_STATUS) {
831 printf (" EFI_FVB2_READ_LOCK_STATUS\n");
832 }
833
834 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_CAP) {
835 printf (" EFI_FVB2_WRITE_LOCK_CAP\n");
836 }
837
838 if (VolumeHeader.Attributes & EFI_FVB2_WRITE_LOCK_STATUS) {
839 printf (" EFI_FVB2_WRITE_LOCK_STATUS\n");
840 }
841
842 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1) {
843 printf (" EFI_FVB2_ALIGNMENT_1\n");
844 }
845
846 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2) {
847 printf (" EFI_FVB2_ALIGNMENT_2\n");
848 }
849
850 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4) {
851 printf (" EFI_FVB2_ALIGNMENT_4\n");
852 }
853
854 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8) {
855 printf (" EFI_FVB2_ALIGNMENT_8\n");
856 }
857
858 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16) {
859 printf (" EFI_FVB2_ALIGNMENT_16\n");
860 }
861
862 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32) {
863 printf (" EFI_FVB2_ALIGNMENT_32\n");
864 }
865
866 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64) {
867 printf (" EFI_FVB2_ALIGNMENT_64\n");
868 }
869
870 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128) {
871 printf (" EFI_FVB2_ALIGNMENT_128\n");
872 }
873
874 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256) {
875 printf (" EFI_FVB2_ALIGNMENT_256\n");
876 }
877
878 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512) {
879 printf (" EFI_FVB2_ALIGNMENT_512\n");
880 }
881
882 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1K) {
883 printf (" EFI_FVB2_ALIGNMENT_1K\n");
884 }
885
886 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2K) {
887 printf (" EFI_FVB2_ALIGNMENT_2K\n");
888 }
889
890 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4K) {
891 printf (" EFI_FVB2_ALIGNMENT_4K\n");
892 }
893
894 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8K) {
895 printf (" EFI_FVB2_ALIGNMENT_8K\n");
896 }
897
898 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16K) {
899 printf (" EFI_FVB2_ALIGNMENT_16K\n");
900 }
901
902 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32K) {
903 printf (" EFI_FVB2_ALIGNMENT_32K\n");
904 }
905
906 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64K) {
907 printf (" EFI_FVB2_ALIGNMENT_64K\n");
908 }
909
910 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128K) {
911 printf (" EFI_FVB2_ALIGNMENT_128K\n");
912 }
913
914 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256K) {
915 printf (" EFI_FVB2_ALIGNMENT_256K\n");
916 }
917
918 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512K) {
919 printf (" EFI_FVB2_ALIGNMENT_512K\n");
920 }
921
922 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1M) {
923 printf (" EFI_FVB2_ALIGNMENT_1M\n");
924 }
925
926 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2M) {
927 printf (" EFI_FVB2_ALIGNMENT_2M\n");
928 }
929
930 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_4M) {
931 printf (" EFI_FVB2_ALIGNMENT_4M\n");
932 }
933
934 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_8M) {
935 printf (" EFI_FVB2_ALIGNMENT_8M\n");
936 }
937
938 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_16M) {
939 printf (" EFI_FVB2_ALIGNMENT_16M\n");
940 }
941
942 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_32M) {
943 printf (" EFI_FVB2_ALIGNMENT_32M\n");
944 }
945
946 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
947 printf (" EFI_FVB2_ALIGNMENT_64M\n");
948 }
949
950 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
951 printf (" EFI_FVB2_ALIGNMENT_128M\n");
952 }
953
954 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_64M) {
955 printf (" EFI_FVB2_ALIGNMENT_64M\n");
956 }
957
958 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_128M) {
959 printf (" EFI_FVB2_ALIGNMENT_128M\n");
960 }
961
962 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_256M) {
963 printf (" EFI_FVB2_ALIGNMENT_256M\n");
964 }
965
966 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_512M) {
967 printf (" EFI_FVB2_ALIGNMENT_512M\n");
968 }
969
970 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_1G) {
971 printf (" EFI_FVB2_ALIGNMENT_1G\n");
972 }
973
974 if (VolumeHeader.Attributes & EFI_FVB2_ALIGNMENT_2G) {
975 printf (" EFI_FVB2_ALIGNMENT_2G\n");
976 }
977
978 #endif
979 printf ("Header Length: 0x%08X\n", VolumeHeader.HeaderLength);
980 printf ("File System ID: ");
981 PrintGuid (&VolumeHeader.FileSystemGuid);
982 //
983 // printf ("\n");
984 //
985 printf ("Revision: 0x%04X\n", VolumeHeader.Revision);
986
987 do {
988 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
989 BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
990
991 if (BlockMap.NumBlocks != 0) {
992 printf ("Number of Blocks: 0x%08X\n", (unsigned) BlockMap.NumBlocks);
993 printf ("Block Length: 0x%08X\n", (unsigned) BlockMap.Length);
994 Size += BlockMap.NumBlocks * BlockMap.Length;
995 }
996
997 } while (!(BlockMap.NumBlocks == 0 && BlockMap.Length == 0));
998
999 if (BytesRead != VolumeHeader.HeaderLength) {
1000 printf ("ERROR: Header length not consistent with Block Maps!\n");
1001 return EFI_ABORTED;
1002 }
1003
1004 if (VolumeHeader.FvLength != Size) {
1005 printf ("ERROR: Volume Size not consistant with Block Maps!\n");
1006 return EFI_ABORTED;
1007 }
1008
1009 printf ("Total Volume Size: 0x%08X\n", (unsigned) Size);
1010
1011 *FvSize = Size;
1012
1013 //
1014 // rewind (InputFile);
1015 //
1016 return EFI_SUCCESS;
1017 }
1018
1019 STATIC
1020 EFI_STATUS
1021 PrintFileInfo (
1022 EFI_FIRMWARE_VOLUME_HEADER *FvImage,
1023 EFI_FFS_FILE_HEADER *FileHeader,
1024 BOOLEAN ErasePolarity
1025 )
1026 /*++
1027
1028 Routine Description:
1029
1030 GC_TODO: Add function description
1031
1032 Arguments:
1033
1034 FvImage - GC_TODO: add argument description
1035 FileHeader - GC_TODO: add argument description
1036 ErasePolarity - GC_TODO: add argument description
1037
1038 Returns:
1039
1040 EFI_SUCCESS - GC_TODO: Add description for return value
1041 EFI_ABORTED - GC_TODO: Add description for return value
1042
1043 --*/
1044 {
1045 UINT32 FileLength;
1046 UINT8 FileState;
1047 UINT8 Checksum;
1048 EFI_FFS_FILE_HEADER2 BlankHeader;
1049 EFI_STATUS Status;
1050 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
1051 UINT32 HeaderSize;
1052 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1053 UINT16 *Tail;
1054 #endif
1055 //
1056 // Check if we have free space
1057 //
1058 HeaderSize = FvBufGetFfsHeaderSize(FileHeader);
1059 if (ErasePolarity) {
1060 memset (&BlankHeader, -1, HeaderSize);
1061 } else {
1062 memset (&BlankHeader, 0, HeaderSize);
1063 }
1064
1065 if (memcmp (&BlankHeader, FileHeader, HeaderSize) == 0) {
1066 return EFI_SUCCESS;
1067 }
1068 //
1069 // Print file information.
1070 //
1071 printf ("============================================================\n");
1072
1073 printf ("File Name: ");
1074 PrintGuidToBuffer (&FileHeader->Name, GuidBuffer, sizeof (GuidBuffer), TRUE);
1075 printf ("%s ", GuidBuffer);
1076 PrintGuidName (GuidBuffer);
1077 printf ("\n");
1078
1079 //
1080 // PrintGuid (&FileHeader->Name);
1081 // printf ("\n");
1082 //
1083 FileLength = FvBufGetFfsFileSize (FileHeader);
1084 printf ("File Offset: 0x%08X\n", (unsigned) ((UINTN) FileHeader - (UINTN) FvImage));
1085 printf ("File Length: 0x%08X\n", (unsigned) FileLength);
1086 printf ("File Attributes: 0x%02X\n", FileHeader->Attributes);
1087 printf ("File State: 0x%02X\n", FileHeader->State);
1088
1089 //
1090 // Print file state
1091 //
1092 FileState = GetFileState (ErasePolarity, FileHeader);
1093
1094 switch (FileState) {
1095
1096 case EFI_FILE_HEADER_CONSTRUCTION:
1097 printf (" EFI_FILE_HEADER_CONSTRUCTION\n");
1098 return EFI_SUCCESS;
1099
1100 case EFI_FILE_HEADER_INVALID:
1101 printf (" EFI_FILE_HEADER_INVALID\n");
1102 return EFI_SUCCESS;
1103
1104 case EFI_FILE_HEADER_VALID:
1105 printf (" EFI_FILE_HEADER_VALID\n");
1106 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);
1107 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
1108 Checksum = (UINT8) (Checksum - FileHeader->State);
1109 if (Checksum != 0) {
1110 printf ("ERROR: Header checksum invalid.\n");
1111 return EFI_ABORTED;
1112 }
1113
1114 return EFI_SUCCESS;
1115
1116 case EFI_FILE_DELETED:
1117 printf (" EFI_FILE_DELETED\n");
1118
1119 case EFI_FILE_MARKED_FOR_UPDATE:
1120 printf (" EFI_FILE_MARKED_FOR_UPDATE\n");
1121
1122 case EFI_FILE_DATA_VALID:
1123 printf (" EFI_FILE_DATA_VALID\n");
1124
1125 //
1126 // Calculate header checksum
1127 //
1128 Checksum = CalculateSum8 ((UINT8 *) FileHeader, HeaderSize);
1129 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);
1130 Checksum = (UINT8) (Checksum - FileHeader->State);
1131 if (Checksum != 0) {
1132 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid header checksum", GuidBuffer);
1133 return EFI_ABORTED;
1134 }
1135
1136 FileLength = FvBufGetFfsFileSize (FileHeader);
1137
1138 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
1139 //
1140 // Calculate file checksum
1141 //
1142 Checksum = CalculateSum8 ((UINT8 *)FileHeader + HeaderSize, FileLength - HeaderSize);
1143 Checksum = Checksum + FileHeader->IntegrityCheck.Checksum.File;
1144 if (Checksum != 0) {
1145 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has invalid file checksum", GuidBuffer);
1146 return EFI_ABORTED;
1147 }
1148 } else {
1149 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {
1150 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);
1151 return EFI_ABORTED;
1152 }
1153 }
1154 #if (PI_SPECIFICATION_VERSION < 0x00010000)
1155 //
1156 // Verify tail if present
1157 //
1158 if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
1159 //
1160 // Verify tail is complement of integrity check field in the header.
1161 //
1162 Tail = (UINT16 *) ((UINTN) FileHeader + GetLength (FileHeader->Size) - sizeof (EFI_FFS_INTEGRITY_CHECK));
1163 if (FileHeader->IntegrityCheck.TailReference != (UINT16)~(*Tail)) {
1164 Error (NULL, 0, 0003, "error parsing FFS file", \
1165 "FFS file with Guid %s failed in the integrity check, tail is not the complement of the header field", GuidBuffer);
1166 return EFI_ABORTED;
1167 }
1168 }
1169 #endif
1170 break;
1171
1172 default:
1173 Error (NULL, 0, 0003, "error parsing FFS file", "FFS file with Guid %s has the invalid/unrecognized file state bits", GuidBuffer);
1174 return EFI_ABORTED;
1175 }
1176
1177 printf ("File Type: 0x%02X ", FileHeader->Type);
1178
1179 switch (FileHeader->Type) {
1180
1181 case EFI_FV_FILETYPE_RAW:
1182 printf ("EFI_FV_FILETYPE_RAW\n");
1183 break;
1184
1185 case EFI_FV_FILETYPE_FREEFORM:
1186 printf ("EFI_FV_FILETYPE_FREEFORM\n");
1187 break;
1188
1189 case EFI_FV_FILETYPE_SECURITY_CORE:
1190 printf ("EFI_FV_FILETYPE_SECURITY_CORE\n");
1191 break;
1192
1193 case EFI_FV_FILETYPE_PEI_CORE:
1194 printf ("EFI_FV_FILETYPE_PEI_CORE\n");
1195 break;
1196
1197 case EFI_FV_FILETYPE_DXE_CORE:
1198 printf ("EFI_FV_FILETYPE_DXE_CORE\n");
1199 break;
1200
1201 case EFI_FV_FILETYPE_PEIM:
1202 printf ("EFI_FV_FILETYPE_PEIM\n");
1203 break;
1204
1205 case EFI_FV_FILETYPE_DRIVER:
1206 printf ("EFI_FV_FILETYPE_DRIVER\n");
1207 break;
1208
1209 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
1210 printf ("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\n");
1211 break;
1212
1213 case EFI_FV_FILETYPE_APPLICATION:
1214 printf ("EFI_FV_FILETYPE_APPLICATION\n");
1215 break;
1216
1217 case EFI_FV_FILETYPE_SMM:
1218 printf ("EFI_FV_FILETYPE_SMM\n");
1219 break;
1220
1221 case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:
1222 printf ("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\n");
1223 break;
1224
1225 case EFI_FV_FILETYPE_COMBINED_SMM_DXE:
1226 printf ("EFI_FV_FILETYPE_COMBINED_SMM_DXE\n");
1227 break;
1228
1229 case EFI_FV_FILETYPE_SMM_CORE:
1230 printf ("EFI_FV_FILETYPE_SMM_CORE\n");
1231 break;
1232
1233 case EFI_FV_FILETYPE_FFS_PAD:
1234 printf ("EFI_FV_FILETYPE_FFS_PAD\n");
1235 break;
1236
1237 default:
1238 printf ("\nERROR: Unrecognized file type %X.\n", FileHeader->Type);
1239 return EFI_ABORTED;
1240 break;
1241 }
1242
1243 switch (FileHeader->Type) {
1244
1245 case EFI_FV_FILETYPE_ALL:
1246 case EFI_FV_FILETYPE_RAW:
1247 case EFI_FV_FILETYPE_FFS_PAD:
1248 break;
1249
1250 default:
1251 //
1252 // All other files have sections
1253 //
1254 Status = ParseSection (
1255 (UINT8 *) ((UINTN) FileHeader + HeaderSize),
1256 FvBufGetFfsFileSize (FileHeader) - HeaderSize
1257 );
1258 if (EFI_ERROR (Status)) {
1259 //
1260 // printf ("ERROR: Parsing the FFS file.\n");
1261 //
1262 return EFI_ABORTED;
1263 }
1264 break;
1265 }
1266
1267 return EFI_SUCCESS;
1268 }
1269
1270 EFI_STATUS
1271 RebaseImageRead (
1272 IN VOID *FileHandle,
1273 IN UINTN FileOffset,
1274 IN OUT UINT32 *ReadSize,
1275 OUT VOID *Buffer
1276 )
1277 /*++
1278
1279 Routine Description:
1280
1281 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
1282
1283 Arguments:
1284
1285 FileHandle - The handle to the PE/COFF file
1286
1287 FileOffset - The offset, in bytes, into the file to read
1288
1289 ReadSize - The number of bytes to read from the file starting at FileOffset
1290
1291 Buffer - A pointer to the buffer to read the data into.
1292
1293 Returns:
1294
1295 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1296
1297 --*/
1298 {
1299 CHAR8 *Destination8;
1300 CHAR8 *Source8;
1301 UINT32 Length;
1302
1303 Destination8 = Buffer;
1304 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
1305 Length = *ReadSize;
1306 while (Length--) {
1307 *(Destination8++) = *(Source8++);
1308 }
1309
1310 return EFI_SUCCESS;
1311 }
1312
1313 EFI_STATUS
1314 SetAddressToSectionHeader (
1315 IN CHAR8 *FileName,
1316 IN OUT UINT8 *FileBuffer,
1317 IN UINT64 NewPe32BaseAddress
1318 )
1319 /*++
1320
1321 Routine Description:
1322
1323 Set new base address into the section header of PeImage
1324
1325 Arguments:
1326
1327 FileName - Name of file
1328 FileBuffer - Pointer to PeImage.
1329 NewPe32BaseAddress - New Base Address for PE image.
1330
1331 Returns:
1332
1333 EFI_SUCCESS Set new base address into this image successfully.
1334
1335 --*/
1336 {
1337 EFI_STATUS Status;
1338 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
1339 UINTN Index;
1340 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
1341 EFI_IMAGE_SECTION_HEADER *SectionHeader;
1342
1343 //
1344 // Initialize context
1345 //
1346 memset (&ImageContext, 0, sizeof (ImageContext));
1347 ImageContext.Handle = (VOID *) FileBuffer;
1348 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
1349 Status = PeCoffLoaderGetImageInfo (&ImageContext);
1350 if (EFI_ERROR (Status)) {
1351 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
1352 return Status;
1353 }
1354
1355 if (ImageContext.RelocationsStripped) {
1356 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
1357 return Status;
1358 }
1359
1360 //
1361 // Get PeHeader pointer
1362 //
1363 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
1364
1365 //
1366 // Get section header list
1367 //
1368 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
1369 (UINTN) ImgHdr +
1370 sizeof (UINT32) +
1371 sizeof (EFI_IMAGE_FILE_HEADER) +
1372 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
1373 );
1374
1375 //
1376 // Set base address into the first section header that doesn't point to code section.
1377 //
1378 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
1379 if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
1380 *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;
1381 break;
1382 }
1383 }
1384
1385 //
1386 // No available section header is found.
1387 //
1388 if (Index == ImgHdr->Pe32.FileHeader.NumberOfSections) {
1389 return EFI_NOT_FOUND;
1390 }
1391
1392 //
1393 // BaseAddress is set to section header.
1394 //
1395 return EFI_SUCCESS;
1396 }
1397
1398 EFI_STATUS
1399 RebaseImage (
1400 IN CHAR8 *FileName,
1401 IN OUT UINT8 *FileBuffer,
1402 IN UINT64 NewPe32BaseAddress
1403 )
1404 /*++
1405
1406 Routine Description:
1407
1408 Set new base address into PeImage, and fix up PeImage based on new address.
1409
1410 Arguments:
1411
1412 FileName - Name of file
1413 FileBuffer - Pointer to PeImage.
1414 NewPe32BaseAddress - New Base Address for PE image.
1415
1416 Returns:
1417
1418 EFI_INVALID_PARAMETER - BaseAddress is not valid.
1419 EFI_SUCCESS - Update PeImage is correctly.
1420
1421 --*/
1422 {
1423 EFI_STATUS Status;
1424 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
1425 UINTN Index;
1426 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
1427 UINT8 *MemoryImagePointer;
1428 EFI_IMAGE_SECTION_HEADER *SectionHeader;
1429
1430 //
1431 // Initialize context
1432 //
1433 memset (&ImageContext, 0, sizeof (ImageContext));
1434 ImageContext.Handle = (VOID *) FileBuffer;
1435 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
1436 Status = PeCoffLoaderGetImageInfo (&ImageContext);
1437 if (EFI_ERROR (Status)) {
1438 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
1439 return Status;
1440 }
1441
1442 if (ImageContext.RelocationsStripped) {
1443 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
1444 return Status;
1445 }
1446
1447 //
1448 // Get PeHeader pointer
1449 //
1450 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
1451
1452 //
1453 // Load and Relocate Image Data
1454 //
1455 MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
1456 if (MemoryImagePointer == NULL) {
1457 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
1458 return EFI_OUT_OF_RESOURCES;
1459 }
1460 memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
1461 ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));
1462
1463 Status = PeCoffLoaderLoadImage (&ImageContext);
1464 if (EFI_ERROR (Status)) {
1465 Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
1466 free ((VOID *) MemoryImagePointer);
1467 return Status;
1468 }
1469
1470 ImageContext.DestinationAddress = NewPe32BaseAddress;
1471 Status = PeCoffLoaderRelocateImage (&ImageContext);
1472 if (EFI_ERROR (Status)) {
1473 Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
1474 free ((VOID *) MemoryImagePointer);
1475 return Status;
1476 }
1477
1478 //
1479 // Copy Relocated data to raw image file.
1480 //
1481 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
1482 (UINTN) ImgHdr +
1483 sizeof (UINT32) +
1484 sizeof (EFI_IMAGE_FILE_HEADER) +
1485 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
1486 );
1487
1488 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
1489 CopyMem (
1490 FileBuffer + SectionHeader->PointerToRawData,
1491 (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
1492 SectionHeader->SizeOfRawData
1493 );
1494 }
1495
1496 free ((VOID *) MemoryImagePointer);
1497
1498 //
1499 // Update Image Base Address
1500 //
1501 if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {
1502 ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
1503 } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
1504 ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
1505 } else {
1506 Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
1507 ImgHdr->Pe32.OptionalHeader.Magic,
1508 FileName
1509 );
1510 return EFI_ABORTED;
1511 }
1512
1513 //
1514 // Set new base address into section header
1515 //
1516 Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);
1517
1518 return Status;
1519 }
1520
1521 EFI_STATUS
1522 CombinePath (
1523 IN CHAR8* DefaultPath,
1524 IN CHAR8* AppendPath,
1525 OUT CHAR8* NewPath
1526 )
1527 {
1528 UINT32 DefaultPathLen;
1529 DefaultPathLen = strlen(DefaultPath);
1530 strcpy(NewPath, DefaultPath);
1531 UINT64 Index = 0;
1532 for (; Index < DefaultPathLen; Index ++) {
1533 if (NewPath[Index] == '\\' || NewPath[Index] == '/') {
1534 if (NewPath[Index + 1] != '\0') {
1535 NewPath[Index] = '/';
1536 }
1537 }
1538 }
1539 if (NewPath[Index -1] != '/') {
1540 NewPath[Index] = '/';
1541 NewPath[Index + 1] = '\0';
1542 }
1543 strcat(NewPath, AppendPath);
1544 return EFI_SUCCESS;
1545 }
1546
1547 EFI_STATUS
1548 ParseSection (
1549 IN UINT8 *SectionBuffer,
1550 IN UINT32 BufferLength
1551 )
1552 /*++
1553
1554 Routine Description:
1555
1556 Parses EFI Sections
1557
1558 Arguments:
1559
1560 SectionBuffer - Buffer containing the section to parse.
1561 BufferLength - Length of SectionBuffer
1562
1563 Returns:
1564
1565 EFI_SECTION_ERROR - Problem with section parsing.
1566 (a) compression errors
1567 (b) unrecognized section
1568 EFI_UNSUPPORTED - Do not know how to parse the section.
1569 EFI_SUCCESS - Section successfully parsed.
1570 EFI_OUT_OF_RESOURCES - Memory allocation failed.
1571
1572 --*/
1573 {
1574 EFI_SECTION_TYPE Type;
1575 UINT8 *Ptr;
1576 UINT32 SectionLength;
1577 UINT32 SectionHeaderLen;
1578 CHAR8 *SectionName;
1579 EFI_STATUS Status;
1580 UINT32 ParsedLength;
1581 UINT8 *CompressedBuffer;
1582 UINT32 CompressedLength;
1583 UINT8 *UncompressedBuffer;
1584 UINT32 UncompressedLength;
1585 UINT8 *ToolOutputBuffer;
1586 UINT32 ToolOutputLength;
1587 UINT8 CompressionType;
1588 UINT32 DstSize;
1589 UINT32 ScratchSize;
1590 UINT8 *ScratchBuffer;
1591 DECOMPRESS_FUNCTION DecompressFunction;
1592 GETINFO_FUNCTION GetInfoFunction;
1593 // CHAR16 *name;
1594 CHAR8 *ExtractionTool;
1595 CHAR8 *ToolInputFile;
1596 CHAR8 *ToolOutputFile;
1597 CHAR8 *SystemCommandFormatString;
1598 CHAR8 *SystemCommand;
1599 EFI_GUID *EfiGuid;
1600 UINT16 DataOffset;
1601 UINT16 Attributes;
1602 UINT32 RealHdrLen;
1603 CHAR8 *ToolInputFileName;
1604 CHAR8 *ToolOutputFileName;
1605
1606 ParsedLength = 0;
1607 ToolInputFileName = NULL;
1608 ToolOutputFileName = NULL;
1609
1610 while (ParsedLength < BufferLength) {
1611 Ptr = SectionBuffer + ParsedLength;
1612
1613 SectionLength = GetLength (((EFI_COMMON_SECTION_HEADER *) Ptr)->Size);
1614 Type = ((EFI_COMMON_SECTION_HEADER *) Ptr)->Type;
1615
1616 //
1617 // This is sort of an odd check, but is necessary because FFS files are
1618 // padded to a QWORD boundary, meaning there is potentially a whole section
1619 // header worth of 0xFF bytes.
1620 //
1621 if (SectionLength == 0xffffff && Type == 0xff) {
1622 ParsedLength += 4;
1623 continue;
1624 }
1625
1626 //
1627 // Get real section file size
1628 //
1629 SectionLength = GetSectionFileLength ((EFI_COMMON_SECTION_HEADER *) Ptr);
1630 SectionHeaderLen = GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
1631
1632 SectionName = SectionNameToStr (Type);
1633 printf ("------------------------------------------------------------\n");
1634 printf (" Type: %s\n Size: 0x%08X\n", SectionName, (unsigned) SectionLength);
1635 free (SectionName);
1636
1637 switch (Type) {
1638 case EFI_SECTION_RAW:
1639 case EFI_SECTION_PIC:
1640 case EFI_SECTION_TE:
1641 // default is no more information
1642 break;
1643
1644 case EFI_SECTION_PE32:
1645 if (EnableHash) {
1646 ToolInputFileName = "edk2Temp_InputEfi.tmp";
1647 ToolOutputFileName = "edk2Temp_OutputHash.tmp";
1648 RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);
1649 PutFileImage (
1650 ToolInputFileName,
1651 (CHAR8*)Ptr + SectionHeaderLen,
1652 SectionLength - SectionHeaderLen
1653 );
1654
1655 SystemCommandFormatString = "%s sha1 -out %s %s";
1656 SystemCommand = malloc (
1657 strlen (SystemCommandFormatString) +
1658 strlen (OpenSslPath) +
1659 strlen (ToolInputFileName) +
1660 strlen (ToolOutputFileName) +
1661 1
1662 );
1663 sprintf (
1664 SystemCommand,
1665 SystemCommandFormatString,
1666 OpenSslPath,
1667 ToolOutputFileName,
1668 ToolInputFileName
1669 );
1670
1671 if (system (SystemCommand) != EFI_SUCCESS) {
1672 Error (NULL, 0, 3000, "Open SSL command not available. Please verify PATH or set OPENSSL_PATH.", NULL);
1673 }
1674 else {
1675 FILE *fp;
1676 CHAR8 *StrLine;
1677 CHAR8 *NewStr;
1678 UINT32 nFileLen;
1679 if((fp = fopen(ToolOutputFileName,"r")) == NULL) {
1680 Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);
1681 }
1682 else {
1683 fseek(fp,0,SEEK_SET);
1684 fseek(fp,0,SEEK_END);
1685 nFileLen = ftell(fp);
1686 fseek(fp,0,SEEK_SET);
1687 StrLine = malloc(nFileLen);
1688 fgets(StrLine, nFileLen, fp);
1689 NewStr = strrchr (StrLine, '=');
1690 printf (" SHA1: %s\n", NewStr + 1);
1691 free (StrLine);
1692 }
1693 fclose(fp);
1694 }
1695 remove(ToolInputFileName);
1696 remove(ToolOutputFileName);
1697 free (SystemCommand);
1698 }
1699 break;
1700
1701 case EFI_SECTION_USER_INTERFACE:
1702 printf (" String: %ls\n", (CHAR16 *) &((EFI_USER_INTERFACE_SECTION *) Ptr)->FileNameString);
1703 break;
1704
1705 case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
1706 Status = PrintFvInfo (Ptr + SectionHeaderLen, TRUE);
1707 if (EFI_ERROR (Status)) {
1708 Error (NULL, 0, 0003, "printing of FV section contents failed", NULL);
1709 return EFI_SECTION_ERROR;
1710 }
1711 break;
1712
1713 case EFI_SECTION_COMPATIBILITY16:
1714 case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
1715 //
1716 // Section does not contain any further header information.
1717 //
1718 break;
1719
1720 case EFI_SECTION_PEI_DEPEX:
1721 case EFI_SECTION_DXE_DEPEX:
1722 case EFI_SECTION_SMM_DEPEX:
1723 DumpDepexSection (Ptr, SectionLength);
1724 break;
1725
1726 case EFI_SECTION_VERSION:
1727 printf (" Build Number: 0x%02X\n", *(UINT16 *)(Ptr + SectionHeaderLen));
1728 printf (" Version Strg: %s\n", (char*) (Ptr + SectionHeaderLen + sizeof (UINT16)));
1729 break;
1730
1731 case EFI_SECTION_COMPRESSION:
1732 UncompressedBuffer = NULL;
1733 if (SectionHeaderLen == sizeof (EFI_COMMON_SECTION_HEADER)) {
1734 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION);
1735 UncompressedLength = ((EFI_COMPRESSION_SECTION *)Ptr)->UncompressedLength;
1736 CompressionType = ((EFI_COMPRESSION_SECTION *)Ptr)->CompressionType;
1737 } else {
1738 RealHdrLen = sizeof(EFI_COMPRESSION_SECTION2);
1739 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *)Ptr)->UncompressedLength;
1740 CompressionType = ((EFI_COMPRESSION_SECTION2 *)Ptr)->CompressionType;
1741 }
1742 CompressedLength = SectionLength - RealHdrLen;
1743 printf (" Uncompressed Length: 0x%08X\n", (unsigned) UncompressedLength);
1744
1745 if (CompressionType == EFI_NOT_COMPRESSED) {
1746 printf (" Compression Type: EFI_NOT_COMPRESSED\n");
1747 if (CompressedLength != UncompressedLength) {
1748 Error (
1749 NULL,
1750 0,
1751 0,
1752 "file is not compressed, but the compressed length does not match the uncompressed length",
1753 NULL
1754 );
1755 return EFI_SECTION_ERROR;
1756 }
1757
1758 UncompressedBuffer = Ptr + RealHdrLen;
1759 } else if (CompressionType == EFI_STANDARD_COMPRESSION) {
1760 GetInfoFunction = EfiGetInfo;
1761 DecompressFunction = EfiDecompress;
1762 printf (" Compression Type: EFI_STANDARD_COMPRESSION\n");
1763
1764 CompressedBuffer = Ptr + RealHdrLen;
1765
1766 Status = GetInfoFunction (CompressedBuffer, CompressedLength, &DstSize, &ScratchSize);
1767 if (EFI_ERROR (Status)) {
1768 Error (NULL, 0, 0003, "error getting compression info from compression section", NULL);
1769 return EFI_SECTION_ERROR;
1770 }
1771
1772 if (DstSize != UncompressedLength) {
1773 Error (NULL, 0, 0003, "compression error in the compression section", NULL);
1774 return EFI_SECTION_ERROR;
1775 }
1776
1777 ScratchBuffer = malloc (ScratchSize);
1778 UncompressedBuffer = malloc (UncompressedLength);
1779 if ((ScratchBuffer == NULL) || (UncompressedBuffer == NULL)) {
1780 return EFI_OUT_OF_RESOURCES;
1781 }
1782 Status = DecompressFunction (
1783 CompressedBuffer,
1784 CompressedLength,
1785 UncompressedBuffer,
1786 UncompressedLength,
1787 ScratchBuffer,
1788 ScratchSize
1789 );
1790 free (ScratchBuffer);
1791 if (EFI_ERROR (Status)) {
1792 Error (NULL, 0, 0003, "decompress failed", NULL);
1793 free (UncompressedBuffer);
1794 return EFI_SECTION_ERROR;
1795 }
1796 } else {
1797 Error (NULL, 0, 0003, "unrecognized compression type", "type 0x%X", CompressionType);
1798 return EFI_SECTION_ERROR;
1799 }
1800
1801 Status = ParseSection (UncompressedBuffer, UncompressedLength);
1802
1803 if (CompressionType == EFI_STANDARD_COMPRESSION) {
1804 //
1805 // We need to deallocate Buffer
1806 //
1807 free (UncompressedBuffer);
1808 }
1809
1810 if (EFI_ERROR (Status)) {
1811 Error (NULL, 0, 0003, "failed to parse section", NULL);
1812 return EFI_SECTION_ERROR;
1813 }
1814 break;
1815
1816 case EFI_SECTION_GUID_DEFINED:
1817 if (SectionHeaderLen == sizeof(EFI_COMMON_SECTION_HEADER)) {
1818 EfiGuid = &((EFI_GUID_DEFINED_SECTION *) Ptr)->SectionDefinitionGuid;
1819 DataOffset = ((EFI_GUID_DEFINED_SECTION *) Ptr)->DataOffset;
1820 Attributes = ((EFI_GUID_DEFINED_SECTION *) Ptr)->Attributes;
1821 } else {
1822 EfiGuid = &((EFI_GUID_DEFINED_SECTION2 *) Ptr)->SectionDefinitionGuid;
1823 DataOffset = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->DataOffset;
1824 Attributes = ((EFI_GUID_DEFINED_SECTION2 *) Ptr)->Attributes;
1825 }
1826 printf (" SectionDefinitionGuid: ");
1827 PrintGuid (EfiGuid);
1828 printf ("\n");
1829 printf (" DataOffset: 0x%04X\n", (unsigned) DataOffset);
1830 printf (" Attributes: 0x%04X\n", (unsigned) Attributes);
1831
1832 ExtractionTool =
1833 LookupGuidedSectionToolPath (
1834 mParsedGuidedSectionTools,
1835 EfiGuid
1836 );
1837
1838 if (ExtractionTool != NULL) {
1839 #ifndef __GNUC__
1840 ToolInputFile = CloneString (tmpnam (NULL));
1841 ToolOutputFile = CloneString (tmpnam (NULL));
1842 #else
1843 char tmp1[] = "/tmp/fileXXXXXX";
1844 char tmp2[] = "/tmp/fileXXXXXX";
1845 int fd1;
1846 int fd2;
1847 fd1 = mkstemp(tmp1);
1848 fd2 = mkstemp(tmp2);
1849 ToolInputFile = CloneString(tmp1);
1850 ToolOutputFile = CloneString(tmp2);
1851 close(fd1);
1852 close(fd2);
1853 #endif
1854
1855 //
1856 // Construction 'system' command string
1857 //
1858 SystemCommandFormatString = "%s -d -o %s %s";
1859 SystemCommand = malloc (
1860 strlen (SystemCommandFormatString) +
1861 strlen (ExtractionTool) +
1862 strlen (ToolInputFile) +
1863 strlen (ToolOutputFile) +
1864 1
1865 );
1866 sprintf (
1867 SystemCommand,
1868 SystemCommandFormatString,
1869 ExtractionTool,
1870 ToolOutputFile,
1871 ToolInputFile
1872 );
1873 free (ExtractionTool);
1874
1875 Status =
1876 PutFileImage (
1877 ToolInputFile,
1878 (CHAR8*) SectionBuffer + DataOffset,
1879 BufferLength - DataOffset
1880 );
1881
1882 system (SystemCommand);
1883 remove (ToolInputFile);
1884 free (ToolInputFile);
1885
1886 Status =
1887 GetFileImage (
1888 ToolOutputFile,
1889 (CHAR8 **)&ToolOutputBuffer,
1890 &ToolOutputLength
1891 );
1892 remove (ToolOutputFile);
1893 free (ToolOutputFile);
1894 if (EFI_ERROR (Status)) {
1895 Error (NULL, 0, 0004, "unable to read decoded GUIDED section", NULL);
1896 return EFI_SECTION_ERROR;
1897 }
1898
1899 Status = ParseSection (
1900 ToolOutputBuffer,
1901 ToolOutputLength
1902 );
1903 if (EFI_ERROR (Status)) {
1904 Error (NULL, 0, 0003, "parse of decoded GUIDED section failed", NULL);
1905 return EFI_SECTION_ERROR;
1906 }
1907
1908 //
1909 // Check for CRC32 sections which we can handle internally if needed.
1910 //
1911 } else if (!CompareGuid (
1912 EfiGuid,
1913 &gEfiCrc32GuidedSectionExtractionProtocolGuid
1914 )
1915 ) {
1916 //
1917 // CRC32 guided section
1918 //
1919 Status = ParseSection (
1920 SectionBuffer + DataOffset,
1921 BufferLength - DataOffset
1922 );
1923 if (EFI_ERROR (Status)) {
1924 Error (NULL, 0, 0003, "parse of CRC32 GUIDED section failed", NULL);
1925 return EFI_SECTION_ERROR;
1926 }
1927 } else {
1928 //
1929 // We don't know how to parse it now.
1930 //
1931 Error (NULL, 0, 0003, "Error parsing section", \
1932 "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).");
1933 return EFI_UNSUPPORTED;
1934 }
1935 break;
1936
1937 default:
1938 //
1939 // Unknown section, return error
1940 //
1941 Error (NULL, 0, 0003, "unrecognized section type found", "section type = 0x%X", Type);
1942 return EFI_SECTION_ERROR;
1943 }
1944
1945 ParsedLength += SectionLength;
1946 //
1947 // We make then next section begin on a 4-byte boundary
1948 //
1949 ParsedLength = GetOccupiedSize (ParsedLength, 4);
1950 }
1951
1952 if (ParsedLength < BufferLength) {
1953 Error (NULL, 0, 0003, "sections do not completely fill the sectioned buffer being parsed", NULL);
1954 return EFI_SECTION_ERROR;
1955 }
1956
1957 return EFI_SUCCESS;
1958 }
1959
1960 EFI_STATUS
1961 DumpDepexSection (
1962 IN UINT8 *Ptr,
1963 IN UINT32 SectionLength
1964 )
1965 /*++
1966
1967 Routine Description:
1968
1969 GC_TODO: Add function description
1970
1971 Arguments:
1972
1973 Ptr - GC_TODO: add argument description
1974 SectionLength - GC_TODO: add argument description
1975
1976 Returns:
1977
1978 EFI_SUCCESS - GC_TODO: Add description for return value
1979
1980 --*/
1981 {
1982 UINT8 GuidBuffer[PRINTED_GUID_BUFFER_SIZE];
1983
1984 //
1985 // Need at least a section header + data
1986 //
1987 if (SectionLength <= sizeof (EFI_COMMON_SECTION_HEADER)) {
1988 return EFI_SUCCESS;
1989 }
1990
1991 Ptr += GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
1992 SectionLength -= GetSectionHeaderLength((EFI_COMMON_SECTION_HEADER *)Ptr);
1993 while (SectionLength > 0) {
1994 printf (" ");
1995 switch (*Ptr) {
1996 case EFI_DEP_BEFORE:
1997 printf ("BEFORE\n");
1998 Ptr++;
1999 SectionLength--;
2000 break;
2001
2002 case EFI_DEP_AFTER:
2003 printf ("AFTER\n");
2004 Ptr++;
2005 SectionLength--;
2006 break;
2007
2008 case EFI_DEP_PUSH:
2009 printf ("PUSH\n ");
2010 PrintGuidToBuffer ((EFI_GUID *) (Ptr + 1), GuidBuffer, sizeof (GuidBuffer), TRUE);
2011 printf ("%s ", GuidBuffer);
2012 PrintGuidName (GuidBuffer);
2013 printf ("\n");
2014 //
2015 // PrintGuid ((EFI_GUID *)(Ptr + 1));
2016 //
2017 Ptr += 17;
2018 SectionLength -= 17;
2019 break;
2020
2021 case EFI_DEP_AND:
2022 printf ("AND\n");
2023 Ptr++;
2024 SectionLength--;
2025 break;
2026
2027 case EFI_DEP_OR:
2028 printf ("OR\n");
2029 Ptr++;
2030 SectionLength--;
2031 break;
2032
2033 case EFI_DEP_NOT:
2034 printf ("NOT\n");
2035 Ptr++;
2036 SectionLength--;
2037 break;
2038
2039 case EFI_DEP_TRUE:
2040 printf ("TRUE\n");
2041 Ptr++;
2042 SectionLength--;
2043 break;
2044
2045 case EFI_DEP_FALSE:
2046 printf ("FALSE\n");
2047 Ptr++;
2048 SectionLength--;
2049 break;
2050
2051 case EFI_DEP_END:
2052 printf ("END DEPEX\n");
2053 Ptr++;
2054 SectionLength--;
2055 break;
2056
2057 case EFI_DEP_SOR:
2058 printf ("SOR\n");
2059 Ptr++;
2060 SectionLength--;
2061 break;
2062
2063 default:
2064 printf ("Unrecognized byte in depex: 0x%X\n", *Ptr);
2065 return EFI_SUCCESS;
2066 }
2067 }
2068
2069 return EFI_SUCCESS;
2070 }
2071
2072 EFI_STATUS
2073 PrintGuidName (
2074 IN UINT8 *GuidStr
2075 )
2076 /*++
2077
2078 Routine Description:
2079
2080 GC_TODO: Add function description
2081
2082 Arguments:
2083
2084 GuidStr - GC_TODO: add argument description
2085
2086 Returns:
2087
2088 EFI_SUCCESS - GC_TODO: Add description for return value
2089 EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
2090
2091 --*/
2092 {
2093 GUID_TO_BASENAME *GPtr;
2094 //
2095 // If we have a list of guid-to-basenames, then go through the list to
2096 // look for a guid string match. If found, print the basename to stdout,
2097 // otherwise return a failure.
2098 //
2099 GPtr = mGuidBaseNameList;
2100 while (GPtr != NULL) {
2101 if (_stricmp ((CHAR8*) GuidStr, (CHAR8*) GPtr->Guid) == 0) {
2102 printf ("%s", GPtr->BaseName);
2103 return EFI_SUCCESS;
2104 }
2105
2106 GPtr = GPtr->Next;
2107 }
2108
2109 return EFI_INVALID_PARAMETER;
2110 }
2111
2112 EFI_STATUS
2113 ParseGuidBaseNameFile (
2114 CHAR8 *FileName
2115 )
2116 /*++
2117
2118 Routine Description:
2119
2120 GC_TODO: Add function description
2121
2122 Arguments:
2123
2124 FileName - GC_TODO: add argument description
2125
2126 Returns:
2127
2128 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
2129 EFI_OUT_OF_RESOURCES - GC_TODO: Add description for return value
2130 EFI_SUCCESS - GC_TODO: Add description for return value
2131
2132 --*/
2133 {
2134 FILE *Fptr;
2135 CHAR8 Line[MAX_LINE_LEN];
2136 GUID_TO_BASENAME *GPtr;
2137
2138 if ((Fptr = fopen (LongFilePath (FileName), "r")) == NULL) {
2139 printf ("ERROR: Failed to open input cross-reference file '%s'\n", FileName);
2140 return EFI_DEVICE_ERROR;
2141 }
2142
2143 while (fgets (Line, sizeof (Line), Fptr) != NULL) {
2144 //
2145 // Allocate space for another guid/basename element
2146 //
2147 GPtr = malloc (sizeof (GUID_TO_BASENAME));
2148 if (GPtr == NULL) {
2149 return EFI_OUT_OF_RESOURCES;
2150 }
2151
2152 memset ((char *) GPtr, 0, sizeof (GUID_TO_BASENAME));
2153 if (sscanf (Line, "%s %s", GPtr->Guid, GPtr->BaseName) == 2) {
2154 GPtr->Next = mGuidBaseNameList;
2155 mGuidBaseNameList = GPtr;
2156 } else {
2157 //
2158 // Some sort of error. Just continue.
2159 //
2160 free (GPtr);
2161 }
2162 }
2163
2164 fclose (Fptr);
2165 return EFI_SUCCESS;
2166 }
2167
2168 EFI_STATUS
2169 FreeGuidBaseNameList (
2170 VOID
2171 )
2172 /*++
2173
2174 Routine Description:
2175
2176 GC_TODO: Add function description
2177
2178 Arguments:
2179
2180 None
2181
2182 Returns:
2183
2184 EFI_SUCCESS - GC_TODO: Add description for return value
2185
2186 --*/
2187 {
2188 GUID_TO_BASENAME *Next;
2189
2190 while (mGuidBaseNameList != NULL) {
2191 Next = mGuidBaseNameList->Next;
2192 free (mGuidBaseNameList);
2193 mGuidBaseNameList = Next;
2194 }
2195
2196 return EFI_SUCCESS;
2197 }
2198
2199
2200 static
2201 VOID
2202 LoadGuidedSectionToolsTxt (
2203 IN CHAR8* FirmwareVolumeFilename
2204 )
2205 {
2206 CHAR8* PeerFilename;
2207 CHAR8* Places[] = {
2208 NULL,
2209 //NULL,
2210 };
2211 UINTN Index;
2212
2213 Places[0] = FirmwareVolumeFilename;
2214 //Places[1] = mUtilityFilename;
2215
2216 mParsedGuidedSectionTools = NULL;
2217
2218 for (Index = 0; Index < (sizeof(Places)/sizeof(Places[0])); Index++) {
2219 PeerFilename = OsPathPeerFilePath (Places[Index], "GuidedSectionTools.txt");
2220 //printf("Loading %s...\n", PeerFilename);
2221 if (OsPathExists (PeerFilename)) {
2222 mParsedGuidedSectionTools = ParseGuidedSectionToolsFile (PeerFilename);
2223 }
2224 free (PeerFilename);
2225 if (mParsedGuidedSectionTools != NULL) {
2226 return;
2227 }
2228 }
2229 }
2230
2231
2232 void
2233 Usage (
2234 VOID
2235 )
2236 /*++
2237
2238 Routine Description:
2239
2240 GC_TODO: Add function description
2241
2242 Arguments:
2243
2244 None
2245
2246 Returns:
2247
2248 GC_TODO: add return values
2249
2250 --*/
2251 {
2252 //
2253 // Summary usage
2254 //
2255 fprintf (stdout, "Usage: %s [options] <input_file>\n\n", UTILITY_NAME);
2256
2257 //
2258 // Copyright declaration
2259 //
2260 fprintf (stdout, "Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.\n\n");
2261 fprintf (stdout, " Display Tiano Firmware Volume FFS image information\n\n");
2262
2263 //
2264 // Details Option
2265 //
2266 fprintf (stdout, "optional arguments:\n");
2267 fprintf (stdout, " -h, --help\n\
2268 Show this help message and exit\n");
2269 fprintf (stdout, " --version\n\
2270 Show program's version number and exit\n");
2271 fprintf (stdout, " -d [DEBUG], --debug [DEBUG]\n\
2272 Output DEBUG statements, where DEBUG_LEVEL is 0 (min) - 9 (max)\n");
2273 fprintf (stdout, " -v, --verbose\n\
2274 Print informational statements\n");
2275 fprintf (stdout, " -q, --quiet\n\
2276 Returns the exit code, error messages will be displayed\n");
2277 fprintf (stdout, " -s, --silent\n\
2278 Returns only the exit code; informational and error\n\
2279 messages are not displayed\n");
2280 fprintf (stdout, " -x XREF_FILENAME, --xref XREF_FILENAME\n\
2281 Parse the basename to file-guid cross reference file(s)\n");
2282 fprintf (stdout, " -f OFFSET, --offset OFFSET\n\
2283 The offset from the start of the input file to start \n\
2284 processing an FV\n");
2285 fprintf (stdout, " --hash\n\
2286 Generate HASH value of the entire PE image\n");
2287 fprintf (stdout, " --sfo\n\
2288 Reserved for future use\n");
2289 }
2290