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