]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
MdePkg: Change complex DEBUG_CODE() to DEBUG_CODE_BEGIN/END()
[mirror_edk2.git] / MdePkg / Library / BasePeCoffGetEntryPointLib / PeCoffGetEntryPoint.c
index a3c117feb33bf22b5e60f09706b4058f7951f1a5..cf10fc5fe42e47ddb4f8eea4a8771e6f3cb37b1d 100644 (file)
@@ -1,16 +1,10 @@
 /** @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
@@ -22,6 +16,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
@@ -32,8 +28,8 @@
   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
@@ -87,10 +83,10 @@ PeCoffLoaderGetEntryPoint (
   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
@@ -128,7 +124,7 @@ PeCoffLoaderGetMachineType (
 \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
@@ -138,7 +134,7 @@ PeCoffLoaderGetMachineType (
   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
@@ -246,7 +242,7 @@ PeCoffLoaderGetPdbPointer (
 \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
@@ -274,10 +270,10 @@ PeCoffLoaderGetPdbPointer (
   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
@@ -291,7 +287,7 @@ PeCoffGetSizeOfHeaders (
   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
@@ -306,7 +302,7 @@ PeCoffGetSizeOfHeaders (
   }\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
@@ -316,3 +312,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_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