]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Image/Image.c
Produce LoadPeImage protocol only in framework compatibility mode.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Image / Image.c
index 4826a959f8a5454c7d3528c6c4656cc0eb472304..7e5cea7b76ad2d27a861e59f52d51c8f72febb4f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Core image handling services to load and unload PeImage.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
+Copyright (c) 2006 - 2009, Intel Corporation. <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
@@ -13,12 +13,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "DxeMain.h"\r
+#include "Image.h"\r
+\r
 //\r
 // Module Globals\r
 //\r
-\r
-SPIN_LOCK                  mUnloadImageLock;\r
-\r
 LOADED_IMAGE_PRIVATE_DATA  *mCurrentImage = NULL;\r
 \r
 LOAD_PE32_IMAGE_PRIVATE_DATA  mLoadPe32PrivateData = {\r
@@ -139,28 +138,70 @@ CoreInitializeImageServices (
 \r
   mCurrentImage = Image;\r
 \r
-  //\r
-  // Initialize spin lock\r
-  //\r
-  InitializeSpinLock (&mUnloadImageLock);\r
-\r
   //\r
   // Fill in DXE globals\r
   //\r
   gDxeCoreImageHandle = Image->Handle;\r
   gDxeCoreLoadedImage = &Image->Info;\r
 \r
+  if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
+    //\r
+    // Export DXE Core PE Loader functionality for backward compatibility.\r
+    //\r
+    Status = CoreInstallProtocolInterface (\r
+      &mLoadPe32PrivateData.Handle,\r
+      &gEfiLoadPeImageProtocolGuid,\r
+      EFI_NATIVE_INTERFACE,\r
+      &mLoadPe32PrivateData.Pe32Image\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Read image file (specified by UserHandle) into user specified buffer with specified offset\r
+  and length.\r
+\r
+  @param  UserHandle             Image file handle\r
+  @param  Offset                 Offset to the source file\r
+  @param  ReadSize               For input, pointer of size to read; For output,\r
+                                 pointer of size actually read.\r
+  @param  Buffer                 Buffer to write into\r
+\r
+  @retval EFI_SUCCESS            Successfully read the specified part of file\r
+                                 into buffer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreReadImageFile (\r
+  IN     VOID    *UserHandle,\r
+  IN     UINTN   Offset,\r
+  IN OUT UINTN   *ReadSize,\r
+  OUT    VOID    *Buffer\r
+  )\r
+{\r
+  UINTN               EndPosition;\r
+  IMAGE_FILE_HANDLE  *FHand;\r
+\r
+  FHand = (IMAGE_FILE_HANDLE  *)UserHandle;\r
+  ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);\r
+\r
   //\r
-  // Export DXE Core PE Loader functionality\r
+  // Move data from our local copy of the file\r
   //\r
-  return CoreInstallProtocolInterface (\r
-           &mLoadPe32PrivateData.Handle,\r
-           &gEfiLoadPeImageProtocolGuid,\r
-           EFI_NATIVE_INTERFACE,\r
-           &mLoadPe32PrivateData.Pe32Image\r
-           );\r
-}\r
+  EndPosition = Offset + *ReadSize;\r
+  if (EndPosition > FHand->SourceSize) {\r
+    *ReadSize = (UINT32)(FHand->SourceSize - Offset);\r
+  }\r
+  if (Offset >= FHand->SourceSize) {\r
+      *ReadSize = 0;\r
+  }\r
 \r
+  CopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Loads, relocates, and invokes a PE/COFF image\r
@@ -196,11 +237,7 @@ CoreLoadPeImage (
   EFI_STATUS                Status;\r
   BOOLEAN                   DstBufAlocated;\r
   UINTN                     Size;\r
-  UINTN                     LinkTimeBase;\r
-  EFI_TCG_PLATFORM_PROTOCOL *TcgPlatformProtocol;\r
-  IMAGE_FILE_HANDLE         *FHandle;\r
 \r
-  FHandle = NULL;\r
   ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext));\r
 \r
   Image->ImageContext.Handle    = Pe32Handle;\r
@@ -245,10 +282,6 @@ CoreLoadPeImage (
     Image->ImageContext.ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;\r
     return EFI_UNSUPPORTED;\r
   }\r
-  //\r
-  // Get the image base address in the original PeImage.\r
-  //\r
-  LinkTimeBase = (UINTN) Image->ImageContext.ImageAddress;\r
 \r
   //\r
   // Allocate memory of the correct memory type aligned on the required image boundry\r
@@ -321,9 +354,11 @@ CoreLoadPeImage (
   }\r
 \r
   Image->ImageBasePage = Image->ImageContext.ImageAddress;\r
-  Image->ImageContext.ImageAddress =\r
-      (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &\r
-      ~((UINTN)Image->ImageContext.SectionAlignment - 1);\r
+  if (!Image->ImageContext.IsTeImage) {\r
+         Image->ImageContext.ImageAddress =\r
+             (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &\r
+             ~((UINTN)Image->ImageContext.SectionAlignment - 1);\r
+  }\r
 \r
   //\r
   // Load the image from the file into the allocated memory\r
@@ -348,29 +383,6 @@ CoreLoadPeImage (
     }\r
   }\r
 \r
-  //\r
-  // Measure the image before applying fixup\r
-  //\r
-  Status = CoreLocateProtocol (\r
-             &gEfiTcgPlatformProtocolGuid,\r
-             NULL,\r
-             (VOID **) &TcgPlatformProtocol\r
-             );\r
-  if (!EFI_ERROR (Status)) {\r
-    FHandle = (IMAGE_FILE_HANDLE *) Image->ImageContext.Handle;\r
-    Status = TcgPlatformProtocol->MeasurePeImage (\r
-                                    BootPolicy,\r
-                                    (EFI_PHYSICAL_ADDRESS) (UINTN) FHandle->Source,\r
-                                    FHandle->SourceSize,\r
-                                    LinkTimeBase,\r
-                                    Image->ImageContext.ImageType,\r
-                                    Image->Info.DeviceHandle,\r
-                                    Image->Info.FilePath\r
-                                    );\r
-\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
-\r
   //\r
   // Relocate the image in memory\r
   //\r
@@ -477,23 +489,26 @@ CoreLoadPeImage (
     DEBUG ((DEBUG_INFO | DEBUG_LOAD,\r
            "Loading driver at 0x%11p EntryPoint=0x%11p ",\r
            (VOID *)(UINTN) Image->ImageContext.ImageAddress,\r
-           FUNCTION_ENTRY_POINT ((UINTN) Image->ImageContext.EntryPoint)));\r
+           FUNCTION_ENTRY_POINT (Image->ImageContext.EntryPoint)));\r
 \r
 \r
     //\r
-    // Print Module Name by Pdb file path\r
+    // Print Module Name by Pdb file path.\r
+    // Windows and Unix style file path are all trimmed correctly.\r
     //\r
     if (Image->ImageContext.PdbPointer != NULL) {\r
       StartIndex = 0;\r
       for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {\r
-        if (Image->ImageContext.PdbPointer[Index] == '\\') {\r
+        if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) {\r
           StartIndex = Index + 1;\r
         }\r
       }\r
       //\r
       // Copy the PDB file name to our temporary string, and replace .pdb with .efi\r
+      // The PDB file name is limited in the range of 0~255.\r
+      // If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary.\r
       //\r
-      for (Index = 0; Index < sizeof (EfiFileName); Index++) {\r
+      for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {\r
         EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];\r
         if (EfiFileName[Index] == 0) {\r
           EfiFileName[Index] = '.';\r
@@ -506,6 +521,10 @@ CoreLoadPeImage (
           break;\r
         }\r
       }\r
+\r
+      if (Index == sizeof (EfiFileName) - 4) {\r
+        EfiFileName[Index] = 0;\r
+      }\r
       DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));\r
     }\r
     DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));\r
