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. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\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
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 (\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
+ );\r
+\r
+ return Pe32Data;\r
+}\r