]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BasePeCoffGetEntryPointLib / PeCoffGetEntryPoint.c
index 0fb7e847b3a7673fd67d4f80c62b5ae4ca847e9a..00b645a1011ad0a309d9db5e08e1c349c86dd48b 100644 (file)
@@ -1,20 +1,13 @@
 /** @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. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2018, 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
-  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
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-\r
 #include <Base.h>\r
 \r
 #include <Library/PeCoffGetEntryPointLib.h>\r
@@ -22,6 +15,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
@@ -46,8 +41,8 @@ PeCoffLoaderGetEntryPoint (
   OUT VOID  **EntryPoint\r
   )\r
 {\r
-  EFI_IMAGE_DOS_HEADER                  *DosHdr;\r
-  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
+  EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;\r
 \r
   ASSERT (Pe32Data   != NULL);\r
   ASSERT (EntryPoint != NULL);\r
@@ -57,7 +52,7 @@ PeCoffLoaderGetEntryPoint (
     //\r
     // DOS image header is present, so read the PE header after the DOS image header.\r
     //\r
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));\r
   } else {\r
     //\r
     // DOS image header is not present, so PE header is at the image base.\r
@@ -70,7 +65,7 @@ PeCoffLoaderGetEntryPoint (
   // AddressOfEntryPoint is common for PE32 & PE32+\r
   //\r
   if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
-    *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);\r
+    *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);\r
     return RETURN_SUCCESS;\r
   } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
     *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));\r
@@ -80,7 +75,6 @@ PeCoffLoaderGetEntryPoint (
   return RETURN_UNSUPPORTED;\r
 }\r
 \r
-\r
 /**\r
   Returns the machine type of a PE/COFF image.\r
 \r
@@ -109,7 +103,7 @@ PeCoffLoaderGetMachineType (
     //\r
     // DOS image header is present, so read the PE header after the DOS image header.\r
     //\r
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));\r
   } else {\r
     //\r
     // DOS image header is not present, so PE header is at the image base.\r
@@ -119,7 +113,7 @@ PeCoffLoaderGetMachineType (
 \r
   if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
     return Hdr.Te->Machine;\r
-  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE)  {\r
+  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
     return Hdr.Pe32->FileHeader.Machine;\r
   }\r
 \r
@@ -128,7 +122,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
@@ -151,15 +145,15 @@ PeCoffLoaderGetPdbPointer (
   IN VOID  *Pe32Data\r
   )\r
 {\r
-  EFI_IMAGE_DOS_HEADER                  *DosHdr;\r
-  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
-  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;\r
-  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;\r
-  UINTN                                 DirCount;\r
-  VOID                                  *CodeViewEntryPointer;\r
-  INTN                                  TEImageAdjust;\r
-  UINT32                                NumberOfRvaAndSizes;\r
-  UINT16                                Magic;\r
+  EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;\r
+  EFI_IMAGE_DATA_DIRECTORY             *DirectoryEntry;\r
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY      *DebugEntry;\r
+  UINTN                                DirCount;\r
+  VOID                                 *CodeViewEntryPointer;\r
+  INTN                                 TEImageAdjust;\r
+  UINT32                               NumberOfRvaAndSizes;\r
+  UINT16                               Magic;\r
 \r
   ASSERT (Pe32Data   != NULL);\r
 \r
@@ -173,7 +167,7 @@ PeCoffLoaderGetPdbPointer (
     //\r
     // DOS image header is present, so read the PE header after the DOS image header.\r
     //\r
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));\r
   } else {\r
     //\r
     // DOS image header is not present, so PE header is at the image base.\r
@@ -183,11 +177,11 @@ PeCoffLoaderGetPdbPointer (
 \r
   if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
     if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
-      DirectoryEntry  = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
-      TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
-      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +\r
-                    Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
-                    TEImageAdjust);\r
+      DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
+      TEImageAdjust  = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
+      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN)Hdr.Te +\r
+                                                           Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
+                                                           TEImageAdjust);\r
     }\r
   } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
     //\r
@@ -196,24 +190,24 @@ PeCoffLoaderGetPdbPointer (
     //       generate PE32+ image with PE32 Magic.\r
     //\r
     switch (Hdr.Pe32->FileHeader.Machine) {\r
-    case IMAGE_FILE_MACHINE_I386:\r
-      //\r
-      // Assume PE32 image with IA32 Machine field.\r
-      //\r
-      Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
-      break;\r
-    case IMAGE_FILE_MACHINE_X64:\r
-    case IMAGE_FILE_MACHINE_IA64:\r
-      //\r
-      // Assume PE32+ image with x64 or IA64 Machine field\r
-      //\r
-      Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
-      break;\r
-    default:\r
-      //\r
-      // For unknow Machine field, use Magic in optional Header\r
-      //\r
-      Magic = Hdr.Pe32->OptionalHeader.Magic;\r
+      case IMAGE_FILE_MACHINE_I386:\r
+        //\r
+        // Assume PE32 image with IA32 Machine field.\r
+        //\r
+        Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
+        break;\r
+      case IMAGE_FILE_MACHINE_X64:\r
+      case IMAGE_FILE_MACHINE_IA64:\r
+        //\r
+        // Assume PE32+ image with x64 or IA64 Machine field\r
+        //\r
+        Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+        break;\r
+      default:\r
+        //\r
+        // For unknow Machine field, use Magic in optional Header\r
+        //\r
+        Magic = Hdr.Pe32->OptionalHeader.Magic;\r
     }\r
 \r
     if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
@@ -221,45 +215,45 @@ PeCoffLoaderGetPdbPointer (
       // Use PE32 offset get Debug Directory Entry\r
       //\r
       NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
-      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
-      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
+      DirectoryEntry      = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+      DebugEntry          = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN)Pe32Data + DirectoryEntry->VirtualAddress);\r
     } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
       //\r
       // Use PE32+ offset get Debug Directory Entry\r
       //\r
       NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
-      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
-      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
+      DirectoryEntry      = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+      DebugEntry          = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN)Pe32Data + DirectoryEntry->VirtualAddress);\r
     }\r
 \r
     if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
       DirectoryEntry = NULL;\r
-      DebugEntry = NULL;\r
+      DebugEntry     = NULL;\r
     }\r
   } else {\r
     return NULL;\r
   }\r
 \r
-  if (DebugEntry == NULL || DirectoryEntry == NULL) {\r
+  if ((DebugEntry == NULL) || (DirectoryEntry == NULL)) {\r
     return NULL;\r
   }\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
-        CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);\r
-        switch (* (UINT32 *) CodeViewEntryPointer) {\r
-        case CODEVIEW_SIGNATURE_NB10:\r
-          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));\r
-        case CODEVIEW_SIGNATURE_RSDS:\r
-          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));\r
-        case CODEVIEW_SIGNATURE_MTOC:\r
-          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));\r
-        default:\r
-          break;\r
+        CodeViewEntryPointer = (VOID *)((UINTN)DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);\r
+        switch (*(UINT32 *)CodeViewEntryPointer) {\r
+          case CODEVIEW_SIGNATURE_NB10:\r
+            return (VOID *)((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));\r
+          case CODEVIEW_SIGNATURE_RSDS:\r
+            return (VOID *)((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));\r
+          case CODEVIEW_SIGNATURE_MTOC:\r
+            return (VOID *)((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));\r
+          default:\r
+            break;\r
         }\r
       }\r
     }\r
@@ -283,21 +277,21 @@ PeCoffLoaderGetPdbPointer (
 UINT32\r
 EFIAPI\r
 PeCoffGetSizeOfHeaders (\r
-  IN VOID     *Pe32Data\r
+  IN VOID  *Pe32Data\r
   )\r
 {\r
-  EFI_IMAGE_DOS_HEADER                  *DosHdr;\r
-  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
-  UINTN                                 SizeOfHeaders;\r
+  EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;\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
     // DOS image header is present, so read the PE header after the DOS image header.\r
     //\r
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));\r
   } else {\r
     //\r
     // DOS image header is not present, so PE header is at the image base.\r
@@ -313,6 +307,76 @@ PeCoffGetSizeOfHeaders (
     SizeOfHeaders = 0;\r
   }\r
 \r
-  return (UINT32) SizeOfHeaders;\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
+      {\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
+  DEBUG_CODE_END ();\r
+\r
+  return Pe32Data;\r
+}\r