/** @file\r
- Provides the services to get the entry point to a PE/COFF image that has either been \r
+ Provides the services to get the entry point to a PE/COFF image that has either been\r
loaded into memory or is executing at it's linked address.\r
\r
- Copyright (c) 2006 - 2010, Intel Corporation<BR>\r
- Portions copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
#include <IndustryStandard/PeImage.h>\r
\r
+#define PE_COFF_IMAGE_ALIGN_SIZE 4\r
+\r
/**\r
Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded\r
into system memory with the PE/COFF Loader Library functions.\r
If Pe32Data is NULL, then ASSERT().\r
If EntryPoint is NULL, then ASSERT().\r
\r
- @param Pe32Data Pointer to the PE/COFF image that is loaded in system memory.\r
- @param EntryPoint Pointer to entry point to the PE/COFF image to return.\r
+ @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.\r
+ @param EntryPoint The pointer to entry point to the PE/COFF image to return.\r
\r
@retval RETURN_SUCCESS EntryPoint was returned.\r
@retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.\r
Returns the machine type from the PE/COFF image specified by Pe32Data.\r
If Pe32Data is NULL, then ASSERT().\r
\r
- @param Pe32Data Pointer to the PE/COFF image that is loaded in system\r
+ @param Pe32Data The pointer to the PE/COFF image that is loaded in system\r
memory.\r
\r
- @return Machine type or zero if not a valid iamge.\r
+ @return Machine type or zero if not a valid image.\r
\r
**/\r
UINT16\r
\r
/**\r
Returns a pointer to the PDB file name for a PE/COFF image that has been\r
- loaded into system memory with the PE/COFF Loader Library functions. \r
+ loaded into system memory with the PE/COFF Loader Library functions.\r
\r
Returns the PDB file name for the PE/COFF image specified by Pe32Data. If\r
the PE/COFF image specified by Pe32Data is not a valid, then NULL is\r
then NULL is returned.\r
If Pe32Data is NULL, then ASSERT().\r
\r
- @param Pe32Data Pointer to the PE/COFF image that is loaded in system\r
+ @param Pe32Data The pointer to the PE/COFF image that is loaded in system\r
memory.\r
\r
@return The PDB file name for the PE/COFF image specified by Pe32Data or NULL\r
\r
//\r
// Scan the directory to find the debug entry.\r
- // \r
+ //\r
for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {\r
if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
if (DebugEntry->SizeOfData > 0) {\r
Returns the size of the PE/COFF header specified by Pe32Data.\r
If Pe32Data is NULL, then ASSERT().\r
\r
- @param Pe32Data Pointer to the PE/COFF image that is loaded in system\r
+ @param Pe32Data The pointer to the PE/COFF image that is loaded in system\r
memory.\r
\r
- @return Size of PE/COFF header in bytes or zero if not a valid iamge.\r
+ @return Size of PE/COFF header in bytes or zero if not a valid image.\r
\r
**/\r
UINT32\r
UINTN SizeOfHeaders;\r
\r
ASSERT (Pe32Data != NULL);\r
- \r
+\r
DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
//\r
}\r
\r
if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
- SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;\r
+ SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;\r
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
} else {\r
return (UINT32) SizeOfHeaders;\r
}\r
\r
+/**\r
+ Returns PE/COFF image base is loaded in system memory where the input address is in.\r
+\r
+ On DEBUG build, searches the PE/COFF image base forward the input address and\r
+ returns it.\r
+\r
+ @param Address Address located in one PE/COFF image.\r
+\r
+ @retval 0 RELEASE build or cannot find the PE/COFF image base.\r
+ @retval others PE/COFF image base found.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PeCoffSearchImageBase (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ UINTN Pe32Data;\r
+\r
+ Pe32Data = 0;\r
+\r
+ DEBUG_CODE_BEGIN ();\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+\r
+ //\r
+ // Find Image Base\r
+ //\r
+ Pe32Data = Address & ~(PE_COFF_IMAGE_ALIGN_SIZE - 1);\r
+ while (Pe32Data != 0) {\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+ //\r
+ // DOS image header is present, so read the PE header after the DOS image header.\r
+ //\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+ //\r
+ // Make sure PE header address does not overflow and is less than the initial address.\r
+ //\r
+ if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < Address)) {\r
+ if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
+ break;\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // DOS image header is not present, TE header is at the image base.\r
+ //\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
+ if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) &&\r
+ ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || (Hdr.Te->Machine == IMAGE_FILE_MACHINE_IA64) ||\r
+ (Hdr.Te->Machine == IMAGE_FILE_MACHINE_EBC) || (Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64) ||\r
+ (Hdr.Te->Machine == IMAGE_FILE_MACHINE_ARM64) || (Hdr.Te->Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED))\r
+ ) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Not found the image base, check the previous aligned address\r
+ //\r
+ Pe32Data -= PE_COFF_IMAGE_ALIGN_SIZE;\r
+ }\r
+ DEBUG_CODE_END ();\r
+\r
+ return Pe32Data;\r
+}\r