break;\r
}\r
}\r
+\r
//\r
// Open the file containing the FV\r
//\r
Version();\r
\r
printf (\r
- "\nUsage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",\r
+ "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-F InputFvInfName]\n",\r
UTILITY_NAME\r
);\r
+ printf (" [-D BootDriverBaseAddress] [-R RuntimeDriverBaseAddress]\n");\r
printf (" Where:\n");\r
- printf (" InputFileName is the name of the EFI FV file to rebase.\n");\r
- printf (" OutputFileName is the desired output file name.\n");\r
- printf (" BaseAddress is the FV base address to rebase agains.\n");\r
- printf (" Argument pair may be in any order.\n");\r
+ printf (" InputFileName is the name of the EFI FV file to rebase.\n");\r
+ printf (" OutputFileName is the desired output file name.\n");\r
+ printf (" BaseAddress is the rebase address for all drivers run in Flash.\n");\r
+ printf (" InputFvInfName is the Fv.inf file that contains this FV base address to rebase against.\n");\r
+ printf (" BootDriverBaseAddress is the rebase address for all boot drivers in this fv image.\n");\r
+ printf (" RuntimeDriverBaseAddress is the rebase address for all runtime drivers in this fv image.\n");\r
+ printf (" Argument pair may be in any order.\n\n");\r
}\r
\r
EFI_STATUS\r
{\r
EFI_STATUS Status;\r
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
- UINTN MemoryImagePointer;\r
- UINTN MemoryImagePointerAligned;\r
- EFI_PHYSICAL_ADDRESS ImageAddress;\r
- UINT64 ImageSize;\r
- EFI_PHYSICAL_ADDRESS EntryPoint;\r
- UINT32 Pe32ImageSize;\r
EFI_PHYSICAL_ADDRESS NewPe32BaseAddress;\r
UINTN Index;\r
EFI_FILE_SECTION_POINTER CurrentPe32Section;\r
EFI_FFS_FILE_STATE SavedState;\r
EFI_IMAGE_NT_HEADERS32 *PeHdr;\r
- EFI_IMAGE_NT_HEADERS64 *PePlusHdr;\r
- UINT32 *PeHdrSizeOfImage;\r
- UINT32 *PeHdrChecksum;\r
EFI_TE_IMAGE_HEADER *TEImageHeader;\r
- UINT8 *TEBuffer;\r
- EFI_IMAGE_DOS_HEADER *DosHeader;\r
UINT8 FileGuidString[80];\r
UINT32 TailSize;\r
EFI_FFS_FILE_TAIL TailValue;\r
EFI_PHYSICAL_ADDRESS *BaseToUpdate;\r
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
+ \r
\r
//\r
// Verify input parameters\r
break;\r
}\r
\r
-\r
//\r
// Initialize context\r
//\r
return Status;\r
}\r
\r
+ //\r
+ // Don't Load PeImage, only to relocate current image.\r
+ //\r
+ ImageContext.ImageAddress = (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION);\r
+\r
+ //\r
+ // Check if section-alignment and file-alignment match or not\r
+ //\r
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);\r
+ if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {\r
+ //\r
+ // Nor XIP module can be ignored. \r
+ //\r
+ if ((Flags & 1) == 0) {\r
+ continue;\r
+ }\r
+ Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);\r
+ return EFI_ABORTED;\r
+ } \r
+\r
+ //\r
+ // Update CodeView and PdbPointer in ImageContext\r
+ //\r
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
+ ImageContext.ImageAddress +\r
+ ImageContext.DebugDirectoryEntryRva\r
+ );\r
+ ImageContext.CodeView = (VOID *)(UINTN)( \r
+ ImageContext.ImageAddress + \r
+ DebugEntry->RVA\r
+ );\r
+ switch (*(UINT32 *) ImageContext.CodeView) {\r
+ case CODEVIEW_SIGNATURE_NB10:\r
+ ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+ break;\r
+\r
+ case CODEVIEW_SIGNATURE_RSDS:\r
+ ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
//\r
// Calculate the PE32 base address, based on file type\r
//\r
}\r
\r
NewPe32BaseAddress =\r
- XipBase +\r
- (UINTN)CurrentPe32Section.Pe32Section +\r
- sizeof (EFI_COMMON_SECTION_HEADER) -\r
- (UINTN)FfsFile;\r
+ XipBase + (UINTN)ImageContext.ImageAddress - (UINTN)FfsFile;\r
BaseToUpdate = &XipBase;\r
break;\r
\r
case EFI_FV_FILETYPE_DRIVER:\r
- PeHdr = (EFI_IMAGE_NT_HEADERS32*)(\r
- (UINTN)CurrentPe32Section.Pe32Section +\r
- sizeof (EFI_COMMON_SECTION_HEADER) +\r
- ImageContext.PeCoffHeaderOffset\r
- );\r
+ PeHdr = (EFI_IMAGE_NT_HEADERS32*)(ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);\r
switch (PeHdr->OptionalHeader.Subsystem) {\r
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
if ((Flags & 4) == 0) {\r
return EFI_SUCCESS;\r
}\r
\r
- //\r
- // Allocate a buffer for the image to be loaded into.\r
- //\r
- Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);\r
- MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x100000));\r
- if (MemoryImagePointer == 0) {\r
- Error (NULL, 0, 0, "memory allocation failure", NULL);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x100000);\r
- MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);\r
-\r
- ImageContext.ImageAddress = MemoryImagePointerAligned;\r
-\r
- Status = PeCoffLoaderLoadImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
- }\r
- \r
- //\r
- // Check if section-alignment and file-alignment match or not\r
- //\r
- if (!(ImageContext.IsTeImage)) {\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress + \r
- ImageContext.PeCoffHeaderOffset);\r
- if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {\r
- Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);\r
- free ((VOID *) MemoryImagePointer);\r
- return EFI_ABORTED;\r
- }\r
- }\r
- else {\r
- //\r
- // BUGBUG: TE Image Header lack section-alignment and file-alignment info\r
- //\r
- }\r
-\r
ImageContext.DestinationAddress = NewPe32BaseAddress;\r
Status = PeCoffLoaderRelocateImage (&ImageContext);\r
if (EFI_ERROR (Status)) {\r
Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);\r
- free ((VOID *) MemoryImagePointer);\r
return Status;\r
}\r
\r
- ImageAddress = ImageContext.ImageAddress;\r
- ImageSize = ImageContext.ImageSize;\r
- EntryPoint = ImageContext.EntryPoint;\r
-\r
- if (ImageSize > Pe32ImageSize) {\r
- Error (\r
- NULL,\r
- 0,\r
- 0,\r
- "rebased image is larger than original PE32 image",\r
- "0x%X > 0x%X, file %s",\r
- ImageSize,\r
- Pe32ImageSize,\r
- FileGuidString\r
- );\r
- free ((VOID *) MemoryImagePointer);\r
- return EFI_ABORTED;\r
- }\r
-\r
//\r
// Update BASE address\r
//\r
);\r
*BaseToUpdate += EFI_SIZE_TO_PAGES (ImageContext.ImageSize) * EFI_PAGE_SIZE;\r
\r
- //\r
- // Since we may have updated the Codeview RVA, we need to insure the PE\r
- // header indicates the image is large enough to contain the Codeview data\r
- // so it will be loaded properly later if the PEIM is reloaded into memory...\r
- //\r
- PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
- PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
- if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
- PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);\r
- PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);\r
- } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
- PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
- PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
- } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
- PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
- PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
- } else {\r
- Error (\r
- NULL,\r
- 0,\r
- 0,\r
- "unknown machine type in PE32 image",\r
- "machine type=0x%X, file=%s",\r
- (UINT32) PeHdr->FileHeader.Machine,\r
- FileGuidString\r
- );\r
- free ((VOID *) MemoryImagePointer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (*PeHdrSizeOfImage != ImageContext.ImageSize) {\r
- *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;\r
- if (*PeHdrChecksum) {\r
- *PeHdrChecksum = 0;\r
- }\r
- }\r
-\r
- memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);\r
-\r
- free ((VOID *) MemoryImagePointer);\r
-\r
//\r
// Now update file checksum\r
//\r
//\r
return EFI_SUCCESS;\r
}\r
-\r
+ \r
//\r
// Now process TE sections\r
//\r
//\r
TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
\r
- NewPe32BaseAddress = ((UINT32) XipBase) +\r
- (\r
- (UINTN) CurrentPe32Section.Pe32Section +\r
- sizeof (EFI_COMMON_SECTION_HEADER) +\r
- sizeof (EFI_TE_IMAGE_HEADER) -\r
- TEImageHeader->StrippedSize -\r
- (UINTN) FfsFile\r
- );\r
-\r
- //\r
- // Allocate a buffer to unshrink the image into.\r
- //\r
- Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
- sizeof (EFI_TE_IMAGE_HEADER);\r
- Pe32ImageSize += TEImageHeader->StrippedSize;\r
- TEBuffer = (UINT8 *) malloc (Pe32ImageSize);\r
- if (TEBuffer == NULL) {\r
- Error (NULL, 0, 0, "failed to allocate memory", NULL);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Expand the image into our buffer and fill in critical fields in the DOS header\r
- // Fill in fields required by the loader.\r
- // At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value\r
- // itself.\r
- //\r
- memset (TEBuffer, 0, Pe32ImageSize);\r
- DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer;\r
- DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
- *(UINT32 *) (TEBuffer + 0x3C) = 0x40;\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);\r
- PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
- PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;\r
- PeHdr->FileHeader.Machine = TEImageHeader->Machine;\r
- PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;\r
-\r
//\r
- // 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\r
- // the 0x40 bytes for our DOS header.\r
- //\r
- PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));\r
- if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA32) {\r
- PeHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {\r
- PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_X64) {\r
- PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- } else {\r
- Error (\r
- NULL,\r
- 0,\r
- 0,\r
- "unknown machine type in TE image",\r
- "machine type=0x%X, file=%s",\r
- (UINT32) TEImageHeader->Machine,\r
- FileGuidString\r
- );\r
- free (TEBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
- PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
- PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;\r
- PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *\r
- sizeof (EFI_IMAGE_SECTION_HEADER) - 12;\r
-\r
- //\r
- // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image\r
- //\r
- if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||\r
- (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)\r
- ) {\r
- PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;\r
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
- }\r
-\r
- if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||\r
- (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)\r
- ) {\r
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
- PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
- if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {\r
- PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;\r
- }\r
- }\r
- //\r
- // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility\r
- //\r
- PeHdr->OptionalHeader.SectionAlignment = 0x10;\r
- } else {\r
- PePlusHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
- PePlusHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
- PePlusHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;\r
- PePlusHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *\r
- sizeof (EFI_IMAGE_SECTION_HEADER) - 12;\r
-\r
- //\r
- // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image\r
- //\r
- if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||\r
- (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)\r
- ) {\r
- PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;\r
- PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
- PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
- }\r
-\r
- if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||\r
- (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)\r
- ) {\r
- PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
- PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
- if (PePlusHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {\r
- PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;\r
- }\r
- }\r
- //\r
- // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility\r
- //\r
- PePlusHdr->OptionalHeader.SectionAlignment = 0x10;\r
- }\r
-\r
- //\r
- // Copy the rest of the image to its original offset\r
- //\r
- memcpy (\r
- TEBuffer + TEImageHeader->StrippedSize,\r
- (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER),\r
- GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
- sizeof (EFI_TE_IMAGE_HEADER)\r
- );\r
-\r
- //\r
- // Initialize context\r
+ // Initialize context, load image info.\r
//\r
memset (&ImageContext, 0, sizeof (ImageContext));\r
- ImageContext.Handle = (VOID *) TEBuffer;\r
+ ImageContext.Handle = (VOID *) TEImageHeader;\r
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
\r
Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
\r
if (EFI_ERROR (Status)) {\r
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);\r
- free (TEBuffer);\r
return Status;\r
}\r
//\r
- // Allocate a buffer for the image to be loaded into.\r
+ // Don't reload TeImage\r
//\r
- MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x100000));\r
- if (MemoryImagePointer == 0) {\r
- Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);\r
- free (TEBuffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x100000);\r
- MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);\r
- \r
+ ImageContext.ImageAddress = (UINTN) TEImageHeader;\r
\r
- ImageContext.ImageAddress = MemoryImagePointerAligned;\r
- Status = PeCoffLoaderLoadImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString);\r
- free (TEBuffer);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
+ //\r
+ // Update CodeView and PdbPointer in ImageContext\r
+ //\r
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
+ ImageContext.ImageAddress +\r
+ ImageContext.DebugDirectoryEntryRva +\r
+ sizeof(EFI_TE_IMAGE_HEADER) -\r
+ TEImageHeader->StrippedSize\r
+ );\r
+\r
+ ImageContext.CodeView = (VOID *)(UINTN)(\r
+ ImageContext.ImageAddress +\r
+ DebugEntry->RVA +\r
+ sizeof(EFI_TE_IMAGE_HEADER) -\r
+ TEImageHeader->StrippedSize\r
+ );\r
+\r
+ switch (*(UINT32 *) ImageContext.CodeView) {\r
+ case CODEVIEW_SIGNATURE_NB10:\r
+ ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+ break;\r
+\r
+ case CODEVIEW_SIGNATURE_RSDS:\r
+ ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+ break;\r
+\r
+ default:\r
+ break;\r
}\r
\r
- ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+ //\r
+ // Reloacate TeImage\r
+ // \r
+ ImageContext.DestinationAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \\r
+ - TEImageHeader->StrippedSize - (UINTN) FfsFile;\r
Status = PeCoffLoaderRelocateImage (&ImageContext);\r
if (EFI_ERROR (Status)) {\r
Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);\r
- free ((VOID *) MemoryImagePointer);\r
- free (TEBuffer);\r
return Status;\r
}\r
\r
- ImageAddress = ImageContext.ImageAddress;\r
- ImageSize = ImageContext.ImageSize;\r
- EntryPoint = ImageContext.EntryPoint;\r
-\r
- //\r
- // Since we may have updated the Codeview RVA, we need to insure the PE\r
- // header indicates the image is large enough to contain the Codeview data\r
- // so it will be loaded properly later if the PEIM is reloaded into memory...\r
- //\r
- PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
- PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
- if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
- PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);\r
- PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);\r
- } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
- PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
- PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
- } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
- PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
- PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
- } else {\r
- Error (\r
- NULL,\r
- 0,\r
- 0,\r
- "unknown machine type in TE image",\r
- "machine type=0x%X, file=%s",\r
- (UINT32) PeHdr->FileHeader.Machine,\r
- FileGuidString\r
- );\r
- free ((VOID *) MemoryImagePointer);\r
- free (TEBuffer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (*PeHdrSizeOfImage != ImageContext.ImageSize) {\r
- *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;\r
- if (*PeHdrChecksum) {\r
- *PeHdrChecksum = 0;\r
- }\r
- }\r
-\r
- TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
- memcpy (\r
- (UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER),\r
- (VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize),\r
- GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
- sizeof (EFI_TE_IMAGE_HEADER)\r
- );\r
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
TailSize = sizeof (EFI_FFS_FILE_TAIL);\r
} else {\r
ImageContext.DestinationAddress,\r
ImageContext.PdbPointer == NULL ? "*" : ImageContext.PdbPointer\r
);\r
-\r
- //\r
- // Free buffers\r
- //\r
- free ((VOID *) MemoryImagePointer);\r
- free (TEBuffer);\r
}\r
-\r
+ \r
return EFI_SUCCESS;\r
}\r
\r