+++ /dev/null
-/**@file\r
-\r
-Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-Module Name:\r
-\r
- PeiNt32PeCoffExtraActionLib.c\r
-\r
-Abstract:\r
-\r
- Provides services to perform additional actions to relocate and unload\r
- PE/Coff image for NT32 environment specific purpose such as souce level debug.\r
- This version only works for PEI phase \r
-\r
-\r
-**/\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <PiPei.h>\r
-#include <WinNtPeim.h>\r
-\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Ppi/NtThunk.h>\r
-\r
-#include <PiPei.h>\r
-#include <Library/PeCoffLib.h>\r
-#include <Library/PeiServicesLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/PeCoffExtraActionLib.h>\r
-\r
-//\r
-// Cache of WinNtThunk protocol\r
-//\r
-EFI_WIN_NT_THUNK_PROTOCOL *mWinNt = NULL;\r
-\r
-/**\r
- The function caches the pointer of the WinNT thunk functions\r
- It will ASSERT() if NT thunk ppi is not installed.\r
-\r
- @retval EFI_SUCCESS WinNT thunk protocol is found and cached.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Nt32PeCoffGetWinNtThunkStucture (\r
- )\r
-{\r
- PEI_NT_THUNK_PPI *NtThunkPpi;\r
- EFI_STATUS Status;\r
-\r
-\r
- //\r
- // Locate NtThunkPpi for retrieving standard output handle\r
- //\r
- Status = PeiServicesLocatePpi (\r
- &gPeiNtThunkPpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **) &NtThunkPpi\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- mWinNt = (EFI_WIN_NT_THUNK_PROTOCOL *) NtThunkPpi->NtThunk ();\r
- \r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Convert the passed in Ascii string to Unicode.\r
- \r
- This function Convert the passed in Ascii string to Unicode.Optionally return\r
- the length of the strings..\r
-\r
- @param AsciiString Pointer to an AscII string\r
- @param StrLen Length of string\r
-\r
- @return Pointer to malloc'ed Unicode version of Ascii\r
-\r
-**/\r
-CHAR16 *\r
-AsciiToUnicode (\r
- IN CHAR8 *Ascii,\r
- IN UINTN *StrLen OPTIONAL\r
- )\r
-{\r
- UINTN Index;\r
- CHAR16 *Unicode;\r
-\r
- //\r
- // Allocate a buffer for unicode string\r
- //\r
- for (Index = 0; Ascii[Index] != '\0'; Index++)\r
- ;\r
- Unicode = mWinNt->HeapAlloc ( mWinNt->GetProcessHeap (),\r
- HEAP_ZERO_MEMORY,\r
- ((Index + 1) * sizeof (CHAR16))\r
- ); \r
- if (Unicode == NULL) {\r
- return NULL;\r
- }\r
-\r
- for (Index = 0; Ascii[Index] != '\0'; Index++) {\r
- Unicode[Index] = (CHAR16) Ascii[Index];\r
- }\r
-\r
- Unicode[Index] = '\0';\r
-\r
- if (StrLen != NULL) {\r
- *StrLen = Index;\r
- }\r
-\r
- return Unicode;\r
-}\r
-\r
-/**\r
- Performs additional actions after a PE/COFF image has been loaded and relocated.\r
-\r
- For NT32, this function load symbols to support source level debugging.\r
-\r
- If ImageContext is NULL, then ASSERT().\r
-\r
- @param ImageContext Pointer to the image context structure that describes the\r
- PE/COFF image that has already been loaded and relocated.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-PeCoffLoaderRelocateImageExtraAction (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
- )\r
-{\r
- VOID *DllEntryPoint;\r
- CHAR16 *DllFileName;\r
- HMODULE Library;\r
- UINTN Index;\r
- \r
- ASSERT (ImageContext != NULL);\r
-\r
- if (mWinNt == NULL) {\r
- Nt32PeCoffGetWinNtThunkStucture ();\r
- }\r
- //\r
- // If we load our own PE COFF images the Windows debugger can not source\r
- // level debug our code. If a valid PDB pointer exists usw it to load\r
- // the *.dll file as a library using Windows* APIs. This allows \r
- // source level debug. The image is still loaded and relocated\r
- // in the Framework memory space like on a real system (by the code above),\r
- // but the entry point points into the DLL loaded by the code bellow. \r
- //\r
-\r
- DllEntryPoint = NULL;\r
-\r
- //\r
- // Load the DLL if it's not an EBC image.\r
- //\r
- if ((ImageContext->PdbPointer != NULL) &&\r
- (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) {\r
- //\r
- // Convert filename from ASCII to Unicode\r
- //\r
- DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index);\r
-\r
- //\r
- // Check that we have a valid filename\r
- //\r
- if (Index < 5 || DllFileName[Index - 4] != '.') {\r
- mWinNt->HeapFree (mWinNt->GetProcessHeap (), 0, DllFileName);\r
-\r
- //\r
- // Never return an error if PeCoffLoaderRelocateImage() succeeded.\r
- // The image will run, but we just can't source level debug. If we\r
- // return an error the image will not run.\r
- //\r
- return;\r
- }\r
- //\r
- // Replace .PDB with .DLL on the filename\r
- //\r
- DllFileName[Index - 3] = 'D';\r
- DllFileName[Index - 2] = 'L';\r
- DllFileName[Index - 1] = 'L';\r
-\r
- //\r
- // Load the .DLL file into the user process's address space for source \r
- // level debug\r
- //\r
- Library = mWinNt->LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);\r
- if (Library != NULL) {\r
- //\r
- // InitializeDriver is the entry point we put in all our EFI DLL's. The\r
- // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() suppresses the \r
- // normal DLL entry point of DllMain, and prevents other modules that are\r
- // referenced in side the DllFileName from being loaded. There is no error \r
- // checking as the we can point to the PE32 image loaded by Tiano. This \r
- // step is only needed for source level debugging\r
- //\r
- DllEntryPoint = (VOID *) (UINTN) mWinNt->GetProcAddress (Library, "InitializeDriver");\r
-\r
- }\r
-\r
- if ((Library != NULL) && (DllEntryPoint != NULL)) {\r
- ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;\r
- DEBUG ((EFI_D_INFO, "LoadLibraryEx (%s,\n NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName));\r
- } else {\r
- DEBUG ((EFI_D_ERROR, "WARNING: No source level debug %s. \n", DllFileName));\r
- }\r
-\r
- mWinNt->HeapFree (mWinNt->GetProcessHeap (), 0, DllFileName);\r
- }\r
-\r
- //\r
- // Never return an error if PeCoffLoaderRelocateImage() succeeded.\r
- // The image will run, but we just can't source level debug. If we\r
- // return an error the image will not run.\r
- //\r
- return;\r
-} \r
-\r
-/**\r
- Performs additional actions just before a PE/COFF image is unloaded. Any resources\r
- that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.\r
- \r
- For NT32, this function unloads symbols for source level debugging.\r
-\r
- If ImageContext is NULL, then ASSERT().\r
- \r
- @param ImageContext Pointer to the image context structure that describes the\r
- PE/COFF image that is being unloaded.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-PeCoffLoaderUnloadImageExtraAction (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
- )\r
-{\r
- ASSERT (ImageContext != NULL);\r
-}\r