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