]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
PeCoffGetEntryPointLib: Fix spelling issue
[mirror_edk2.git] / MdePkg / Library / BasePeCoffGetEntryPointLib / PeCoffGetEntryPoint.c
index 0fb7e847b3a7673fd67d4f80c62b5ae4ca847e9a..e1ddc8bafa4124822c123efc282ecf674f96a0b9 100644 (file)
@@ -2,7 +2,7 @@
   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
@@ -22,6 +22,8 @@
 \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
@@ -316,3 +318,71 @@ PeCoffGetSizeOfHeaders (
   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