]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/Library/PeiNt32PeCoffExtraActionLib/PeiNt32PeCoffExtraActionLib.c
UefiCpuPkg: Remove double \r
[mirror_edk2.git] / Nt32Pkg / Library / PeiNt32PeCoffExtraActionLib / PeiNt32PeCoffExtraActionLib.c
CommitLineData
ffdd18bb 1/**@file\r
2\r
8f2a5f80 3Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
9d2eedba 4SPDX-License-Identifier: BSD-2-Clause-Patent\r
ffdd18bb 5\r
6Module Name:\r
7\r
8 PeiNt32PeCoffExtraActionLib.c\r
9\r
10Abstract:\r
11\r
12 Provides services to perform additional actions to relocate and unload\r
13 PE/Coff image for NT32 environment specific purpose such as souce level debug.\r
14 This version only works for PEI phase \r
15\r
16\r
17**/\r
18//\r
19// The package level header files this module uses\r
20//\r
5e335a52 21#include <PiPei.h>\r
ffdd18bb 22#include <WinNtPeim.h>\r
23\r
24//\r
25// The protocols, PPI and GUID defintions for this module\r
26//\r
27#include <Ppi/NtThunk.h>\r
28\r
29#include <PiPei.h>\r
30#include <Library/PeCoffLib.h>\r
31#include <Library/PeiServicesLib.h>\r
32#include <Library/DebugLib.h>\r
33#include <Library/BaseLib.h>\r
34#include <Library/PeCoffExtraActionLib.h>\r
35\r
36//\r
37// Cache of WinNtThunk protocol\r
38//\r
39EFI_WIN_NT_THUNK_PROTOCOL *mWinNt = NULL;\r
40\r
41/**\r
42 The function caches the pointer of the WinNT thunk functions\r
43 It will ASSERT() if NT thunk ppi is not installed.\r
44\r
45 @retval EFI_SUCCESS WinNT thunk protocol is found and cached.\r
46\r
47**/\r
48EFI_STATUS\r
49EFIAPI\r
50Nt32PeCoffGetWinNtThunkStucture (\r
51 )\r
52{\r
53 PEI_NT_THUNK_PPI *NtThunkPpi;\r
54 EFI_STATUS Status;\r
55\r
56\r
57 //\r
58 // Locate NtThunkPpi for retrieving standard output handle\r
59 //\r
60 Status = PeiServicesLocatePpi (\r
61 &gPeiNtThunkPpiGuid,\r
62 0,\r
63 NULL,\r
64 (VOID **) &NtThunkPpi\r
65 );\r
66\r
67 ASSERT_EFI_ERROR (Status);\r
68\r
69 mWinNt = (EFI_WIN_NT_THUNK_PROTOCOL *) NtThunkPpi->NtThunk ();\r
70 \r
71 return EFI_SUCCESS;\r
72}\r
73\r
74/**\r
75 Convert the passed in Ascii string to Unicode.\r
76 \r
77 This function Convert the passed in Ascii string to Unicode.Optionally return\r
78 the length of the strings..\r
79\r
80 @param AsciiString Pointer to an AscII string\r
81 @param StrLen Length of string\r
82\r
83 @return Pointer to malloc'ed Unicode version of Ascii\r
84\r
85**/\r
86CHAR16 *\r
87AsciiToUnicode (\r
88 IN CHAR8 *Ascii,\r
89 IN UINTN *StrLen OPTIONAL\r
90 )\r
91{\r
92 UINTN Index;\r
93 CHAR16 *Unicode;\r
94\r
95 //\r
96 // Allocate a buffer for unicode string\r
97 //\r
98 for (Index = 0; Ascii[Index] != '\0'; Index++)\r
99 ;\r
100 Unicode = mWinNt->HeapAlloc ( mWinNt->GetProcessHeap (),\r
101 HEAP_ZERO_MEMORY,\r
102 ((Index + 1) * sizeof (CHAR16))\r
103 ); \r
104 if (Unicode == NULL) {\r
105 return NULL;\r
106 }\r
107\r
108 for (Index = 0; Ascii[Index] != '\0'; Index++) {\r
109 Unicode[Index] = (CHAR16) Ascii[Index];\r
110 }\r
111\r
112 Unicode[Index] = '\0';\r
113\r
114 if (StrLen != NULL) {\r
115 *StrLen = Index;\r
116 }\r
117\r
118 return Unicode;\r
119}\r
120\r
121/**\r
51f1a2b5 122 Performs additional actions after a PE/COFF image has been loaded and relocated.\r
ffdd18bb 123\r
51f1a2b5 124 For NT32, this function load symbols to support source level debugging.\r
125\r
126 If ImageContext is NULL, then ASSERT().\r
127\r
128 @param ImageContext Pointer to the image context structure that describes the\r
129 PE/COFF image that has already been loaded and relocated.\r
ffdd18bb 130\r
131**/\r
132VOID\r
133EFIAPI\r
134PeCoffLoaderRelocateImageExtraAction (\r
135 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
136 )\r
137{\r
138 VOID *DllEntryPoint;\r
139 CHAR16 *DllFileName;\r
140 HMODULE Library;\r
141 UINTN Index;\r
142 \r
51f1a2b5 143 ASSERT (ImageContext != NULL);\r
144\r
ffdd18bb 145 if (mWinNt == NULL) {\r
146 Nt32PeCoffGetWinNtThunkStucture ();\r
147 }\r
148 //\r
149 // If we load our own PE COFF images the Windows debugger can not source\r
150 // level debug our code. If a valid PDB pointer exists usw it to load\r
151 // the *.dll file as a library using Windows* APIs. This allows \r
8aa9d680 152 // source level debug. The image is still loaded and relocated\r
ffdd18bb 153 // in the Framework memory space like on a real system (by the code above),\r
154 // but the entry point points into the DLL loaded by the code bellow. \r
155 //\r
156\r
157 DllEntryPoint = NULL;\r
158\r
159 //\r
160 // Load the DLL if it's not an EBC image.\r
161 //\r
162 if ((ImageContext->PdbPointer != NULL) &&\r
163 (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) {\r
164 //\r
165 // Convert filename from ASCII to Unicode\r
166 //\r
167 DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index);\r
168\r
169 //\r
170 // Check that we have a valid filename\r
171 //\r
172 if (Index < 5 || DllFileName[Index - 4] != '.') {\r
173 mWinNt->HeapFree (mWinNt->GetProcessHeap (), 0, DllFileName);\r
174\r
175 //\r
176 // Never return an error if PeCoffLoaderRelocateImage() succeeded.\r
177 // The image will run, but we just can't source level debug. If we\r
178 // return an error the image will not run.\r
179 //\r
180 return;\r
181 }\r
182 //\r
183 // Replace .PDB with .DLL on the filename\r
184 //\r
185 DllFileName[Index - 3] = 'D';\r
186 DllFileName[Index - 2] = 'L';\r
187 DllFileName[Index - 1] = 'L';\r
188\r
189 //\r
190 // Load the .DLL file into the user process's address space for source \r
191 // level debug\r
192 //\r
193 Library = mWinNt->LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);\r
194 if (Library != NULL) {\r
195 //\r
196 // InitializeDriver is the entry point we put in all our EFI DLL's. The\r
8aa9d680 197 // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() suppresses the \r
ffdd18bb 198 // normal DLL entry point of DllMain, and prevents other modules that are\r
199 // referenced in side the DllFileName from being loaded. There is no error \r
200 // checking as the we can point to the PE32 image loaded by Tiano. This \r
8aa9d680 201 // step is only needed for source level debugging\r
ffdd18bb 202 //\r
203 DllEntryPoint = (VOID *) (UINTN) mWinNt->GetProcAddress (Library, "InitializeDriver");\r
204\r
205 }\r
206\r
207 if ((Library != NULL) && (DllEntryPoint != NULL)) {\r
208 ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;\r
209 DEBUG ((EFI_D_INFO, "LoadLibraryEx (%s,\n NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName));\r
210 } else {\r
211 DEBUG ((EFI_D_ERROR, "WARNING: No source level debug %s. \n", DllFileName));\r
212 }\r
213\r
214 mWinNt->HeapFree (mWinNt->GetProcessHeap (), 0, DllFileName);\r
215 }\r
216\r
217 //\r
218 // Never return an error if PeCoffLoaderRelocateImage() succeeded.\r
219 // The image will run, but we just can't source level debug. If we\r
220 // return an error the image will not run.\r
221 //\r
222 return;\r
223} \r
224\r
225/**\r
51f1a2b5 226 Performs additional actions just before a PE/COFF image is unloaded. Any resources\r
227 that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.\r
ffdd18bb 228 \r
51f1a2b5 229 For NT32, this function unloads symbols for source level debugging.\r
230\r
ffdd18bb 231 If ImageContext is NULL, then ASSERT().\r
232 \r
51f1a2b5 233 @param ImageContext Pointer to the image context structure that describes the\r
234 PE/COFF image that is being unloaded.\r
ffdd18bb 235\r
236**/\r
237VOID\r
238EFIAPI\r
239PeCoffLoaderUnloadImageExtraAction (\r
240 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
241 )\r
242{\r
51f1a2b5 243 ASSERT (ImageContext != NULL);\r
ee31b443 244}\r