mirror of https://github.com/acidanthera/audk.git
Correct TeImage file format and Clean up PeiRebase tool to remove unused code and only relocate image.
Move two EFI_DEP_REPLACE_TRUE and DEPEX_STACK_SIZE_INCREMENT macros from MdePkg to EdkModule/DxeMain module, because these two macros are specific implementation, not defined in spec. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2249 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
591ee27e84
commit
5b66424456
|
@ -33,6 +33,18 @@ Revision History
|
||||||
#include "Exec.h"
|
#include "Exec.h"
|
||||||
#include "hand.h"
|
#include "hand.h"
|
||||||
|
|
||||||
|
///
|
||||||
|
/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependecy expression
|
||||||
|
/// to save time. A EFI_DEP_PUSH is evauated one an
|
||||||
|
/// replaced with EFI_DEP_REPLACE_TRUE
|
||||||
|
///
|
||||||
|
#define EFI_DEP_REPLACE_TRUE 0xff
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Define the initial size of the dependency expression evaluation stack
|
||||||
|
///
|
||||||
|
#define DEPEX_STACK_SIZE_INCREMENT 0x1000
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EFI_GUID *ProtocolGuid;
|
EFI_GUID *ProtocolGuid;
|
||||||
VOID **Protocol;
|
VOID **Protocol;
|
||||||
|
|
|
@ -208,7 +208,7 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugEntry != NULL && DirectoryEntry != NULL) {
|
if (DebugEntry != NULL && DirectoryEntry != NULL) {
|
||||||
for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {
|
for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
|
||||||
if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
|
if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
|
||||||
if (DebugEntry->SizeOfData > 0) {
|
if (DebugEntry->SizeOfData > 0) {
|
||||||
CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
|
CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
Module Name: Dependency.h
|
Module Name: Dependency.h
|
||||||
|
|
||||||
|
@par Revision Reference:
|
||||||
|
These definitions are from DxeCis 0.91 spec.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __DEPENDENCY_H__
|
#ifndef __DEPENDENCY_H__
|
||||||
|
@ -34,16 +37,4 @@
|
||||||
/// EFI_DEP_SOR - If present, this must be the first opcode
|
/// EFI_DEP_SOR - If present, this must be the first opcode
|
||||||
#define EFI_DEP_SOR 0x09
|
#define EFI_DEP_SOR 0x09
|
||||||
|
|
||||||
///
|
|
||||||
/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependecy expression
|
|
||||||
/// to save time. A EFI_DEP_PUSH is evauated one an
|
|
||||||
/// replaced with EFI_DEP_REPLACE_TRUE
|
|
||||||
///
|
|
||||||
#define EFI_DEP_REPLACE_TRUE 0xff
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Define the initial size of the dependency expression evaluation stack
|
|
||||||
///
|
|
||||||
#define DEPEX_STACK_SIZE_INCREMENT 0x1000
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -60,13 +60,6 @@
|
||||||
EFI_FILE_HEADER_INVALID \
|
EFI_FILE_HEADER_INVALID \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \
|
|
||||||
( \
|
|
||||||
(BOOLEAN) ( \
|
|
||||||
(FvbAttributes & EFI_FVB_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \
|
|
||||||
) \
|
|
||||||
)
|
|
||||||
|
|
||||||
typedef UINT16 EFI_FFS_FILE_TAIL;
|
typedef UINT16 EFI_FFS_FILE_TAIL;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
|
@ -70,6 +70,13 @@ typedef UINT32 EFI_FVB_ATTRIBUTES;
|
||||||
EFI_FVB_LOCK_CAP \
|
EFI_FVB_LOCK_CAP \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \
|
||||||
|
( \
|
||||||
|
(BOOLEAN) ( \
|
||||||
|
(FvbAttributes & EFI_FVB_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
#define EFI_FVB_STATUS (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | EFI_FVB_LOCK_STATUS)
|
#define EFI_FVB_STATUS (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | EFI_FVB_LOCK_STATUS)
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
|
@ -299,7 +299,7 @@ PeCoffLoaderGetImageInfo (
|
||||||
ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;
|
ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase);
|
ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -598,8 +598,11 @@ PeCoffLoaderRelocateImage (
|
||||||
//
|
//
|
||||||
if (ImageContext->DestinationAddress != 0) {
|
if (ImageContext->DestinationAddress != 0) {
|
||||||
BaseAddress = ImageContext->DestinationAddress;
|
BaseAddress = ImageContext->DestinationAddress;
|
||||||
} else {
|
} else if (!(ImageContext->IsTeImage)) {
|
||||||
BaseAddress = ImageContext->ImageAddress;
|
BaseAddress = ImageContext->ImageAddress;
|
||||||
|
} else {
|
||||||
|
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
|
||||||
|
BaseAddress = ImageContext->ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ImageContext->IsTeImage)) {
|
if (!(ImageContext->IsTeImage)) {
|
||||||
|
|
|
@ -272,6 +272,7 @@ Returns:
|
||||||
//
|
//
|
||||||
// Double-check the file to make sure it's what we expect it to be
|
// Double-check the file to make sure it's what we expect it to be
|
||||||
//
|
//
|
||||||
|
|
||||||
if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {
|
if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {
|
||||||
goto Finish;
|
goto Finish;
|
||||||
}
|
}
|
||||||
|
@ -372,7 +373,7 @@ Returns:
|
||||||
|
|
||||||
TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem;
|
TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem;
|
||||||
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
|
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
|
||||||
TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
|
TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase);
|
||||||
if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
||||||
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
@ -413,7 +414,7 @@ Returns:
|
||||||
|
|
||||||
TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem;
|
TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem;
|
||||||
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
|
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
|
||||||
TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
|
TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase);
|
||||||
if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
||||||
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
@ -620,6 +621,17 @@ Returns:
|
||||||
goto Finish;
|
goto Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check FileAlginment and SectionAlignment match or not
|
||||||
|
// Because TeImage header doesn't record filealginment and sectionalignment info,
|
||||||
|
// TeImage is used for PEIM and PeiCore XIP module.
|
||||||
|
// So, check alignment match before generate TeImage to check.
|
||||||
|
//
|
||||||
|
if (OptionalHdr.SectionAlignment != OptionalHdr.FileAlignment) {
|
||||||
|
Error (NULL, 0, 0, FileName, "Section-Alignment and File-Alignment does not match");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
*SubSystem = OptionalHdr.Subsystem;
|
*SubSystem = OptionalHdr.Subsystem;
|
||||||
if (mOptions.Verbose) {
|
if (mOptions.Verbose) {
|
||||||
fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem);
|
fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem);
|
||||||
|
|
|
@ -260,7 +260,7 @@ Returns:
|
||||||
if (!(ImageContext->IsTeImage)) {
|
if (!(ImageContext->IsTeImage)) {
|
||||||
ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;
|
ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;
|
||||||
} else {
|
} else {
|
||||||
ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase);
|
ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr.StrippedSize);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Initialize the alternate destination address to 0 indicating that it
|
// Initialize the alternate destination address to 0 indicating that it
|
||||||
|
@ -346,7 +346,7 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugDirectoryEntryFileOffset != 0) {
|
if (DebugDirectoryEntryFileOffset != 0) {
|
||||||
for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {
|
for (Index = 0; Index < (DebugDirectoryEntry->Size); Index += Size) {
|
||||||
//
|
//
|
||||||
// Read next debug directory entry
|
// Read next debug directory entry
|
||||||
//
|
//
|
||||||
|
@ -363,7 +363,7 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
|
if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
|
||||||
ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
|
ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);
|
||||||
if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {
|
if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {
|
||||||
ImageContext->ImageSize += DebugEntry.SizeOfData;
|
ImageContext->ImageSize += DebugEntry.SizeOfData;
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugDirectoryEntryFileOffset != 0) {
|
if (DebugDirectoryEntryFileOffset != 0) {
|
||||||
for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {
|
for (Index = 0; Index < (DebugDirectoryEntry->Size); Index += Size) {
|
||||||
//
|
//
|
||||||
// Read next debug directory entry
|
// Read next debug directory entry
|
||||||
//
|
//
|
||||||
|
@ -455,7 +455,7 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
|
if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
|
||||||
ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
|
ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,6 +279,7 @@ Returns:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Open the file containing the FV
|
// Open the file containing the FV
|
||||||
//
|
//
|
||||||
|
@ -553,14 +554,18 @@ Returns:
|
||||||
Version();
|
Version();
|
||||||
|
|
||||||
printf (
|
printf (
|
||||||
"\nUsage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",
|
"Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-F InputFvInfName]\n",
|
||||||
UTILITY_NAME
|
UTILITY_NAME
|
||||||
);
|
);
|
||||||
|
printf (" [-D BootDriverBaseAddress] [-R RuntimeDriverBaseAddress]\n");
|
||||||
printf (" Where:\n");
|
printf (" Where:\n");
|
||||||
printf (" InputFileName is the name of the EFI FV file to rebase.\n");
|
printf (" InputFileName is the name of the EFI FV file to rebase.\n");
|
||||||
printf (" OutputFileName is the desired output file name.\n");
|
printf (" OutputFileName is the desired output file name.\n");
|
||||||
printf (" BaseAddress is the FV base address to rebase agains.\n");
|
printf (" BaseAddress is the rebase address for all drivers run in Flash.\n");
|
||||||
printf (" Argument pair may be in any order.\n");
|
printf (" InputFvInfName is the Fv.inf file that contains this FV base address to rebase against.\n");
|
||||||
|
printf (" BootDriverBaseAddress is the rebase address for all boot drivers in this fv image.\n");
|
||||||
|
printf (" RuntimeDriverBaseAddress is the rebase address for all runtime drivers in this fv image.\n");
|
||||||
|
printf (" Argument pair may be in any order.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -596,27 +601,18 @@ Returns:
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
UINTN MemoryImagePointer;
|
|
||||||
UINTN MemoryImagePointerAligned;
|
|
||||||
EFI_PHYSICAL_ADDRESS ImageAddress;
|
|
||||||
UINT64 ImageSize;
|
|
||||||
EFI_PHYSICAL_ADDRESS EntryPoint;
|
|
||||||
UINT32 Pe32ImageSize;
|
|
||||||
EFI_PHYSICAL_ADDRESS NewPe32BaseAddress;
|
EFI_PHYSICAL_ADDRESS NewPe32BaseAddress;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
EFI_FILE_SECTION_POINTER CurrentPe32Section;
|
EFI_FILE_SECTION_POINTER CurrentPe32Section;
|
||||||
EFI_FFS_FILE_STATE SavedState;
|
EFI_FFS_FILE_STATE SavedState;
|
||||||
EFI_IMAGE_NT_HEADERS32 *PeHdr;
|
EFI_IMAGE_NT_HEADERS32 *PeHdr;
|
||||||
EFI_IMAGE_NT_HEADERS64 *PePlusHdr;
|
|
||||||
UINT32 *PeHdrSizeOfImage;
|
|
||||||
UINT32 *PeHdrChecksum;
|
|
||||||
EFI_TE_IMAGE_HEADER *TEImageHeader;
|
EFI_TE_IMAGE_HEADER *TEImageHeader;
|
||||||
UINT8 *TEBuffer;
|
|
||||||
EFI_IMAGE_DOS_HEADER *DosHeader;
|
|
||||||
UINT8 FileGuidString[80];
|
UINT8 FileGuidString[80];
|
||||||
UINT32 TailSize;
|
UINT32 TailSize;
|
||||||
EFI_FFS_FILE_TAIL TailValue;
|
EFI_FFS_FILE_TAIL TailValue;
|
||||||
EFI_PHYSICAL_ADDRESS *BaseToUpdate;
|
EFI_PHYSICAL_ADDRESS *BaseToUpdate;
|
||||||
|
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Verify input parameters
|
// Verify input parameters
|
||||||
|
@ -668,7 +664,6 @@ Returns:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize context
|
// Initialize context
|
||||||
//
|
//
|
||||||
|
@ -681,6 +676,50 @@ Returns:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Don't Load PeImage, only to relocate current image.
|
||||||
|
//
|
||||||
|
ImageContext.ImageAddress = (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if section-alignment and file-alignment match or not
|
||||||
|
//
|
||||||
|
PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);
|
||||||
|
if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {
|
||||||
|
//
|
||||||
|
// Nor XIP module can be ignored.
|
||||||
|
//
|
||||||
|
if ((Flags & 1) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update CodeView and PdbPointer in ImageContext
|
||||||
|
//
|
||||||
|
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(
|
||||||
|
ImageContext.ImageAddress +
|
||||||
|
ImageContext.DebugDirectoryEntryRva
|
||||||
|
);
|
||||||
|
ImageContext.CodeView = (VOID *)(UINTN)(
|
||||||
|
ImageContext.ImageAddress +
|
||||||
|
DebugEntry->RVA
|
||||||
|
);
|
||||||
|
switch (*(UINT32 *) ImageContext.CodeView) {
|
||||||
|
case CODEVIEW_SIGNATURE_NB10:
|
||||||
|
ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CODEVIEW_SIGNATURE_RSDS:
|
||||||
|
ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Calculate the PE32 base address, based on file type
|
// Calculate the PE32 base address, based on file type
|
||||||
//
|
//
|
||||||
|
@ -697,19 +736,12 @@ Returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
NewPe32BaseAddress =
|
NewPe32BaseAddress =
|
||||||
XipBase +
|
XipBase + (UINTN)ImageContext.ImageAddress - (UINTN)FfsFile;
|
||||||
(UINTN)CurrentPe32Section.Pe32Section +
|
|
||||||
sizeof (EFI_COMMON_SECTION_HEADER) -
|
|
||||||
(UINTN)FfsFile;
|
|
||||||
BaseToUpdate = &XipBase;
|
BaseToUpdate = &XipBase;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFI_FV_FILETYPE_DRIVER:
|
case EFI_FV_FILETYPE_DRIVER:
|
||||||
PeHdr = (EFI_IMAGE_NT_HEADERS32*)(
|
PeHdr = (EFI_IMAGE_NT_HEADERS32*)(ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);
|
||||||
(UINTN)CurrentPe32Section.Pe32Section +
|
|
||||||
sizeof (EFI_COMMON_SECTION_HEADER) +
|
|
||||||
ImageContext.PeCoffHeaderOffset
|
|
||||||
);
|
|
||||||
switch (PeHdr->OptionalHeader.Subsystem) {
|
switch (PeHdr->OptionalHeader.Subsystem) {
|
||||||
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
||||||
if ((Flags & 4) == 0) {
|
if ((Flags & 4) == 0) {
|
||||||
|
@ -759,72 +791,13 @@ Returns:
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate a buffer for the image to be loaded into.
|
|
||||||
//
|
|
||||||
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);
|
|
||||||
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x100000));
|
|
||||||
if (MemoryImagePointer == 0) {
|
|
||||||
Error (NULL, 0, 0, "memory allocation failure", NULL);
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x100000);
|
|
||||||
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);
|
|
||||||
|
|
||||||
ImageContext.ImageAddress = MemoryImagePointerAligned;
|
|
||||||
|
|
||||||
Status = PeCoffLoaderLoadImage (&ImageContext);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString);
|
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check if section-alignment and file-alignment match or not
|
|
||||||
//
|
|
||||||
if (!(ImageContext.IsTeImage)) {
|
|
||||||
PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress +
|
|
||||||
ImageContext.PeCoffHeaderOffset);
|
|
||||||
if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {
|
|
||||||
Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);
|
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
return EFI_ABORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//
|
|
||||||
// BUGBUG: TE Image Header lack section-alignment and file-alignment info
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageContext.DestinationAddress = NewPe32BaseAddress;
|
ImageContext.DestinationAddress = NewPe32BaseAddress;
|
||||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);
|
Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageAddress = ImageContext.ImageAddress;
|
|
||||||
ImageSize = ImageContext.ImageSize;
|
|
||||||
EntryPoint = ImageContext.EntryPoint;
|
|
||||||
|
|
||||||
if (ImageSize > Pe32ImageSize) {
|
|
||||||
Error (
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"rebased image is larger than original PE32 image",
|
|
||||||
"0x%X > 0x%X, file %s",
|
|
||||||
ImageSize,
|
|
||||||
Pe32ImageSize,
|
|
||||||
FileGuidString
|
|
||||||
);
|
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
return EFI_ABORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update BASE address
|
// Update BASE address
|
||||||
//
|
//
|
||||||
|
@ -837,47 +810,6 @@ Returns:
|
||||||
);
|
);
|
||||||
*BaseToUpdate += EFI_SIZE_TO_PAGES (ImageContext.ImageSize) * EFI_PAGE_SIZE;
|
*BaseToUpdate += EFI_SIZE_TO_PAGES (ImageContext.ImageSize) * EFI_PAGE_SIZE;
|
||||||
|
|
||||||
//
|
|
||||||
// Since we may have updated the Codeview RVA, we need to insure the PE
|
|
||||||
// header indicates the image is large enough to contain the Codeview data
|
|
||||||
// so it will be loaded properly later if the PEIM is reloaded into memory...
|
|
||||||
//
|
|
||||||
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
|
|
||||||
PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
|
|
||||||
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
|
|
||||||
PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);
|
|
||||||
PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);
|
|
||||||
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
|
|
||||||
PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
|
|
||||||
PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
|
|
||||||
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
|
|
||||||
PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
|
|
||||||
PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
|
|
||||||
} else {
|
|
||||||
Error (
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"unknown machine type in PE32 image",
|
|
||||||
"machine type=0x%X, file=%s",
|
|
||||||
(UINT32) PeHdr->FileHeader.Machine,
|
|
||||||
FileGuidString
|
|
||||||
);
|
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
return EFI_ABORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*PeHdrSizeOfImage != ImageContext.ImageSize) {
|
|
||||||
*PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;
|
|
||||||
if (*PeHdrChecksum) {
|
|
||||||
*PeHdrChecksum = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);
|
|
||||||
|
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now update file checksum
|
// Now update file checksum
|
||||||
//
|
//
|
||||||
|
@ -939,235 +871,65 @@ Returns:
|
||||||
//
|
//
|
||||||
TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));
|
TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));
|
||||||
|
|
||||||
NewPe32BaseAddress = ((UINT32) XipBase) +
|
|
||||||
(
|
|
||||||
(UINTN) CurrentPe32Section.Pe32Section +
|
|
||||||
sizeof (EFI_COMMON_SECTION_HEADER) +
|
|
||||||
sizeof (EFI_TE_IMAGE_HEADER) -
|
|
||||||
TEImageHeader->StrippedSize -
|
|
||||||
(UINTN) FfsFile
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate a buffer to unshrink the image into.
|
// Initialize context, load image info.
|
||||||
//
|
|
||||||
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
|
|
||||||
sizeof (EFI_TE_IMAGE_HEADER);
|
|
||||||
Pe32ImageSize += TEImageHeader->StrippedSize;
|
|
||||||
TEBuffer = (UINT8 *) malloc (Pe32ImageSize);
|
|
||||||
if (TEBuffer == NULL) {
|
|
||||||
Error (NULL, 0, 0, "failed to allocate memory", NULL);
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Expand the image into our buffer and fill in critical fields in the DOS header
|
|
||||||
// Fill in fields required by the loader.
|
|
||||||
// At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value
|
|
||||||
// itself.
|
|
||||||
//
|
|
||||||
memset (TEBuffer, 0, Pe32ImageSize);
|
|
||||||
DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer;
|
|
||||||
DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;
|
|
||||||
*(UINT32 *) (TEBuffer + 0x3C) = 0x40;
|
|
||||||
PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);
|
|
||||||
PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
|
|
||||||
PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;
|
|
||||||
PeHdr->FileHeader.Machine = TEImageHeader->Machine;
|
|
||||||
PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Say the size of the optional header is the total we stripped off less the size of a PE file header and PE signature and
|
|
||||||
// the 0x40 bytes for our DOS header.
|
|
||||||
//
|
|
||||||
PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));
|
|
||||||
if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA32) {
|
|
||||||
PeHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
|
|
||||||
} else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {
|
|
||||||
PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
|
||||||
} else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_X64) {
|
|
||||||
PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
|
||||||
} else {
|
|
||||||
Error (
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"unknown machine type in TE image",
|
|
||||||
"machine type=0x%X, file=%s",
|
|
||||||
(UINT32) TEImageHeader->Machine,
|
|
||||||
FileGuidString
|
|
||||||
);
|
|
||||||
free (TEBuffer);
|
|
||||||
return EFI_ABORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
|
||||||
PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
|
|
||||||
PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
|
|
||||||
PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
|
|
||||||
PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
|
|
||||||
sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
|
|
||||||
//
|
|
||||||
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
|
|
||||||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
|
|
||||||
) {
|
|
||||||
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
|
|
||||||
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
|
||||||
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
|
|
||||||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
|
|
||||||
) {
|
|
||||||
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
|
|
||||||
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
|
|
||||||
if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
|
|
||||||
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
|
|
||||||
//
|
|
||||||
PeHdr->OptionalHeader.SectionAlignment = 0x10;
|
|
||||||
} else {
|
|
||||||
PePlusHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
|
|
||||||
PePlusHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
|
|
||||||
PePlusHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
|
|
||||||
PePlusHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
|
|
||||||
sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
|
|
||||||
//
|
|
||||||
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
|
|
||||||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
|
|
||||||
) {
|
|
||||||
PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
|
|
||||||
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
|
||||||
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
|
|
||||||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
|
|
||||||
) {
|
|
||||||
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
|
|
||||||
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
|
|
||||||
if (PePlusHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
|
|
||||||
PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
|
|
||||||
//
|
|
||||||
PePlusHdr->OptionalHeader.SectionAlignment = 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Copy the rest of the image to its original offset
|
|
||||||
//
|
|
||||||
memcpy (
|
|
||||||
TEBuffer + TEImageHeader->StrippedSize,
|
|
||||||
(UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER),
|
|
||||||
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
|
|
||||||
sizeof (EFI_TE_IMAGE_HEADER)
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize context
|
|
||||||
//
|
//
|
||||||
memset (&ImageContext, 0, sizeof (ImageContext));
|
memset (&ImageContext, 0, sizeof (ImageContext));
|
||||||
ImageContext.Handle = (VOID *) TEBuffer;
|
ImageContext.Handle = (VOID *) TEImageHeader;
|
||||||
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
|
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
|
||||||
|
|
||||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);
|
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);
|
||||||
free (TEBuffer);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Allocate a buffer for the image to be loaded into.
|
// Don't reload TeImage
|
||||||
//
|
//
|
||||||
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x100000));
|
ImageContext.ImageAddress = (UINTN) TEImageHeader;
|
||||||
if (MemoryImagePointer == 0) {
|
|
||||||
Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);
|
|
||||||
free (TEBuffer);
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x100000);
|
|
||||||
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update CodeView and PdbPointer in ImageContext
|
||||||
|
//
|
||||||
|
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(
|
||||||
|
ImageContext.ImageAddress +
|
||||||
|
ImageContext.DebugDirectoryEntryRva +
|
||||||
|
sizeof(EFI_TE_IMAGE_HEADER) -
|
||||||
|
TEImageHeader->StrippedSize
|
||||||
|
);
|
||||||
|
|
||||||
ImageContext.ImageAddress = MemoryImagePointerAligned;
|
ImageContext.CodeView = (VOID *)(UINTN)(
|
||||||
Status = PeCoffLoaderLoadImage (&ImageContext);
|
ImageContext.ImageAddress +
|
||||||
if (EFI_ERROR (Status)) {
|
DebugEntry->RVA +
|
||||||
Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString);
|
sizeof(EFI_TE_IMAGE_HEADER) -
|
||||||
free (TEBuffer);
|
TEImageHeader->StrippedSize
|
||||||
free ((VOID *) MemoryImagePointer);
|
);
|
||||||
return Status;
|
|
||||||
|
switch (*(UINT32 *) ImageContext.CodeView) {
|
||||||
|
case CODEVIEW_SIGNATURE_NB10:
|
||||||
|
ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CODEVIEW_SIGNATURE_RSDS:
|
||||||
|
ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageContext.DestinationAddress = NewPe32BaseAddress;
|
//
|
||||||
|
// Reloacate TeImage
|
||||||
|
//
|
||||||
|
ImageContext.DestinationAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \
|
||||||
|
- TEImageHeader->StrippedSize - (UINTN) FfsFile;
|
||||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);
|
Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
free (TEBuffer);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageAddress = ImageContext.ImageAddress;
|
|
||||||
ImageSize = ImageContext.ImageSize;
|
|
||||||
EntryPoint = ImageContext.EntryPoint;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Since we may have updated the Codeview RVA, we need to insure the PE
|
|
||||||
// header indicates the image is large enough to contain the Codeview data
|
|
||||||
// so it will be loaded properly later if the PEIM is reloaded into memory...
|
|
||||||
//
|
|
||||||
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
|
|
||||||
PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
|
|
||||||
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
|
|
||||||
PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);
|
|
||||||
PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);
|
|
||||||
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
|
|
||||||
PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
|
|
||||||
PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
|
|
||||||
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
|
|
||||||
PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
|
|
||||||
PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
|
|
||||||
} else {
|
|
||||||
Error (
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"unknown machine type in TE image",
|
|
||||||
"machine type=0x%X, file=%s",
|
|
||||||
(UINT32) PeHdr->FileHeader.Machine,
|
|
||||||
FileGuidString
|
|
||||||
);
|
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
free (TEBuffer);
|
|
||||||
return EFI_ABORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*PeHdrSizeOfImage != ImageContext.ImageSize) {
|
|
||||||
*PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;
|
|
||||||
if (*PeHdrChecksum) {
|
|
||||||
*PeHdrChecksum = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
|
|
||||||
memcpy (
|
|
||||||
(UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER),
|
|
||||||
(VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize),
|
|
||||||
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
|
|
||||||
sizeof (EFI_TE_IMAGE_HEADER)
|
|
||||||
);
|
|
||||||
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
TailSize = sizeof (EFI_FFS_FILE_TAIL);
|
TailSize = sizeof (EFI_FFS_FILE_TAIL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1206,12 +968,6 @@ Returns:
|
||||||
ImageContext.DestinationAddress,
|
ImageContext.DestinationAddress,
|
||||||
ImageContext.PdbPointer == NULL ? "*" : ImageContext.PdbPointer
|
ImageContext.PdbPointer == NULL ? "*" : ImageContext.PdbPointer
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// Free buffers
|
|
||||||
//
|
|
||||||
free ((VOID *) MemoryImagePointer);
|
|
||||||
free (TEBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue