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