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