@@ -669,6 +688,14 @@ CoreUnloadAndCloseImage (
                &Image->Info\r
                );\r
 \r
+    if (Image->ImageContext.HiiResourceData != 0) {\r
+      Status = CoreUninstallProtocolInterface (\r
+                 Image->Handle,\r
+                 &gEfiHiiPackageListProtocolGuid,\r
+                 (VOID *) (UINTN) Image->ImageContext.HiiResourceData\r
+                 );\r
+    }\r
+\r
   }\r
 \r
   if (Image->RuntimeData != NULL) {\r
@@ -786,19 +813,63 @@ CoreLoadImageCommon (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // Get simple read access to the source file\r
-  //\r
+  ZeroMem (&FHand, sizeof (IMAGE_FILE_HANDLE));\r
+  FHand.Signature  = IMAGE_FILE_HANDLE_SIGNATURE;\r
   OriginalFilePath = FilePath;\r
-  Status = CoreOpenImageFile (\r
-             BootPolicy,\r
-             SourceBuffer,\r
-             SourceSize,\r
-             &FilePath,\r
-             &DeviceHandle,\r
-             &FHand,\r
-             &AuthenticationStatus\r
-             );\r
+  HandleFilePath   = FilePath;\r
+  DeviceHandle     = NULL;\r
+  Status           = EFI_SUCCESS;\r
+  AuthenticationStatus = 0;\r
+  //\r
+  // If the caller passed a copy of the file, then just use it\r
+  //\r
+  if (SourceBuffer != NULL) {\r
+    FHand.Source     = SourceBuffer;\r
+    FHand.SourceSize = SourceSize;\r
+    CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+    if (SourceSize > 0) {\r
+      Status = EFI_SUCCESS;\r
+    } else {\r
+      Status = EFI_LOAD_ERROR;\r
+    }\r
+  } else {\r
+    if (FilePath == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    //\r
+    // Get the source file buffer by its device path.\r
+    //\r
+    FHand.Source = GetFileBufferByFilePath (\r
+                      BootPolicy, \r
+                      FilePath,\r
+                      &FHand.SourceSize,\r
+                      &AuthenticationStatus\r
+                      );\r
+    if (FHand.Source == NULL) {\r
+      Status = EFI_NOT_FOUND;\r
+    } else {\r
+      //\r
+      // Try to get the image device handle by checking the match protocol.\r
+      //\r
+      FHand.FreeBuffer = TRUE;\r
+      Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+      if (EFI_ERROR (Status)) {\r
+        HandleFilePath = FilePath;\r
+        Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+        if (EFI_ERROR (Status)) {\r
+          if (!BootPolicy) {\r
+            HandleFilePath = FilePath;\r
+            Status = CoreLocateDevicePath (&gEfiLoadFile2ProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+          }\r
+          if (EFI_ERROR (Status)) {\r
+            HandleFilePath = FilePath;\r
+            Status = CoreLocateDevicePath (&gEfiLoadFileProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
   if (Status == EFI_ALREADY_STARTED) {\r
     Image = NULL;\r
     goto Done;\r
@@ -931,6 +1002,21 @@ CoreLoadImageCommon (
     goto Done;\r
   }\r
 \r
+  //\r
+  // Install HII Package List Protocol onto the image handle\r
+  //\r
+  if (Image->ImageContext.HiiResourceData != 0) {\r
+    Status = CoreInstallProtocolInterface (\r
+               &Image->Handle,\r
+               &gEfiHiiPackageListProtocolGuid,\r
+               EFI_NATIVE_INTERFACE,\r
+               (VOID *) (UINTN) Image->ImageContext.HiiResourceData\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  }\r
+\r
   //\r
   // Success.  Return the image handle\r
   //\r
@@ -1001,8 +1087,12 @@ CoreLoadImage (
   )\r
 {\r
   EFI_STATUS    Status;\r
+  UINT64        Tick;\r
 \r
-  PERF_START (NULL, "LoadImage", NULL, 0);\r
+  Tick = 0;\r
+  PERF_CODE (\r
+    Tick = GetPerformanceCounter ();\r
+  );\r
 \r
   Status = CoreLoadImageCommon (\r
              BootPolicy,\r
@@ -1017,7 +1107,8 @@ CoreLoadImage (
              EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION\r
              );\r
 \r
-  PERF_END (NULL, "LoadImage", NULL, 0);\r
+  PERF_START (*ImageHandle, "LoadImage:", NULL, Tick);\r
+  PERF_END (*ImageHandle, "LoadImage:", NULL, 0);\r
 \r
   return Status;\r
 }\r
@@ -1120,10 +1211,18 @@ CoreStartImage (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // The image to be started must have the machine type supported by DxeCore.\r
+  //\r
+  ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->Machine));\r
+  if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->Machine)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   //\r
   // Don't profile Objects or invalid start requests\r
   //\r
-  PERF_START (ImageHandle, START_IMAGE_TOK, NULL, 0);\r
+  PERF_START (ImageHandle, "StartImage:", NULL, 0);\r
 \r
 \r
   //\r
@@ -1143,7 +1242,7 @@ CoreStartImage (
   //\r
   Image->JumpBuffer = AllocatePool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);\r
   if (Image->JumpBuffer == NULL) {\r
-    PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);\r
+    PERF_END (ImageHandle, "StartImage:", NULL, 0);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   Image->JumpContext = ALIGN_POINTER (Image->JumpBuffer, BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);\r
@@ -1201,7 +1300,7 @@ CoreStartImage (
   DEBUG_CODE_BEGIN ();\r
     if (Image->ExitDataSize != 0 || Image->ExitData != NULL) {\r
 \r
-      DEBUG ((DEBUG_LOAD, "StartImage: ExitDataSize %d, ExitData %x", Image->ExitDataSize, Image->ExitData));\r
+      DEBUG ((DEBUG_LOAD, "StartImage: ExitDataSize %d, ExitData %p", (UINT32)Image->ExitDataSize, Image->ExitData));\r
       if (Image->ExitData != NULL) {\r
         DEBUG ((DEBUG_LOAD, " (%hs)", Image->ExitData));\r
       }\r
@@ -1239,7 +1338,7 @@ CoreStartImage (
   //\r
   // Done\r
   //\r
-  PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);\r
+  PERF_END (ImageHandle, "StartImage:", NULL, 0);\r
   return Status;\r
 }\r
 \r
@@ -1366,14 +1465,6 @@ CoreUnloadImage (
   EFI_STATUS                 Status;\r
   LOADED_IMAGE_PRIVATE_DATA  *Image;\r
 \r
-  //\r
-  // Prevent possible reentrance to this function\r
-  // for the same ImageHandle\r
-  //\r
-  if (!AcquireSpinLockOrFail (&mUnloadImageLock)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
   Image = CoreLoadedImageInfo (ImageHandle);\r
   if (Image == NULL ) {\r
     //\r
@@ -1408,7 +1499,6 @@ CoreUnloadImage (
   }\r
 \r
 Done:\r
-  ReleaseSpinLock (&mUnloadImageLock);\r
   return Status;\r
 }\r
 \r