]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Image/Image.c
Update DxeCore to support to install gEfiHiiPackageListProtocolGuid in LoadImage...
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Image / Image.c
index 4b651483448254df3d953ca18852ae6e88455f47..8ec6793966c8d3338cf471a0ee0c66003d78516f 100644 (file)
@@ -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,11 +138,6 @@ CoreInitializeImageServices (
 \r
   mCurrentImage = Image;\r
 \r
-  //\r
-  // Initialize spin lock\r
-  //\r
-  InitializeSpinLock (&mUnloadImageLock);\r
-\r
   //\r
   // Fill in DXE globals\r
   //\r
@@ -196,11 +190,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 +235,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 +307,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 +336,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 +442,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 +474,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
@@ -566,6 +538,155 @@ CoreLoadedImageInfo (
 }\r
 \r
 \r
+/**\r
+  Unloads EFI image from memory.\r
+\r
+  @param  Image                   EFI image\r
+  @param  FreePage                Free allocated pages\r
+\r
+**/\r
+VOID\r
+CoreUnloadAndCloseImage (\r
+  IN LOADED_IMAGE_PRIVATE_DATA  *Image,\r
+  IN BOOLEAN                    FreePage\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  UINTN                               HandleCount;\r
+  EFI_HANDLE                          *HandleBuffer;\r
+  UINTN                               HandleIndex;\r
+  EFI_GUID                            **ProtocolGuidArray;\r
+  UINTN                               ArrayCount;\r
+  UINTN                               ProtocolIndex;\r
+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
+  UINTN                               OpenInfoCount;\r
+  UINTN                               OpenInfoIndex;\r
+\r
+  if (Image->Ebc != NULL) {\r
+    //\r
+    // If EBC protocol exists we must perform cleanups for this image.\r
+    //\r
+    Image->Ebc->UnloadImage (Image->Ebc, Image->Handle);\r
+  }\r
+\r
+  //\r
+  // Unload image, free Image->ImageContext->ModHandle\r
+  //\r
+  PeCoffLoaderUnloadImage (&Image->ImageContext);\r
+\r
+  //\r
+  // Free our references to the image handle\r
+  //\r
+  if (Image->Handle != NULL) {\r
+\r
+    Status = CoreLocateHandleBuffer (\r
+               AllHandles,\r
+               NULL,\r
+               NULL,\r
+               &HandleCount,\r
+               &HandleBuffer\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
+        Status = CoreProtocolsPerHandle (\r
+                   HandleBuffer[HandleIndex],\r
+                   &ProtocolGuidArray,\r
+                   &ArrayCount\r
+                   );\r
+        if (!EFI_ERROR (Status)) {\r
+          for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
+            Status = CoreOpenProtocolInformation (\r
+                       HandleBuffer[HandleIndex],\r
+                       ProtocolGuidArray[ProtocolIndex],\r
+                       &OpenInfo,\r
+                       &OpenInfoCount\r
+                       );\r
+            if (!EFI_ERROR (Status)) {\r
+              for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
+                if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {\r
+                  Status = CoreCloseProtocol (\r
+                             HandleBuffer[HandleIndex],\r
+                             ProtocolGuidArray[ProtocolIndex],\r
+                             Image->Handle,\r
+                             OpenInfo[OpenInfoIndex].ControllerHandle\r
+                             );\r
+                }\r
+              }\r
+              if (OpenInfo != NULL) {\r
+                CoreFreePool(OpenInfo);\r
+              }\r
+            }\r
+          }\r
+          if (ProtocolGuidArray != NULL) {\r
+            CoreFreePool(ProtocolGuidArray);\r
+          }\r
+        }\r
+      }\r
+      if (HandleBuffer != NULL) {\r
+        CoreFreePool (HandleBuffer);\r
+      }\r
+    }\r
+\r
+    CoreRemoveDebugImageInfoEntry (Image->Handle);\r
+\r
+    Status = CoreUninstallProtocolInterface (\r
+               Image->Handle,\r
+               &gEfiLoadedImageDevicePathProtocolGuid,\r
+               Image->LoadedImageDevicePath\r
+               );\r
+\r
+    Status = CoreUninstallProtocolInterface (\r
+               Image->Handle,\r
+               &gEfiLoadedImageProtocolGuid,\r
+               &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
+    if (Image->RuntimeData->Link.ForwardLink != NULL) {\r
+      //\r
+      // Remove the Image from the Runtime Image list as we are about to Free it!\r
+      //\r
+      RemoveEntryList (&Image->RuntimeData->Link);\r
+    }\r
+    CoreFreePool (Image->RuntimeData);\r
+  }\r
+\r
+  //\r
+  // Free the Image from memory\r
+  //\r
+  if ((Image->ImageBasePage != 0) && FreePage) {\r
+    CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);\r
+  }\r
+\r
+  //\r
+  // Done with the Image structure\r
+  //\r
+  if (Image->Info.FilePath != NULL) {\r
+    CoreFreePool (Image->Info.FilePath);\r
+  }\r
+\r
+  if (Image->LoadedImageDevicePath != NULL) {\r
+    CoreFreePool (Image->LoadedImageDevicePath);\r
+  }\r
+\r
+  if (Image->FixupData != NULL) {\r
+    CoreFreePool (Image->FixupData);\r
+  }\r
+\r
+  CoreFreePool (Image);\r
+}\r
+\r
+\r
 /**\r
   Loads an EFI image into memory and returns a handle to the image.\r
 \r
@@ -790,6 +911,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
@@ -860,8 +996,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
@@ -876,7 +1016,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
@@ -975,14 +1116,14 @@ CoreStartImage (
   UINTN                         SetJumpFlag;\r
 \r
   Image = CoreLoadedImageInfo (ImageHandle);\r
-  if (Image == NULL_HANDLE  ||  Image->Started) {\r
+  if (Image == NULL  ||  Image->Started) {\r
     return EFI_INVALID_PARAMETER;\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
@@ -1002,7 +1143,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
@@ -1060,7 +1201,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
@@ -1098,155 +1239,10 @@ 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
-\r
-\r
-/**\r
-  Unloads EFI image from memory.\r
-\r
-  @param  Image                   EFI image\r
-  @param  FreePage                Free allocated pages\r
-\r
-**/\r
-VOID\r
-CoreUnloadAndCloseImage (\r
-  IN LOADED_IMAGE_PRIVATE_DATA  *Image,\r
-  IN BOOLEAN                    FreePage\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  UINTN                               HandleCount;\r
-  EFI_HANDLE                          *HandleBuffer;\r
-  UINTN                               HandleIndex;\r
-  EFI_GUID                            **ProtocolGuidArray;\r
-  UINTN                               ArrayCount;\r
-  UINTN                               ProtocolIndex;\r
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
-  UINTN                               OpenInfoCount;\r
-  UINTN                               OpenInfoIndex;\r
-\r
-  if (Image->Ebc != NULL) {\r
-    //\r
-    // If EBC protocol exists we must perform cleanups for this image.\r
-    //\r
-    Image->Ebc->UnloadImage (Image->Ebc, Image->Handle);\r
-  }\r
-\r
-  //\r
-  // Unload image, free Image->ImageContext->ModHandle\r
-  //\r
-  PeCoffLoaderUnloadImage (&Image->ImageContext);\r
-\r
-  //\r
-  // Free our references to the image handle\r
-  //\r
-  if (Image->Handle != NULL_HANDLE) {\r
-\r
-    Status = CoreLocateHandleBuffer (\r
-               AllHandles,\r
-               NULL,\r
-               NULL,\r
-               &HandleCount,\r
-               &HandleBuffer\r
-               );\r
-    if (!EFI_ERROR (Status)) {\r
-      for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
-        Status = CoreProtocolsPerHandle (\r
-                   HandleBuffer[HandleIndex],\r
-                   &ProtocolGuidArray,\r
-                   &ArrayCount\r
-                   );\r
-        if (!EFI_ERROR (Status)) {\r
-          for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
-            Status = CoreOpenProtocolInformation (\r
-                       HandleBuffer[HandleIndex],\r
-                       ProtocolGuidArray[ProtocolIndex],\r
-                       &OpenInfo,\r
-                       &OpenInfoCount\r
-                       );\r
-            if (!EFI_ERROR (Status)) {\r
-              for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
-                if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {\r
-                  Status = CoreCloseProtocol (\r
-                             HandleBuffer[HandleIndex],\r
-                             ProtocolGuidArray[ProtocolIndex],\r
-                             Image->Handle,\r
-                             OpenInfo[OpenInfoIndex].ControllerHandle\r
-                             );\r
-                }\r
-              }\r
-              if (OpenInfo != NULL) {\r
-                CoreFreePool(OpenInfo);\r
-              }\r
-            }\r
-          }\r
-          if (ProtocolGuidArray != NULL) {\r
-            CoreFreePool(ProtocolGuidArray);\r
-          }\r
-        }\r
-      }\r
-      if (HandleBuffer != NULL) {\r
-        CoreFreePool (HandleBuffer);\r
-      }\r
-    }\r
-\r
-    CoreRemoveDebugImageInfoEntry (Image->Handle);\r
-\r
-    Status = CoreUninstallProtocolInterface (\r
-               Image->Handle,\r
-               &gEfiLoadedImageDevicePathProtocolGuid,\r
-               Image->LoadedImageDevicePath\r
-               );\r
-\r
-    Status = CoreUninstallProtocolInterface (\r
-               Image->Handle,\r
-               &gEfiLoadedImageProtocolGuid,\r
-               &Image->Info\r
-               );\r
-\r
-  }\r
-\r
-  if (Image->RuntimeData != NULL) {\r
-    if (Image->RuntimeData->Link.ForwardLink != NULL) {\r
-      //\r
-      // Remove the Image from the Runtime Image list as we are about to Free it!\r
-      //\r
-      RemoveEntryList (&Image->RuntimeData->Link);\r
-    }\r
-    CoreFreePool (Image->RuntimeData);\r
-  }\r
-\r
-  //\r
-  // Free the Image from memory\r
-  //\r
-  if ((Image->ImageBasePage != 0) && FreePage) {\r
-    CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);\r
-  }\r
-\r
-  //\r
-  // Done with the Image structure\r
-  //\r
-  if (Image->Info.FilePath != NULL) {\r
-    CoreFreePool (Image->Info.FilePath);\r
-  }\r
-\r
-  if (Image->LoadedImageDevicePath != NULL) {\r
-    CoreFreePool (Image->LoadedImageDevicePath);\r
-  }\r
-\r
-  if (Image->FixupData != NULL) {\r
-    CoreFreePool (Image->FixupData);\r
-  }\r
-\r
-  CoreFreePool (Image);\r
-}\r
-\r
-\r
-\r
-\r
 /**\r
   Terminates the currently loaded EFI image and returns control to boot services.\r
 \r
@@ -1289,7 +1285,7 @@ CoreExit (
   OldTpl = CoreRaiseTpl (TPL_NOTIFY);\r
 \r
   Image = CoreLoadedImageInfo (ImageHandle);\r
-  if (Image == NULL_HANDLE) {\r
+  if (Image == NULL) {\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
@@ -1370,14 +1366,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
@@ -1412,7 +1400,6 @@ CoreUnloadImage (
   }\r
 \r
 Done:\r
-  ReleaseSpinLock (&mUnloadImageLock);\r
   return Status;\r
 }\r
 \r