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
);
108 if ((strcmp(argv
[1], "-h") == 0) || (strcmp(argv
[1], "--help") == 0) ||
109 (strcmp(argv
[1], "-?") == 0) || (strcmp(argv
[1], "/?") == 0)) {
114 if ((strcmp(argv
[1], "-V") == 0) || (strcmp(argv
[1], "--version") == 0)) {
120 // Verify the correct number of arguments
122 if (argc
< MAX_ARGS
) {
128 // Initialize variables
130 InputFileName
[0] = '\0';
131 OutputFileName
= NULL
;
132 XipBase
= BsBase
= RtBase
= 0;
136 ErasePolarity
= FALSE
;
143 // Parse the command line arguments
145 for (Index
= 1; Index
< argc
; Index
+= 2) {
147 // Make sure argument pair begin with - or /
149 if (argv
[Index
][0] != '-' && argv
[Index
][0] != '/') {
151 Error (NULL
, 0, 0, argv
[Index
], "unrecognized option");
155 // Make sure argument specifier is only one letter
157 if (argv
[Index
][2] != 0) {
159 Error (NULL
, 0, 0, argv
[Index
], "unrecognized option");
163 // Determine argument to read
165 switch (argv
[Index
][1]) {
168 if (strlen (InputFileName
) == 0) {
169 strcpy (InputFileName
, argv
[Index
+ 1]);
172 Error (NULL
, 0, 0, argv
[Index
+ 1], "only one -i InputFileName may be specified");
179 if (OutputFileName
== NULL
) {
180 OutputFileName
= argv
[Index
+ 1];
183 Error (NULL
, 0, 0, argv
[Index
+ 1], "only one -o OutputFileName may be specified");
191 // Load INF file into memory & initialize MEMORY_FILE structure
193 Status
= GetFileImage (argv
[Index
+ 1], &InfMemoryFile
.FileImage
, (UINT32
*)&InfMemoryFile
.Eof
);
194 InfMemoryFile
.Eof
= InfMemoryFile
.FileImage
+ (UINT32
)(UINTN
)InfMemoryFile
.Eof
;
195 InfMemoryFile
.CurrentFilePointer
= InfMemoryFile
.FileImage
;
196 if (EFI_ERROR (Status
)) {
197 Error (NULL
, 0, 0, argv
[Index
+ 1], "Error opening FvInfFile");
202 // Read BaseAddress from fv.inf file
204 FindToken (&InfMemoryFile
, "[options]", "EFI_BASE_ADDRESS", 0, StringBuffer
);
207 // Free INF file image
209 free (InfMemoryFile
.FileImage
);
212 // Point argv[Index + 1] to StringBuffer so that it could be processed as "-b"
214 argv
[Index
+ 1] = StringBuffer
;
220 Error (NULL
, 0, 0, argv
[Index
+ 1], "XipBaseAddress may be specified only once by either -b or -f");
224 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &XipBase
);
225 if (EFI_ERROR (Status
)) {
227 Error (NULL
, 0, 0, argv
[Index
+ 1], "invalid hex digit given for XIP base address");
238 Error (NULL
, 0, 0, argv
[Index
+ 1], "-d BsBaseAddress may be specified only once");
242 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &BsBase
);
243 if (EFI_ERROR (Status
)) {
245 Error (NULL
, 0, 0, argv
[Index
+ 1], "invalid hex digit given for BS_DRIVER base address");
256 Error (NULL
, 0, 0, argv
[Index
+ 1], "-r RtBaseAddress may be specified only once");
260 Status
= AsciiStringToUint64 (argv
[Index
+ 1], FALSE
, &RtBase
);
261 if (EFI_ERROR (Status
)) {
263 Error (NULL
, 0, 0, argv
[Index
+ 1], "invalid hex digit given for RT_DRIVER base address");
272 Error (NULL
, 0, 0, argv
[Index
], "unrecognized argument");
279 // Open the file containing the FV
281 InputFile
= fopen (InputFileName
, "rb");
282 if (InputFile
== NULL
) {
283 Error (NULL
, 0, 0, InputFileName
, "could not open input file for reading");
290 strcat (InputFileName
, ".log");
291 LogFile
= fopen (InputFileName
, "w");
292 if (LogFile
== NULL
) {
293 Error (NULL
, 0, 0, InputFileName
, "could not append to log file");
297 // Determine size of FV
299 Status
= ReadHeader (InputFile
, &FvSize
, &ErasePolarity
);
300 if (EFI_ERROR (Status
)) {
301 Error (NULL
, 0, 0, "could not parse the FV header", NULL
);
305 // Allocate a buffer for the FV image
307 FvImage
= malloc (FvSize
);
308 if (FvImage
== NULL
) {
309 Error (NULL
, 0, 0, "application error", "memory allocation failed");
313 // Read the entire FV to the buffer
315 BytesRead
= fread (FvImage
, 1, FvSize
, InputFile
);
318 if ((unsigned int) BytesRead
!= FvSize
) {
319 Error (NULL
, 0, 0, InputFileName
, "failed to read from file");
323 // Prepare to walk the FV image
325 InitializeFvLib (FvImage
, FvSize
);
327 // Get the first file
329 Status
= GetNextFile (NULL
, &CurrentFile
);
330 if (EFI_ERROR (Status
)) {
331 Error (NULL
, 0, 0, "cannot find the first file in the FV image", NULL
);
335 // Check if each file should be rebased
337 while (CurrentFile
!= NULL
) {
344 XipBase
+ (UINTN
)CurrentFile
- (UINTN
)FvImage
,
350 if (EFI_ERROR (Status
)) {
353 case EFI_INVALID_PARAMETER
:
354 Error (NULL
, 0, 0, "invalid parameter passed to FfsRebase", NULL
);
358 Error (NULL
, 0, 0, "error detected while rebasing -- aborted", NULL
);
361 case EFI_OUT_OF_RESOURCES
:
362 Error (NULL
, 0, 0, "FfsRebase could not allocate required resources", NULL
);
366 Error (NULL
, 0, 0, "FfsRebase could not locate a PE32 section", NULL
);
370 Error (NULL
, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status
);
379 Status
= GetNextFile (CurrentFile
, &CurrentFile
);
380 if (EFI_ERROR (Status
)) {
381 Error (NULL
, 0, 0, "cannot find the next file in the FV image", NULL
);
386 // Open the output file
388 OutputFile
= fopen (OutputFileName
, "wb");
389 if (OutputFile
== NULL
) {
390 Error (NULL
, 0, 0, OutputFileName
, "failed to open output file");
394 if (fwrite (FvImage
, 1, FvSize
, OutputFile
) != FvSize
) {
395 Error (NULL
, 0, 0, "failed to write to output file", 0);
400 if (InputFile
!= NULL
) {
404 // If we created an output file, and there was an error, remove it so
405 // subsequent builds will rebuild it.
407 if (OutputFile
!= NULL
) {
408 if (GetUtilityStatus () == STATUS_ERROR
) {
409 remove (OutputFileName
);
415 if (LogFile
!= NULL
) {
419 if (FvImage
!= NULL
) {
423 return GetUtilityStatus ();
430 OUT BOOLEAN
*ErasePolarity
436 This function determines the size of the FV and the erase polarity. The
437 erase polarity is the FALSE value for file state.
441 InputFile The file that contains the FV image.
442 FvSize The size of the FV.
443 ErasePolarity The FV erase polarity.
447 EFI_SUCCESS Function completed successfully.
448 EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
449 EFI_ABORTED The function encountered an error.
453 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader
;
454 EFI_FV_BLOCK_MAP_ENTRY BlockMap
;
462 // Check input parameters
464 if ((InputFile
== NULL
) || (FvSize
== NULL
) || (ErasePolarity
== NULL
)) {
465 Error (NULL
, 0, 0, "ReadHeader()", "invalid input parameter");
466 return EFI_INVALID_PARAMETER
;
471 fread (&VolumeHeader
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
472 BytesRead
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
) - sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
473 Signature
[0] = VolumeHeader
.Signature
;
477 // Get erase polarity
479 if (VolumeHeader
.Attributes
& EFI_FVB_ERASE_POLARITY
) {
480 *ErasePolarity
= TRUE
;
484 fread (&BlockMap
, sizeof (EFI_FV_BLOCK_MAP_ENTRY
), 1, InputFile
);
485 BytesRead
+= sizeof (EFI_FV_BLOCK_MAP_ENTRY
);
487 if (BlockMap
.NumBlocks
!= 0) {
488 Size
+= BlockMap
.NumBlocks
* BlockMap
.BlockLength
;
491 } while (!(BlockMap
.NumBlocks
== 0 && BlockMap
.BlockLength
== 0));
493 if (VolumeHeader
.FvLength
!= Size
) {
494 Error (NULL
, 0, 0, "volume size not consistant with block maps", NULL
);
513 Displays the standard utility information to SDTOUT
525 printf ("%s v%d.%d -PEI Rebase Utility.\n", UTILITY_NAME
, UTILITY_MAJOR_VERSION
, UTILITY_MINOR_VERSION
);
526 printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");
537 Displays the utility usage syntax to STDOUT
552 "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-F InputFvInfName]\n",
555 printf (" [-D BootDriverBaseAddress] [-R RuntimeDriverBaseAddress]\n");
556 printf (" Where:\n");
557 printf (" InputFileName is the name of the EFI FV file to rebase.\n");
558 printf (" OutputFileName is the desired output file name.\n");
559 printf (" BaseAddress is the rebase address for all drivers run in Flash.\n");
560 printf (" InputFvInfName is the Fv.inf file that contains this FV base address to rebase against.\n");
561 printf (" BootDriverBaseAddress is the rebase address for all boot drivers in this fv image.\n");
562 printf (" RuntimeDriverBaseAddress is the rebase address for all runtime drivers in this fv image.\n");
563 printf (" Argument pair may be in any order.\n\n");
568 IN OUT EFI_FFS_FILE_HEADER
*FfsFile
,
570 IN OUT EFI_PHYSICAL_ADDRESS XipBase
,
571 IN OUT EFI_PHYSICAL_ADDRESS
*BsBase
,
572 IN OUT EFI_PHYSICAL_ADDRESS
*RtBase
,
579 This function determines if a file is XIP and should be rebased. It will
580 rebase any PE32 sections found in the file using the base address.
584 FfsFile A pointer to Ffs file image.
585 BaseAddress The base address to use for rebasing the file image.
589 EFI_SUCCESS The image was properly rebased.
590 EFI_INVALID_PARAMETER An input parameter is invalid.
591 EFI_ABORTED An error occurred while rebasing the input file image.
592 EFI_OUT_OF_RESOURCES Could not allocate a required resource.
593 EFI_NOT_FOUND No compressed sections could be found.
598 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
599 EFI_PHYSICAL_ADDRESS NewPe32BaseAddress
;
601 EFI_FILE_SECTION_POINTER CurrentPe32Section
;
602 EFI_FFS_FILE_STATE SavedState
;
603 EFI_IMAGE_NT_HEADERS32
*PeHdr
;
604 EFI_TE_IMAGE_HEADER
*TEImageHeader
;
605 UINT8 FileGuidString
[80];
607 EFI_FFS_FILE_TAIL TailValue
;
608 EFI_PHYSICAL_ADDRESS
*BaseToUpdate
;
609 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*DebugEntry
;
613 // Verify input parameters
615 if (FfsFile
== NULL
) {
616 return EFI_INVALID_PARAMETER
;
619 // Convert the GUID to a string so we can at least report which file
620 // if we find an error.
622 PrintGuidToBuffer (&FfsFile
->Name
, FileGuidString
, sizeof (FileGuidString
), TRUE
);
623 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
624 TailSize
= sizeof (EFI_FFS_FILE_TAIL
);
629 // Do some cursory checks on the FFS file contents
631 Status
= VerifyFfsFile (FfsFile
);
632 if (EFI_ERROR (Status
)) {
633 Error (NULL
, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString
);
634 return EFI_INVALID_PARAMETER
;
638 // We only process files potentially containing PE32 sections.
640 switch (FfsFile
->Type
) {
641 case EFI_FV_FILETYPE_SECURITY_CORE
:
642 case EFI_FV_FILETYPE_PEI_CORE
:
643 case EFI_FV_FILETYPE_PEIM
:
644 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
645 case EFI_FV_FILETYPE_DRIVER
:
646 case EFI_FV_FILETYPE_DXE_CORE
:
653 // Rebase each PE32 section
655 Status
= EFI_SUCCESS
;
656 for (Index
= 1;; Index
++) {
657 Status
= GetSectionByType (FfsFile
, EFI_SECTION_PE32
, Index
, &CurrentPe32Section
);
658 if (EFI_ERROR (Status
)) {
663 // Initialize context
665 memset (&ImageContext
, 0, sizeof (ImageContext
));
666 ImageContext
.Handle
= (VOID
*) ((UINTN
) CurrentPe32Section
.Pe32Section
+ sizeof (EFI_PE32_SECTION
));
667 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) FfsRebaseImageRead
;
668 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
669 if (EFI_ERROR (Status
)) {
670 Error (NULL
, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString
);
675 // Don't Load PeImage, only to relocate current image.
677 ImageContext
.ImageAddress
= (UINTN
) CurrentPe32Section
.Pe32Section
+ sizeof (EFI_PE32_SECTION
);
680 // Check if section-alignment and file-alignment match or not
682 PeHdr
= (EFI_IMAGE_NT_HEADERS
*)((UINTN
)ImageContext
.ImageAddress
+ ImageContext
.PeCoffHeaderOffset
);
683 if (PeHdr
->OptionalHeader
.SectionAlignment
!= PeHdr
->OptionalHeader
.FileAlignment
) {
685 // Nor XIP module can be ignored.
687 if ((Flags
& 1) == 0) {
690 Error (NULL
, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString
);
695 // Update CodeView and PdbPointer in ImageContext
697 DebugEntry
= (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*)(UINTN
)(
698 ImageContext
.ImageAddress
+
699 ImageContext
.DebugDirectoryEntryRva
701 ImageContext
.CodeView
= (VOID
*)(UINTN
)(
702 ImageContext
.ImageAddress
+
705 switch (*(UINT32
*) ImageContext
.CodeView
) {
706 case CODEVIEW_SIGNATURE_NB10
:
707 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
);
710 case CODEVIEW_SIGNATURE_RSDS
:
711 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY
);
719 // Calculate the PE32 base address, based on file type
721 switch (FfsFile
->Type
) {
722 case EFI_FV_FILETYPE_SECURITY_CORE
:
723 case EFI_FV_FILETYPE_PEI_CORE
:
724 case EFI_FV_FILETYPE_PEIM
:
725 case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
:
726 if ((Flags
& 1) == 0) {
728 // We aren't relocating XIP code, so skip it.
734 XipBase
+ (UINTN
)ImageContext
.ImageAddress
- (UINTN
)FfsFile
;
735 BaseToUpdate
= &XipBase
;
738 case EFI_FV_FILETYPE_DRIVER
:
739 PeHdr
= (EFI_IMAGE_NT_HEADERS32
*)(ImageContext
.ImageAddress
+ ImageContext
.PeCoffHeaderOffset
);
740 switch (PeHdr
->OptionalHeader
.Subsystem
) {
741 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
:
742 if ((Flags
& 4) == 0) {
744 // RT drivers aren't supposed to be relocated
749 NewPe32BaseAddress
= *RtBase
;
750 BaseToUpdate
= RtBase
;
755 // We treat all other subsystems the same as BS_DRIVER
757 if ((Flags
& 2) == 0) {
759 // Skip all BS_DRIVER's
764 NewPe32BaseAddress
= *BsBase
;
765 BaseToUpdate
= BsBase
;
770 case EFI_FV_FILETYPE_DXE_CORE
:
771 if ((Flags
& 2) == 0) {
778 NewPe32BaseAddress
= *BsBase
;
779 BaseToUpdate
= BsBase
;
784 // Not supported file type
789 ImageContext
.DestinationAddress
= NewPe32BaseAddress
;
790 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
791 if (EFI_ERROR (Status
)) {
792 Error (NULL
, 0, 0, "RelocateImage() call failed on rebase", FileGuidString
);
797 // Update BASE address
803 ImageContext
.DestinationAddress
805 *BaseToUpdate
+= EFI_SIZE_TO_PAGES (ImageContext
.ImageSize
) * EFI_PAGE_SIZE
;
808 // Now update file checksum
810 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
811 TailSize
= sizeof (EFI_FFS_FILE_TAIL
);
816 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
817 SavedState
= FfsFile
->State
;
818 FfsFile
->IntegrityCheck
.Checksum
.File
= 0;
820 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
821 FfsFile
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 (
823 GetLength (FfsFile
->Size
) - TailSize
826 FfsFile
->IntegrityCheck
.Checksum
.File
= FFS_FIXED_CHECKSUM
;
829 FfsFile
->State
= SavedState
;
832 // Update tail if present
834 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
835 TailValue
= (EFI_FFS_FILE_TAIL
) (~(FfsFile
->IntegrityCheck
.TailReference
));
836 *(EFI_FFS_FILE_TAIL
*) (((UINTN
) FfsFile
+ GetLength (FfsFile
->Size
) - sizeof (EFI_FFS_FILE_TAIL
))) = TailValue
;
840 if ((Flags
& 1) == 0 || (
841 FfsFile
->Type
!= EFI_FV_FILETYPE_SECURITY_CORE
&&
842 FfsFile
->Type
!= EFI_FV_FILETYPE_PEI_CORE
&&
844 FfsFile
->Type
!= EFI_FV_FILETYPE_PEIM
&&
845 FfsFile
->Type
!= EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
848 // Only XIP code may have a TE section
854 // Now process TE sections
856 for (Index
= 1;; Index
++) {
857 Status
= GetSectionByType (FfsFile
, EFI_SECTION_TE
, Index
, &CurrentPe32Section
);
858 if (EFI_ERROR (Status
)) {
863 // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
866 TEImageHeader
= (EFI_TE_IMAGE_HEADER
*) ((UINT8
*) CurrentPe32Section
.Pe32Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
869 // Initialize context, load image info.
871 memset (&ImageContext
, 0, sizeof (ImageContext
));
872 ImageContext
.Handle
= (VOID
*) TEImageHeader
;
873 ImageContext
.ImageRead
= (PE_COFF_LOADER_READ_FILE
) FfsRebaseImageRead
;
875 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
877 if (EFI_ERROR (Status
)) {
878 Error (NULL
, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString
);
882 // Don't reload TeImage
884 ImageContext
.ImageAddress
= (UINTN
) TEImageHeader
;
887 // Update CodeView and PdbPointer in ImageContext
889 DebugEntry
= (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*)(UINTN
)(
890 ImageContext
.ImageAddress
+
891 ImageContext
.DebugDirectoryEntryRva
+
892 sizeof(EFI_TE_IMAGE_HEADER
) -
893 TEImageHeader
->StrippedSize
896 ImageContext
.CodeView
= (VOID
*)(UINTN
)(
897 ImageContext
.ImageAddress
+
899 sizeof(EFI_TE_IMAGE_HEADER
) -
900 TEImageHeader
->StrippedSize
903 switch (*(UINT32
*) ImageContext
.CodeView
) {
904 case CODEVIEW_SIGNATURE_NB10
:
905 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
);
908 case CODEVIEW_SIGNATURE_RSDS
:
909 ImageContext
.PdbPointer
= (CHAR8
*) ImageContext
.CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY
);
919 ImageContext
.DestinationAddress
= XipBase
+ (UINTN
) TEImageHeader
+ sizeof (EFI_TE_IMAGE_HEADER
) \
920 - TEImageHeader
->StrippedSize
- (UINTN
) FfsFile
;
921 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
922 if (EFI_ERROR (Status
)) {
923 Error (NULL
, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString
);
927 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
928 TailSize
= sizeof (EFI_FFS_FILE_TAIL
);
933 // Now update file checksum
935 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
936 SavedState
= FfsFile
->State
;
937 FfsFile
->IntegrityCheck
.Checksum
.File
= 0;
939 if (FfsFile
->Attributes
& FFS_ATTRIB_CHECKSUM
) {
940 FfsFile
->IntegrityCheck
.Checksum
.File
= CalculateChecksum8 (
942 GetLength (FfsFile
->Size
) - TailSize
945 FfsFile
->IntegrityCheck
.Checksum
.File
= FFS_FIXED_CHECKSUM
;
948 FfsFile
->State
= SavedState
;
951 // Update tail if present
953 if (FfsFile
->Attributes
& FFS_ATTRIB_TAIL_PRESENT
) {
954 TailValue
= (EFI_FFS_FILE_TAIL
) (~(FfsFile
->IntegrityCheck
.TailReference
));
955 *(EFI_FFS_FILE_TAIL
*) (((UINTN
) FfsFile
+ GetLength (FfsFile
->Size
) - sizeof (EFI_FFS_FILE_TAIL
))) = TailValue
;
962 ImageContext
.DestinationAddress
973 IN OUT UINT32
*ReadSize
,
980 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
984 FileHandle - The handle to the PE/COFF file
986 FileOffset - The offset, in bytes, into the file to read
988 ReadSize - The number of bytes to read from the file starting at FileOffset
990 Buffer - A pointer to the buffer to read the data into.
994 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
1002 Destination8
= Buffer
;
1003 Source8
= (CHAR8
*) ((UINTN
) FileHandle
+ FileOffset
);
1006 *(Destination8
++) = *(Source8
++);