3 Copyright (c) 1999-2006 Intel Corporation. All rights reserved
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 This contains all code necessary to build the PeiRebase.exe utility.
20 This utility relies heavily on the PeiRebase DLL. Definitions for both
21 can be found in the PEI Rebase Utility Specification, review draft.
29 #include <Common/UefiBaseTypes.h>
30 #include <Common/FirmwareVolumeImageFormat.h>
31 #include <Common/FirmwareFileSystem.h>
32 #include <Library/PeCoffLib.h>
34 #include "CommonLib.h"
37 #include "EfiUtilityMsgs.h"
38 #include "PeiRebaseExe.h"
44 OUT BOOLEAN
*ErasePolarity
56 This utility relocates PEI XIP PE32s in a FV.
60 argc - Number of command line arguments
62 BaseAddress The base address to use for rebasing the FV. The correct
63 format is a hex number preceded by 0x.
64 InputFileName The name of the input FV file.
65 OutputFileName The name of the output FV file.
67 Arguments come in pair in any order.
74 0 No error conditions detected.
75 1 One or more of the input parameters is invalid.
76 2 A resource required by the utility was unavailable.
77 Most commonly this will be memory allocation or file creation.
78 3 PeiRebase.dll could not be loaded.
79 4 Error executing the PEI rebase.
84 CHAR8 InputFileName
[_MAX_PATH
];
85 CHAR8
*OutputFileName
;
86 EFI_PHYSICAL_ADDRESS XipBase
, BsBase
, RtBase
;
95 EFI_FIRMWARE_VOLUME_HEADER
*FvImage
;
97 EFI_FFS_FILE_HEADER
*CurrentFile
;
98 BOOLEAN ErasePolarity
;
99 MEMORY_FILE InfMemoryFile
;
100 CHAR8 StringBuffer
[0x100];
102 ErasePolarity
= FALSE
;
104 // Set utility name for error/warning reporting purposes.
106 SetUtilityName (UTILITY_NAME
);
113 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0) ||
114 (strcmp(argv
[1], "-?") == 0) || (strcmp(argv
[1], "/?") == 0)) {
119 if ((strcmp(argv
[1], "-V") == 0) || (strcmp(argv
[1], "--version") == 0)) {
125 // Verify the correct number of arguments
127 if (argc
!= MAX_ARGS
) {
133 // Initialize variables
135 InputFileName
[0] = '\0';
136 OutputFileName
= NULL
;
137 XipBase
= BsBase
= RtBase
= 0;
141 ErasePolarity
= FALSE
;
148 // Parse the command line arguments
150 for (Index
= 1; Index
< MAX_ARGS
; Index
+= 2) {
152 // Make sure argument pair begin with - or /
154 if (argv
[Index
][0] != '-' && argv
[Index
][0] != '/') {
156 Error (NULL
, 0, 0, argv
[Index
], "unrecognized option");
160 // Make sure argument specifier is only one letter
162 if (argv
[Index
][2] != 0) {
164 Error (NULL
, 0, 0, argv
[Index
], "unrecognized option");
168 // Determine argument to read
170 switch (argv
[Index
][1]) {
173 if (strlen (InputFileName
) == 0) {
174 strcpy (InputFileName
, argv
[Index
+ 1]);
177 Error (NULL
, 0, 0, argv
[Index
+ 1], "only one -i InputFileName may be specified");
184 if (OutputFileName
== NULL
) {
185 OutputFileName
= argv
[Index
+ 1];
188 Error (NULL
, 0, 0, argv
[Index
+ 1], "only one -o OutputFileName may be specified");
196 // Load INF file into memory & initialize MEMORY_FILE structure
198 Status
= GetFileImage (argv
[Index
+ 1], &InfMemoryFile
.FileImage
, (UINT32
*)&InfMemoryFile
.Eof
);
199 InfMemoryFile
.Eof
= InfMemoryFile
.FileImage
+ (UINT32
)(UINTN
)InfMemoryFile
.Eof
;
200 InfMemoryFile
.CurrentFilePointer
= InfMemoryFile
.FileImage
;
201 if (EFI_ERROR (Status
)) {
202 Error (NULL
, 0, 0, argv
[Index
+ 1], "Error opening FvInfFile");
207 // Read BaseAddress from fv.inf file
209 FindToken (&InfMemoryFile
, "[options]", "EFI_BASE_ADDRESS", 0, StringBuffer
);
212 // Free INF file image
214 free (InfMemoryFile
.FileImage
);
217 // Point argv[Index + 1] to StringBuffer so that it could be processed as "-b"
219 argv
[Index
+ 1] = StringBuffer
;
225 Error (NULL
, 0, 0, argv
[Index
+ 1], "XipBaseAddress may be specified only once by either -b or -f");
229 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &XipBase
);
230 if (EFI_ERROR (Status
)) {
232 Error (NULL
, 0, 0, argv
[Index
+ 1], "invalid hex digit given for XIP base address");
243 Error (NULL
, 0, 0, argv
[Index
+ 1], "-d BsBaseAddress may be specified only once");
247 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &BsBase
);
248 if (EFI_ERROR (Status
)) {
250 Error (NULL
, 0, 0, argv
[Index
+ 1], "invalid hex digit given for BS_DRIVER base address");
261 Error (NULL
, 0, 0, argv
[Index
+ 1], "-r RtBaseAddress may be specified only once");
265 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &RtBase
);
266 if (EFI_ERROR (Status
)) {
268 Error (NULL
, 0, 0, argv
[Index
+ 1], "invalid hex digit given for RT_DRIVER base address");
277 Error (NULL
, 0, 0, argv
[Index
], "unrecognized argument");
284 // Open the file containing the FV
286 InputFile
= fopen (InputFileName
, "rb");
287 if (InputFile
== NULL
) {
288 Error (NULL
, 0, 0, InputFileName
, "could not open input file for reading");
295 strcat (InputFileName
, ".log");
296 LogFile
= fopen (InputFileName
, "a");
297 if (LogFile
== NULL
) {
298 Error (NULL
, 0, 0, InputFileName
, "could not append to log file");
302 // Determine size of FV
304 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
305 if (EFI_ERROR (Status
)) {
306 Error (NULL
, 0, 0, "could not parse the FV header", NULL
);
310 // Allocate a buffer for the FV image
312 FvImage
= malloc (FvSize
);
313 if (FvImage
== NULL
) {
314 Error (NULL
, 0, 0, "application error", "memory allocation failed");
318 // Read the entire FV to the buffer
320 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
323 if ((unsigned int) BytesRead
!= FvSize
) {
324 Error (NULL
, 0, 0, InputFileName
, "failed to read from file");
328 // Prepare to walk the FV image
330 InitializeFvLib (FvImage
, FvSize
);
332 // Get the first file
334 Status
= GetNextFile (NULL
, &CurrentFile
);
335 if (EFI_ERROR (Status
)) {
336 Error (NULL
, 0, 0, "cannot find the first file in the FV image", NULL
);
340 // Check if each file should be rebased
342 while (CurrentFile
!= NULL
) {
349 XipBase
+ (UINTN
)CurrentFile
- (UINTN
)FvImage
,
355 if (EFI_ERROR (Status
)) {
358 case EFI_INVALID_PARAMETER
:
359 Error (NULL
, 0, 0, "invalid parameter passed to FfsRebase", NULL
);
363 Error (NULL
, 0, 0, "error detected while rebasing -- aborted", NULL
);
366 case EFI_OUT_OF_RESOURCES
:
367 Error (NULL
, 0, 0, "FfsRebase could not allocate required resources", NULL
);
371 Error (NULL
, 0, 0, "FfsRebase could not locate a PE32 section", NULL
);
375 Error (NULL
, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status
);
384 Status
= GetNextFile (CurrentFile
, &CurrentFile
);
385 if (EFI_ERROR (Status
)) {
386 Error (NULL
, 0, 0, "cannot find the next file in the FV image", NULL
);
391 // Open the output file
393 OutputFile
= fopen (OutputFileName
, "wb");
394 if (OutputFile
== NULL
) {
395 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file");
399 if (fwrite (FvImage
, 1, FvSize
, OutputFile
) != FvSize
) {
400 Error (NULL
, 0, 0, "failed to write to output file", 0);
405 if (InputFile
!= NULL
) {
409 // If we created an output file, and there was an error, remove it so
410 // subsequent builds will rebuild it.
412 if (OutputFile
!= NULL
) {
413 if (GetUtilityStatus () == STATUS_ERROR
) {
414 remove (OutputFileName
);
420 if (LogFile
!= NULL
) {
424 if (FvImage
!= NULL
) {
428 return GetUtilityStatus ();
435 OUT BOOLEAN
*ErasePolarity
441 This function determines the size of the FV and the erase polarity. The
442 erase polarity is the FALSE value for file state.
446 InputFile The file that contains the FV image.
447 FvSize The size of the FV.
448 ErasePolarity The FV erase polarity.
452 EFI_SUCCESS Function completed successfully.
453 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
454 EFI_ABORTED The function encountered an error.
458 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
459 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
467 // Check input parameters
469 if ((InputFile
== NULL
) || (FvSize
== NULL
) || (ErasePolarity
== NULL
)) {
470 Error (NULL
, 0, 0, "ReadHeader()", "invalid input parameter");
471 return EFI_INVALID_PARAMETER
;
476 fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
477 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
478 Signature
[0] = VolumeHeader
.Signature
;
482 // Get erase polarity
484 if (VolumeHeader
.Attributes
& EFI_FVB_ERASE_POLARITY
) {
485 *ErasePolarity
= TRUE
;
489 fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
490 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
492 if (BlockMap
.NumBlocks
!= 0) {
493 Size
+= BlockMap
.NumBlocks
* BlockMap
.BlockLength
;
496 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.BlockLength
== 0));
498 if (VolumeHeader
.FvLength
!= Size
) {
499 Error (NULL
, 0, 0, "volume size not consistant with block maps", NULL
);
518 Displays the standard utility information to SDTOUT
530 printf ("%s v%d.%d -PEI Rebase Utility.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
);
531 printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");
542 Displays the utility usage syntax to STDOUT
557 "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-F InputFvInfName]\n",
560 printf (" [-D BootDriverBaseAddress] [-R RuntimeDriverBaseAddress]\n");
561 printf (" Where:\n");
562 printf (" InputFileName is the name of the EFI FV file to rebase.\n");
563 printf (" OutputFileName is the desired output file name.\n");
564 printf (" BaseAddress is the rebase address for all drivers run in Flash.\n");
565 printf (" InputFvInfName is the Fv.inf file that contains this FV base address to rebase against.\n");
566 printf (" BootDriverBaseAddress is the rebase address for all boot drivers in this fv image.\n");
567 printf (" RuntimeDriverBaseAddress is the rebase address for all runtime drivers in this fv image.\n");
568 printf (" Argument pair may be in any order.\n\n");
573 IN OUT EFI_FFS_FILE_HEADER
*FfsFile
,
575 IN OUT EFI_PHYSICAL_ADDRESS XipBase
,
576 IN OUT EFI_PHYSICAL_ADDRESS
*BsBase
,
577 IN OUT EFI_PHYSICAL_ADDRESS
*RtBase
,
584 This function determines if a file is XIP and should be rebased. It will
585 rebase any PE32 sections found in the file using the base address.
589 FfsFile A pointer to Ffs file image.
590 BaseAddress The base address to use for rebasing the file image.
594 EFI_SUCCESS The image was properly rebased.
595 EFI_INVALID_PARAMETER An input parameter is invalid.
596 EFI_ABORTED An error occurred while rebasing the input file image.
597 EFI_OUT_OF_RESOURCES Could not allocate a required resource.
598 EFI_NOT_FOUND No compressed sections could be found.
603 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
604 EFI_PHYSICAL_ADDRESS NewPe32BaseAddress
;
606 EFI_FILE_SECTION_POINTER CurrentPe32Section
;
607 EFI_FFS_FILE_STATE SavedState
;
608 EFI_IMAGE_NT_HEADERS32
*PeHdr
;
609 EFI_TE_IMAGE_HEADER
*TEImageHeader
;
610 UINT8 FileGuidString
[80];
612 EFI_FFS_FILE_TAIL TailValue
;
613 EFI_PHYSICAL_ADDRESS
*BaseToUpdate
;
614 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*DebugEntry
;
618 // Verify input parameters
620 if (FfsFile
== NULL
) {
621 return EFI_INVALID_PARAMETER
;
624 // Convert the GUID to a string so we can at least report which file
625 // if we find an error.
627 PrintGuidToBuffer (&FfsFile
->Name
, FileGuidString
, sizeof (FileGuidString
), TRUE
);
628 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
629 TailSize
= sizeof (EFI_FFS_FILE_TAIL
);
634 // Do some cursory checks on the FFS file contents
636 Status
= VerifyFfsFile (FfsFile
);
637 if (EFI_ERROR (Status
)) {
638 Error (NULL
, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString
);
639 return EFI_INVALID_PARAMETER
;
643 // We only process files potentially containing PE32 sections.
645 switch (FfsFile
->Type
) {
646 case EFI_FV_FILETYPE_SECURITY_CORE
:
647 case EFI_FV_FILETYPE_PEI_CORE
:
648 case EFI_FV_FILETYPE_PEIM
:
649 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
650 case EFI_FV_FILETYPE_DRIVER
:
651 case EFI_FV_FILETYPE_DXE_CORE
:
658 // Rebase each PE32 section
660 Status
= EFI_SUCCESS
;
661 for (Index
= 1;; Index
++) {
662 Status
= GetSectionByType (FfsFile
, EFI_SECTION_PE32
, Index
, &CurrentPe32Section
);
663 if (EFI_ERROR (Status
)) {
668 // Initialize context
670 memset (&ImageContext
, 0, sizeof (ImageContext
));
671 ImageContext
.Handle
= (VOID
*) ((UINTN
) CurrentPe32Section
.Pe32Section
+ sizeof (EFI_PE32_SECTION
));
672 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) FfsRebaseImageRead
;
673 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
674 if (EFI_ERROR (Status
)) {
675 Error (NULL
, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString
);
680 // Don't Load PeImage, only to relocate current image.
682 ImageContext
.ImageAddress
= (UINTN
) CurrentPe32Section
.Pe32Section
+ sizeof (EFI_PE32_SECTION
);
685 // Check if section-alignment and file-alignment match or not
687 PeHdr
= (EFI_IMAGE_NT_HEADERS
*)((UINTN
)ImageContext
.ImageAddress
+ ImageContext
.PeCoffHeaderOffset
);
688 if (PeHdr
->OptionalHeader
.SectionAlignment
!= PeHdr
->OptionalHeader
.FileAlignment
) {
690 // Nor XIP module can be ignored.
692 if ((Flags
& 1) == 0) {
695 Error (NULL
, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString
);
700 // Update CodeView and PdbPointer in ImageContext
702 DebugEntry
= (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*)(UINTN
)(
703 ImageContext
.ImageAddress
+
704 ImageContext
.DebugDirectoryEntryRva
706 ImageContext
.CodeView
= (VOID
*)(UINTN
)(
707 ImageContext
.ImageAddress
+
710 switch (*(UINT32
*) ImageContext
.CodeView
) {
711 case CODEVIEW_SIGNATURE_NB10
:
712 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
);
715 case CODEVIEW_SIGNATURE_RSDS
:
716 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY
);
724 // Calculate the PE32 base address, based on file type
726 switch (FfsFile
->Type
) {
727 case EFI_FV_FILETYPE_SECURITY_CORE
:
728 case EFI_FV_FILETYPE_PEI_CORE
:
729 case EFI_FV_FILETYPE_PEIM
:
730 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
731 if ((Flags
& 1) == 0) {
733 // We aren't relocating XIP code, so skip it.
739 XipBase
+ (UINTN
)ImageContext
.ImageAddress
- (UINTN
)FfsFile
;
740 BaseToUpdate
= &XipBase
;
743 case EFI_FV_FILETYPE_DRIVER
:
744 PeHdr
= (EFI_IMAGE_NT_HEADERS32
*)(ImageContext
.ImageAddress
+ ImageContext
.PeCoffHeaderOffset
);
745 switch (PeHdr
->OptionalHeader
.Subsystem
) {
746 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
:
747 if ((Flags
& 4) == 0) {
749 // RT drivers aren't supposed to be relocated
754 NewPe32BaseAddress
= *RtBase
;
755 BaseToUpdate
= RtBase
;
760 // We treat all other subsystems the same as BS_DRIVER
762 if ((Flags
& 2) == 0) {
764 // Skip all BS_DRIVER's
769 NewPe32BaseAddress
= *BsBase
;
770 BaseToUpdate
= BsBase
;
775 case EFI_FV_FILETYPE_DXE_CORE
:
776 if ((Flags
& 2) == 0) {
783 NewPe32BaseAddress
= *BsBase
;
784 BaseToUpdate
= BsBase
;
789 // Not supported file type
794 ImageContext
.DestinationAddress
= NewPe32BaseAddress
;
795 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
796 if (EFI_ERROR (Status
)) {
797 Error (NULL
, 0, 0, "RelocateImage() call failed on rebase", FileGuidString
);
802 // Update BASE address
808 ImageContext
.DestinationAddress
,
809 ImageContext
.PdbPointer
== NULL
? "*" : ImageContext
.PdbPointer
811 *BaseToUpdate
+= EFI_SIZE_TO_PAGES (ImageContext
.ImageSize
) * EFI_PAGE_SIZE
;
814 // Now update file checksum
816 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
817 TailSize
= sizeof (EFI_FFS_FILE_TAIL
);
822 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
823 SavedState
= FfsFile
->State
;
824 FfsFile
->IntegrityCheck
.Checksum
.File
= 0;
826 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
827 FfsFile
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 (
829 GetLength (FfsFile
->Size
) - TailSize
832 FfsFile
->IntegrityCheck
.Checksum
.File
= FFS_FIXED_CHECKSUM
;
835 FfsFile
->State
= SavedState
;
838 // Update tail if present
840 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
841 TailValue
= (EFI_FFS_FILE_TAIL
) (~(FfsFile
->IntegrityCheck
.TailReference
));
842 *(EFI_FFS_FILE_TAIL
*) (((UINTN
) FfsFile
+ GetLength (FfsFile
->Size
) - sizeof (EFI_FFS_FILE_TAIL
))) = TailValue
;
846 if ((Flags
& 1) == 0 || (
847 FfsFile
->Type
!= EFI_FV_FILETYPE_SECURITY_CORE
&&
848 FfsFile
->Type
!= EFI_FV_FILETYPE_PEI_CORE
&&
850 FfsFile
->Type
!= EFI_FV_FILETYPE_PEIM
&&
851 FfsFile
->Type
!= EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
854 // Only XIP code may have a TE section
860 // Now process TE sections
862 for (Index
= 1;; Index
++) {
863 Status
= GetSectionByType (FfsFile
, EFI_SECTION_TE
, Index
, &CurrentPe32Section
);
864 if (EFI_ERROR (Status
)) {
869 // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
872 TEImageHeader
= (EFI_TE_IMAGE_HEADER
*) ((UINT8
*) CurrentPe32Section
.Pe32Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
875 // Initialize context, load image info.
877 memset (&ImageContext
, 0, sizeof (ImageContext
));
878 ImageContext
.Handle
= (VOID
*) TEImageHeader
;
879 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) FfsRebaseImageRead
;
881 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
883 if (EFI_ERROR (Status
)) {
884 Error (NULL
, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString
);
888 // Don't reload TeImage
890 ImageContext
.ImageAddress
= (UINTN
) TEImageHeader
;
893 // Update CodeView and PdbPointer in ImageContext
895 DebugEntry
= (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*)(UINTN
)(
896 ImageContext
.ImageAddress
+
897 ImageContext
.DebugDirectoryEntryRva
+
898 sizeof(EFI_TE_IMAGE_HEADER
) -
899 TEImageHeader
->StrippedSize
902 ImageContext
.CodeView
= (VOID
*)(UINTN
)(
903 ImageContext
.ImageAddress
+
905 sizeof(EFI_TE_IMAGE_HEADER
) -
906 TEImageHeader
->StrippedSize
909 switch (*(UINT32
*) ImageContext
.CodeView
) {
910 case CODEVIEW_SIGNATURE_NB10
:
911 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
);
914 case CODEVIEW_SIGNATURE_RSDS
:
915 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY
);
925 ImageContext
.DestinationAddress
= XipBase
+ (UINTN
) TEImageHeader
+ sizeof (EFI_TE_IMAGE_HEADER
) \
926 - TEImageHeader
->StrippedSize
- (UINTN
) FfsFile
;
927 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
928 if (EFI_ERROR (Status
)) {
929 Error (NULL
, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString
);
933 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
934 TailSize
= sizeof (EFI_FFS_FILE_TAIL
);
939 // Now update file checksum
941 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
942 SavedState
= FfsFile
->State
;
943 FfsFile
->IntegrityCheck
.Checksum
.File
= 0;
945 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
946 FfsFile
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 (
948 GetLength (FfsFile
->Size
) - TailSize
951 FfsFile
->IntegrityCheck
.Checksum
.File
= FFS_FIXED_CHECKSUM
;
954 FfsFile
->State
= SavedState
;
957 // Update tail if present
959 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
960 TailValue
= (EFI_FFS_FILE_TAIL
) (~(FfsFile
->IntegrityCheck
.TailReference
));
961 *(EFI_FFS_FILE_TAIL
*) (((UINTN
) FfsFile
+ GetLength (FfsFile
->Size
) - sizeof (EFI_FFS_FILE_TAIL
))) = TailValue
;
968 ImageContext
.DestinationAddress
,
969 ImageContext
.PdbPointer
== NULL
? "*" : ImageContext
.PdbPointer
980 IN OUT UINT32
*ReadSize
,
987 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
991 FileHandle - The handle to the PE/COFF file
993 FileOffset - The offset, in bytes, into the file to read
995 ReadSize - The number of bytes to read from the file starting at FileOffset
997 Buffer - A pointer to the buffer to read the data into.
1001 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1005 CHAR8
*Destination8
;
1009 Destination8
= Buffer
;
1010 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
1013 *(Destination8
++) = *(Source8
++);