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