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 "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 {
|
||||
EFI_GUID *ProtocolGuid;
|
||||
VOID **Protocol;
|
||||
|
|
|
@ -208,7 +208,7 @@ Returns:
|
|||
}
|
||||
|
||||
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->SizeOfData > 0) {
|
||||
CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
Module Name: Dependency.h
|
||||
|
||||
@par Revision Reference:
|
||||
These definitions are from DxeCis 0.91 spec.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __DEPENDENCY_H__
|
||||
|
@ -34,16 +37,4 @@
|
|||
/// EFI_DEP_SOR - If present, this must be the first opcode
|
||||
#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
|
||||
|
|
|
@ -60,13 +60,6 @@
|
|||
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;
|
||||
|
||||
///
|
||||
|
|
|
@ -70,6 +70,13 @@ typedef UINT32 EFI_FVB_ATTRIBUTES;
|
|||
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)
|
||||
|
||||
///
|
||||
|
|
|
@ -299,7 +299,7 @@ PeCoffLoaderGetImageInfo (
|
|||
ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;
|
||||
}
|
||||
} 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) {
|
||||
BaseAddress = ImageContext->DestinationAddress;
|
||||
} else {
|
||||
} else if (!(ImageContext->IsTeImage)) {
|
||||
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)) {
|
||||
|
|
|
@ -272,6 +272,7 @@ Returns:
|
|||
//
|
||||
// Double-check the file to make sure it's what we expect it to be
|
||||
//
|
||||
|
||||
if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {
|
||||
goto Finish;
|
||||
}
|
||||
|
@ -372,7 +373,7 @@ Returns:
|
|||
|
||||
TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem;
|
||||
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) {
|
||||
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;
|
||||
|
@ -413,7 +414,7 @@ Returns:
|
|||
|
||||
TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem;
|
||||
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) {
|
||||
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;
|
||||
|
@ -620,6 +621,17 @@ Returns:
|
|||
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;
|
||||
if (mOptions.Verbose) {
|
||||
fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem);
|
||||
|
|
|
@ -260,7 +260,7 @@ Returns:
|
|||
if (!(ImageContext->IsTeImage)) {
|
||||
ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;
|
||||
} 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
|
||||
|
@ -345,12 +345,12 @@ Returns:
|
|||
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
|
||||
}
|
||||
|
||||
if (DebugDirectoryEntryFileOffset != 0) {
|
||||
for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {
|
||||
if (DebugDirectoryEntryFileOffset != 0) {
|
||||
for (Index = 0; Index < (DebugDirectoryEntry->Size); Index += Size) {
|
||||
//
|
||||
// Read next debug directory entry
|
||||
//
|
||||
Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
|
||||
Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
|
||||
Status = ImageContext->ImageRead (
|
||||
ImageContext->Handle,
|
||||
DebugDirectoryEntryFileOffset,
|
||||
|
@ -363,7 +363,7 @@ Returns:
|
|||
}
|
||||
|
||||
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) {
|
||||
ImageContext->ImageSize += DebugEntry.SizeOfData;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ Returns:
|
|||
}
|
||||
|
||||
if (DebugDirectoryEntryFileOffset != 0) {
|
||||
for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {
|
||||
for (Index = 0; Index < (DebugDirectoryEntry->Size); Index += Size) {
|
||||
//
|
||||
// Read next debug directory entry
|
||||
//
|
||||
|
@ -455,7 +455,7 @@ Returns:
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,6 +279,7 @@ Returns:
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Open the file containing the FV
|
||||
//
|
||||
|
@ -553,14 +554,18 @@ Returns:
|
|||
Version();
|
||||
|
||||
printf (
|
||||
"\nUsage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",
|
||||
"Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-F InputFvInfName]\n",
|
||||
UTILITY_NAME
|
||||
);
|
||||
printf (" [-D BootDriverBaseAddress] [-R RuntimeDriverBaseAddress]\n");
|
||||
printf (" Where:\n");
|
||||
printf (" InputFileName is the name of the EFI FV file to rebase.\n");
|
||||
printf (" OutputFileName is the desired output file name.\n");
|
||||
printf (" BaseAddress is the FV base address to rebase agains.\n");
|
||||
printf (" Argument pair may be in any order.\n");
|
||||
printf (" InputFileName is the name of the EFI FV file to rebase.\n");
|
||||
printf (" OutputFileName is the desired output file name.\n");
|
||||
printf (" BaseAddress is the rebase address for all drivers run in Flash.\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
|
||||
|
@ -596,27 +601,18 @@ Returns:
|
|||
{
|
||||
EFI_STATUS Status;
|
||||
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;
|
||||
UINTN Index;
|
||||
EFI_FILE_SECTION_POINTER CurrentPe32Section;
|
||||
EFI_FFS_FILE_STATE SavedState;
|
||||
EFI_IMAGE_NT_HEADERS32 *PeHdr;
|
||||
EFI_IMAGE_NT_HEADERS64 *PePlusHdr;
|
||||
UINT32 *PeHdrSizeOfImage;
|
||||
UINT32 *PeHdrChecksum;
|
||||
EFI_TE_IMAGE_HEADER *TEImageHeader;
|
||||
UINT8 *TEBuffer;
|
||||
EFI_IMAGE_DOS_HEADER *DosHeader;
|
||||
UINT8 FileGuidString[80];
|
||||
UINT32 TailSize;
|
||||
EFI_FFS_FILE_TAIL TailValue;
|
||||
EFI_PHYSICAL_ADDRESS *BaseToUpdate;
|
||||
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
|
||||
|
||||
|
||||
//
|
||||
// Verify input parameters
|
||||
|
@ -668,7 +664,6 @@ Returns:
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Initialize context
|
||||
//
|
||||
|
@ -681,6 +676,50 @@ Returns:
|
|||
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
|
||||
//
|
||||
|
@ -697,19 +736,12 @@ Returns:
|
|||
}
|
||||
|
||||
NewPe32BaseAddress =
|
||||
XipBase +
|
||||
(UINTN)CurrentPe32Section.Pe32Section +
|
||||
sizeof (EFI_COMMON_SECTION_HEADER) -
|
||||
(UINTN)FfsFile;
|
||||
XipBase + (UINTN)ImageContext.ImageAddress - (UINTN)FfsFile;
|
||||
BaseToUpdate = &XipBase;
|
||||
break;
|
||||
|
||||
case EFI_FV_FILETYPE_DRIVER:
|
||||
PeHdr = (EFI_IMAGE_NT_HEADERS32*)(
|
||||
(UINTN)CurrentPe32Section.Pe32Section +
|
||||
sizeof (EFI_COMMON_SECTION_HEADER) +
|
||||
ImageContext.PeCoffHeaderOffset
|
||||
);
|
||||
PeHdr = (EFI_IMAGE_NT_HEADERS32*)(ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);
|
||||
switch (PeHdr->OptionalHeader.Subsystem) {
|
||||
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
||||
if ((Flags & 4) == 0) {
|
||||
|
@ -759,72 +791,13 @@ Returns:
|
|||
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;
|
||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);
|
||||
free ((VOID *) MemoryImagePointer);
|
||||
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
|
||||
//
|
||||
|
@ -837,47 +810,6 @@ Returns:
|
|||
);
|
||||
*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
|
||||
//
|
||||
|
@ -923,7 +855,7 @@ Returns:
|
|||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Now process TE sections
|
||||
//
|
||||
|
@ -939,235 +871,65 @@ Returns:
|
|||
//
|
||||
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.
|
||||
//
|
||||
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
|
||||
// Initialize context, load image info.
|
||||
//
|
||||
memset (&ImageContext, 0, sizeof (ImageContext));
|
||||
ImageContext.Handle = (VOID *) TEBuffer;
|
||||
ImageContext.Handle = (VOID *) TEImageHeader;
|
||||
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
|
||||
|
||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);
|
||||
free (TEBuffer);
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Allocate a buffer for the image to be loaded into.
|
||||
// Don't reload TeImage
|
||||
//
|
||||
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x100000));
|
||||
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);
|
||||
|
||||
ImageContext.ImageAddress = (UINTN) TEImageHeader;
|
||||
|
||||
ImageContext.ImageAddress = MemoryImagePointerAligned;
|
||||
Status = PeCoffLoaderLoadImage (&ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString);
|
||||
free (TEBuffer);
|
||||
free ((VOID *) MemoryImagePointer);
|
||||
return Status;
|
||||
//
|
||||
// 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.CodeView = (VOID *)(UINTN)(
|
||||
ImageContext.ImageAddress +
|
||||
DebugEntry->RVA +
|
||||
sizeof(EFI_TE_IMAGE_HEADER) -
|
||||
TEImageHeader->StrippedSize
|
||||
);
|
||||
|
||||
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);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);
|
||||
free ((VOID *) MemoryImagePointer);
|
||||
free (TEBuffer);
|
||||
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) {
|
||||
TailSize = sizeof (EFI_FFS_FILE_TAIL);
|
||||
} else {
|
||||
|
@ -1206,14 +968,8 @@ Returns:
|
|||
ImageContext.DestinationAddress,
|
||||
ImageContext.PdbPointer == NULL ? "*" : ImageContext.PdbPointer
|
||||
);
|
||||
|
||||
//
|
||||
// Free buffers
|
||||
//
|
||||
free ((VOID *) MemoryImagePointer);
|
||||
free (TEBuffer);
|
||||
}
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue