]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Core/Pei/Image/Image.c
1. PEI core needs to check image machine type
[mirror_edk2.git] / EdkModulePkg / Core / Pei / Image / Image.c
index 5edc8479eb04ca4aadd31c43ca684952f07a8a88..202936869b62eb4b2f9417f4b5dc6562d76f934c 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \r
+Copyright (c) 2006 - 2007, Intel Corporation                                                         \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
@@ -21,6 +21,8 @@ Abstract:
 \r
 #include <PeiMain.h>\r
 \r
+\r
+\r
 EFI_STATUS\r
 PeiLoadImage (\r
   IN EFI_PEI_SERVICES         **PeiServices,\r
@@ -54,6 +56,7 @@ Returns:
   UINT64                      ImageSize;\r
   EFI_PHYSICAL_ADDRESS        ImageEntryPoint;\r
   EFI_TE_IMAGE_HEADER         *TEImageHeader;\r
+  UINT16                      Machine;\r
 \r
   *EntryPoint   = NULL;\r
   TEImageHeader = NULL;\r
@@ -103,16 +106,16 @@ Returns:
       }\r
 \r
       //\r
-      // Got the entry point from ImageEntryPoint\r
+      // Got the entry point from ImageEntryPoint and ImageStartAddress\r
       //\r
+      Pe32Data    = (VOID *) ((UINTN) ImageAddress);\r
       *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);\r
-      return EFI_SUCCESS;\r
     } else {\r
       //\r
       // Retrieve the entry point from the TE image header\r
       //\r
       ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;\r
-      *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
+      *EntryPoint  = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
                     TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);\r
     }\r
   } else {\r
@@ -126,40 +129,49 @@ Returns:
     }\r
   }\r
 \r
+  if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+    TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress;\r
+    Machine = TEImageHeader->Machine;\r
+  } else {\r
+    Machine = PeCoffLoaderGetMachineType (Pe32Data);\r
+  } \r
+  \r
+  if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {\r
+    return EFI_UNSUPPORTED;  \r
+  }\r
+\r
   //\r
   // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
   //\r
-  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", Pe32Data, *EntryPoint));\r
-  DEBUG_CODE (\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_NT_HEADERS  *PeHeader;\r
+  DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));\r
+  DEBUG_CODE_BEGIN ();\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
-    //\r
-    // Pe32Data is NULL when load TE image \r
-    //    \r
-    PeHeader = NULL;\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
-        PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));\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
-        PeHeader = (EFI_IMAGE_NT_HEADERS *) Pe32Data;\r
+        Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
       }\r
     }\r
 \r
@@ -171,13 +183,31 @@ Returns:
     // 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
+    DebugEntry          = NULL;\r
+    DirectoryEntry      = NULL;\r
+    NumberOfRvaAndSizes = 0;\r
+    TEImageAdjust       = 0;\r
+    \r
     if (TEImageHeader == NULL) {\r
-      if (PeHeader->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
-        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHeader->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
-        DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) ImageAddress + DirectoryEntry->VirtualAddress);\r
+      if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+        //     \r
+        // 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
+      } 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
+      }\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
@@ -190,17 +220,17 @@ Returns:
     }\r
 \r
     if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
-      for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {\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) ImageAddress + (UINTN)TEImageAdjust);\r
             switch (* (UINT32 *) CodeViewEntryPointer) {\r
               case CODEVIEW_SIGNATURE_NB10:\r
-                AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\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
+                AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
                 break;\r
 \r
               default:\r
@@ -209,7 +239,7 @@ Returns:
             }\r
             if (AsciiString != NULL) {\r
               FileNameFound = FALSE;\r
-              for (Index = 0, Index1 = 0; AsciiString[Index] != 0; Index++) {\r
+              for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) {\r
                 if (AsciiString[Index] == '\\') {\r
                   Index1 = Index;\r
                   FileNameFound = TRUE;\r
@@ -229,7 +259,7 @@ Returns:
         }\r
       }\r
     }\r
-  );\r
+  DEBUG_CODE_END ();\r
 \r
   DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
 \r