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 // @@ -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; }