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