]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Core/Pei/Image/Image.c
Add temporary fix for PeLoader
[mirror_edk2.git] / EdkModulePkg / Core / Pei / Image / Image.c
index 9df12f8ab3ef3f0da77fcffc658249293522718e..32f0fe652300822d1f1e58d7d5a5da673d9baa19 100644 (file)
@@ -133,33 +133,116 @@ Returns:
   //\r
   DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", Pe32Data, *EntryPoint));\r
   DEBUG_CODE_BEGIN ();\r
-    PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;\r
-    UINTN                                 Index;\r
-    CHAR8                                 *PdbStr;\r
-    CHAR8                                 AsciiBuffer[512];\r
-\r
+    EFI_IMAGE_DATA_DIRECTORY            *DirectoryEntry;\r
+    EFI_IMAGE_DEBUG_DIRECTORY_ENTRY     *DebugEntry;\r
+    UINTN                               DirCount;\r
+    UINTN                               Index;\r
+    UINTN                               Index1;\r
+    BOOLEAN                             FileNameFound;\r
+    CHAR8                               *AsciiString;\r
+    CHAR8                               AsciiBuffer[512];\r
+    VOID                                *CodeViewEntryPointer;\r
+    INTN                                TEImageAdjust;\r
+    EFI_IMAGE_DOS_HEADER                *DosHeader;\r
+    EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+    UINT32                              NumberOfRvaAndSizes;\r
+\r
+    Hdr.Pe32 = NULL;\r
+    if (TEImageHeader == NULL) {\r
+      DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
+      if (DosHeader->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)((DosHeader->e_lfanew) & 0x0ffff));\r
+      } else {\r
+        //\r
+        // DOS image header is not present, so PE header is at the image base\r
+        //\r
+        Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
+      }\r
+    }\r
 \r
-    ZeroMem (&ImageContext, sizeof (ImageContext));\r
-    ImageContext.Handle    = Pe32Data;\r
-    ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
+    //\r
+    // Find the codeview info in the image and display the file name\r
+    // being loaded.\r
+    //\r
+    // Per the PE/COFF spec, you can't assume that a given data directory\r
+    // is present in the image. You have to check the NumberOfRvaAndSizes in\r
+    // the optional header to verify a desired directory entry is there.\r
+    //\r
+    DebugEntry      = NULL;\r
+    DirectoryEntry  = NULL;\r
+    TEImageAdjust   = 0;\r
+    if (TEImageHeader == NULL) {\r
+      if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+        //     \r
+        // Use PE32 offset\r
+        //\r
+        NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+      } else {\r
+        //     \r
+        // Use PE32+ offset\r
+        //\r
+        NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+      }    \r
+\r
+      if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+        DirectoryEntry = NULL;\r
+        DebugEntry = NULL;\r
+      }\r
+    } else {\r
+      if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
+        DirectoryEntry  = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
+        TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;\r
+        DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +\r
+                      TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
+                      TEImageAdjust);\r
+      }\r
+    }\r
 \r
-    PeCoffLoaderGetImageInfo (&ImageContext);\r
-    \r
-    if (ImageContext.PdbPointer != NULL) {\r
-      //\r
-      // Copy PDB pointer to AsciiBuffer and replace .PDB with .EFI\r
-      //\r
-      PdbStr = ImageContext.PdbPointer;\r
-      for (Index = 0; PdbStr != 0; Index++, PdbStr++) {\r
-        AsciiBuffer[Index] = *PdbStr;\r
-        if (*PdbStr == '.') {\r
-          AsciiBuffer[Index] = '\0';  \r
+    if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
+      for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {\r
+        if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+          if (DebugEntry->SizeOfData > 0) {\r
+            CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);\r
+            switch (* (UINT32 *) CodeViewEntryPointer) {\r
+              case CODEVIEW_SIGNATURE_NB10:\r
+                AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+                break;\r
+\r
+              case CODEVIEW_SIGNATURE_RSDS:\r
+                AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+                break;\r
+\r
+              default:\r
+                AsciiString = NULL;\r
+                break;\r
+            }\r
+            if (AsciiString != NULL) {\r
+              FileNameFound = FALSE;\r
+              for (Index = 0, Index1 = 0; (AsciiString[Index] != 0) && (Index < sizeof (AsciiString)); Index++) {\r
+                if (AsciiString[Index] == '\\') {\r
+                  Index1 = Index;\r
+                  FileNameFound = TRUE;\r
+                }\r
+              }\r
+\r
+              if (FileNameFound) {\r
+                for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {\r
+                  AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];\r
+                }\r
+                AsciiBuffer[Index - (Index1 + 1)] = 0;\r
+                DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
+                break;\r
+              }\r
+            }\r
+          }\r
         }\r
       }\r
-      \r
-      DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
     }\r
-\r
   DEBUG_CODE_END ();\r
 \r
   DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r