diff options
-rw-r--r-- | EdkModulePkg/Core/Dxe/DxeMain.h | 12 | ||||
-rw-r--r-- | EdkModulePkg/Core/Pei/Image/Image.c | 2 | ||||
-rw-r--r-- | MdePkg/Include/Common/Dependency.h | 15 | ||||
-rw-r--r-- | MdePkg/Include/Common/FirmwareFileSystem.h | 7 | ||||
-rw-r--r-- | MdePkg/Include/Common/FirmwareVolumeHeader.h | 7 | ||||
-rw-r--r-- | MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 7 | ||||
-rw-r--r-- | Tools/CCode/Source/GenTEImage/GenTEImage.c | 16 | ||||
-rw-r--r-- | Tools/CCode/Source/PeCoffLoader/BasePeCoff.c | 14 | ||||
-rw-r--r-- | Tools/CCode/Source/PeiRebase/PeiRebaseExe.c | 438 |
9 files changed, 146 insertions, 372 deletions
diff --git a/EdkModulePkg/Core/Dxe/DxeMain.h b/EdkModulePkg/Core/Dxe/DxeMain.h index 28c805703a..b38ba8e7f9 100644 --- a/EdkModulePkg/Core/Dxe/DxeMain.h +++ b/EdkModulePkg/Core/Dxe/DxeMain.h @@ -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;
diff --git a/EdkModulePkg/Core/Pei/Image/Image.c b/EdkModulePkg/Core/Pei/Image/Image.c index 377a0d918d..dfe4668c1b 100644 --- a/EdkModulePkg/Core/Pei/Image/Image.c +++ b/EdkModulePkg/Core/Pei/Image/Image.c @@ -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);
diff --git a/MdePkg/Include/Common/Dependency.h b/MdePkg/Include/Common/Dependency.h index d82cefd958..b38dcd5477 100644 --- a/MdePkg/Include/Common/Dependency.h +++ b/MdePkg/Include/Common/Dependency.h @@ -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
diff --git a/MdePkg/Include/Common/FirmwareFileSystem.h b/MdePkg/Include/Common/FirmwareFileSystem.h index 5678a95524..00ce8faff1 100644 --- a/MdePkg/Include/Common/FirmwareFileSystem.h +++ b/MdePkg/Include/Common/FirmwareFileSystem.h @@ -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;
///
diff --git a/MdePkg/Include/Common/FirmwareVolumeHeader.h b/MdePkg/Include/Common/FirmwareVolumeHeader.h index 038dce6f7f..c2bbddf3e9 100644 --- a/MdePkg/Include/Common/FirmwareVolumeHeader.h +++ b/MdePkg/Include/Common/FirmwareVolumeHeader.h @@ -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)
///
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c index ad9c627727..f16ea90ffa 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c @@ -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)) {
diff --git a/Tools/CCode/Source/GenTEImage/GenTEImage.c b/Tools/CCode/Source/GenTEImage/GenTEImage.c index 39b83326e2..665498ac2c 100644 --- a/Tools/CCode/Source/GenTEImage/GenTEImage.c +++ b/Tools/CCode/Source/GenTEImage/GenTEImage.c @@ -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);
diff --git a/Tools/CCode/Source/PeCoffLoader/BasePeCoff.c b/Tools/CCode/Source/PeCoffLoader/BasePeCoff.c index 9c25e1f4b8..f2053b7e38 100644 --- a/Tools/CCode/Source/PeCoffLoader/BasePeCoff.c +++ b/Tools/CCode/Source/PeCoffLoader/BasePeCoff.c @@ -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;
}
}
diff --git a/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c b/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c index c234ccffaa..93acb635f5 100644 --- a/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c +++ b/Tools/CCode/Source/PeiRebase/PeiRebaseExe.c @@ -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
//
@@ -682,6 +677,50 @@ Returns: }
//
+ // 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
//
switch (FfsFile->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
//
@@ -838,47 +811,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
//
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
@@ -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;
}
|