]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Source/TianoTools/Common/PeiLib/PeCoffLoader.c
Removed #ifdef NT32 as we don't need them for tools
[mirror_edk2.git] / Tools / Source / TianoTools / Common / PeiLib / PeCoffLoader.c
... / ...
CommitLineData
1/*++\r
2\r
3Copyright (c) 2004 - 2005, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 PeCoffLoader.c\r
15\r
16Abstract:\r
17\r
18 Tiano PE/COFF loader \r
19\r
20Revision History\r
21\r
22--*/\r
23\r
24#include "Tiano.h"\r
25#include "Pei.h"\r
26#include "PeiLib.h"\r
27#include "PeCoffLoaderEx.h"\r
28\r
29\r
30STATIC\r
31EFI_STATUS\r
32PeCoffLoaderGetPeHeader (\r
33 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
34 OUT EFI_IMAGE_NT_HEADERS *PeHdr,\r
35 OUT EFI_TE_IMAGE_HEADER *TeHdr\r
36 );\r
37\r
38STATIC\r
39EFI_STATUS\r
40PeCoffLoaderCheckImageType (\r
41 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
42 IN EFI_IMAGE_NT_HEADERS *PeHdr,\r
43 IN EFI_TE_IMAGE_HEADER *TeHdr\r
44 );\r
45\r
46STATIC\r
47VOID *\r
48PeCoffLoaderImageAddress (\r
49 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
50 IN UINTN Address\r
51 );\r
52\r
53EFI_STATUS\r
54EFIAPI\r
55PeCoffLoaderGetImageInfo (\r
56 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
57 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
58 );\r
59\r
60EFI_STATUS\r
61EFIAPI\r
62PeCoffLoaderRelocateImage (\r
63 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
64 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
65 );\r
66\r
67EFI_STATUS\r
68EFIAPI\r
69PeCoffLoaderLoadImage (\r
70 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
71 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
72 );\r
73\r
74EFI_STATUS\r
75EFIAPI\r
76PeCoffLoaderUnloadImage (\r
77 IN EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
78 );\r
79\r
80EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoader = {\r
81 PeCoffLoaderGetImageInfo,\r
82 PeCoffLoaderLoadImage,\r
83 PeCoffLoaderRelocateImage,\r
84 PeCoffLoaderUnloadImage\r
85};\r
86\r
87\r
88EFI_STATUS\r
89InstallEfiPeiPeCoffLoader (\r
90 IN EFI_PEI_SERVICES **PeiServices,\r
91 IN OUT EFI_PEI_PE_COFF_LOADER_PROTOCOL **This,\r
92 IN EFI_PEI_PPI_DESCRIPTOR *ThisPpi\r
93 )\r
94/*++\r
95\r
96Routine Description:\r
97\r
98 Install PE/COFF loader PPI\r
99 \r
100Arguments:\r
101\r
102 PeiServices - General purpose services available to every PEIM\r
103\r
104 This - Pointer to get Pei PE coff loader protocol as output\r
105 \r
106 ThisPpi - Passed in as EFI_NT_LOAD_AS_DLL_PPI on NT_EMULATOR platform\r
107\r
108Returns:\r
109\r
110 EFI_SUCCESS\r
111\r
112--*/\r
113{\r
114 if (NULL != This) {\r
115 *This = &mPeCoffLoader;\r
116 }\r
117\r
118 return EFI_SUCCESS;\r
119}\r
120\r
121STATIC\r
122EFI_STATUS\r
123PeCoffLoaderGetPeHeader (\r
124 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
125 OUT EFI_IMAGE_NT_HEADERS *PeHdr,\r
126 OUT EFI_TE_IMAGE_HEADER *TeHdr\r
127 )\r
128/*++\r
129\r
130Routine Description:\r
131\r
132 Retrieves the PE or TE Header from a PE/COFF or TE image\r
133\r
134Arguments:\r
135\r
136 ImageContext - The context of the image being loaded\r
137\r
138 PeHdr - The buffer in which to return the PE header\r
139 \r
140 TeHdr - The buffer in which to return the TE header\r
141\r
142Returns:\r
143\r
144 EFI_SUCCESS if the PE or TE Header is read, \r
145 Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.\r
146\r
147--*/\r
148{\r
149 EFI_STATUS Status;\r
150 EFI_IMAGE_DOS_HEADER DosHdr;\r
151 UINTN Size;\r
152\r
153 ImageContext->IsTeImage = FALSE;\r
154 //\r
155 // Read the DOS image headers\r
156 //\r
157 Size = sizeof (EFI_IMAGE_DOS_HEADER);\r
158 Status = ImageContext->ImageRead (\r
159 ImageContext->Handle,\r
160 0,\r
161 &Size,\r
162 &DosHdr\r
163 );\r
164 if (EFI_ERROR (Status)) {\r
165 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
166 return Status;\r
167 }\r
168\r
169 ImageContext->PeCoffHeaderOffset = 0;\r
170 if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
171 //\r
172 // DOS image header is present, so read the PE header after the DOS image header\r
173 //\r
174 ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;\r
175 }\r
176 //\r
177 // Read the PE/COFF Header\r
178 //\r
179 Size = sizeof (EFI_IMAGE_NT_HEADERS);\r
180 Status = ImageContext->ImageRead (\r
181 ImageContext->Handle,\r
182 ImageContext->PeCoffHeaderOffset,\r
183 &Size,\r
184 PeHdr\r
185 );\r
186 if (EFI_ERROR (Status)) {\r
187 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
188 return Status;\r
189 }\r
190 //\r
191 // Check the PE/COFF Header Signature. If not, then try to read a TE header\r
192 //\r
193 if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
194 Size = sizeof (EFI_TE_IMAGE_HEADER);\r
195 Status = ImageContext->ImageRead (\r
196 ImageContext->Handle,\r
197 0,\r
198 &Size,\r
199 TeHdr\r
200 );\r
201 if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
202 return EFI_UNSUPPORTED;\r
203 }\r
204\r
205 ImageContext->IsTeImage = TRUE;\r
206 }\r
207\r
208 return EFI_SUCCESS;\r
209}\r
210\r
211STATIC\r
212EFI_STATUS\r
213PeCoffLoaderCheckImageType (\r
214 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
215 IN EFI_IMAGE_NT_HEADERS *PeHdr,\r
216 IN EFI_TE_IMAGE_HEADER *TeHdr\r
217 )\r
218/*++\r
219\r
220Routine Description:\r
221\r
222 Checks the PE or TE header of a PE/COFF or TE image to determine if it supported\r
223\r
224Arguments:\r
225\r
226 ImageContext - The context of the image being loaded\r
227\r
228 PeHdr - The buffer in which to return the PE header\r
229 \r
230 TeHdr - The buffer in which to return the TE header\r
231\r
232Returns:\r
233\r
234 EFI_SUCCESS if the PE/COFF or TE image is supported\r
235 EFI_UNSUPPORTED of the PE/COFF or TE image is not supported.\r
236\r
237--*/\r
238{\r
239 //\r
240 // See if the machine type is supported. We support a native machine type (IA-32/Itanium-based)\r
241 // and the machine type for the Virtual Machine.\r
242 //\r
243 if (ImageContext->IsTeImage == FALSE) {\r
244 ImageContext->Machine = PeHdr->FileHeader.Machine;\r
245 } else {\r
246 ImageContext->Machine = TeHdr->Machine;\r
247 }\r
248\r
249 if (!(EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {\r
250 ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_MACHINE_TYPE;\r
251 return EFI_UNSUPPORTED;\r
252 }\r
253\r
254 //\r
255 // See if the image type is supported. We support EFI Applications,\r
256 // EFI Boot Service Drivers, and EFI Runtime Drivers.\r
257 //\r
258 if (ImageContext->IsTeImage == FALSE) {\r
259 ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;\r
260 } else {\r
261 ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);\r
262 }\r
263\r
264 switch (ImageContext->ImageType) {\r
265\r
266 case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:\r
267 ImageContext->ImageCodeMemoryType = EfiLoaderCode;\r
268 ImageContext->ImageDataMemoryType = EfiLoaderData;\r
269 break;\r
270\r
271 case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:\r
272 ImageContext->ImageCodeMemoryType = EfiBootServicesCode;\r
273 ImageContext->ImageDataMemoryType = EfiBootServicesData;\r
274 break;\r
275\r
276 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
277 case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:\r
278 ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;\r
279 ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;\r
280 break;\r
281\r
282 default:\r
283 ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_SUBSYSTEM;\r
284 return EFI_UNSUPPORTED;\r
285 }\r
286\r
287 return EFI_SUCCESS;\r
288}\r
289\r
290EFI_STATUS\r
291EFIAPI\r
292PeCoffLoaderGetImageInfo (\r
293 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
294 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
295 )\r
296/*++\r
297\r
298Routine Description:\r
299\r
300 Retrieves information on a PE/COFF image\r
301\r
302Arguments:\r
303\r
304 This - Calling context\r
305 ImageContext - The context of the image being loaded\r
306\r
307Returns:\r
308\r
309 EFI_SUCCESS - The information on the PE/COFF image was collected.\r
310 EFI_INVALID_PARAMETER - ImageContext is NULL.\r
311 EFI_UNSUPPORTED - The PE/COFF image is not supported.\r
312 Otherwise - The error status from reading the PE/COFF image using the\r
313 ImageContext->ImageRead() function\r
314\r
315--*/\r
316{\r
317 EFI_STATUS Status;\r
318 EFI_IMAGE_NT_HEADERS PeHdr;\r
319 EFI_TE_IMAGE_HEADER TeHdr;\r
320 EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;\r
321 UINTN Size;\r
322 UINTN Index;\r
323 UINTN DebugDirectoryEntryRva;\r
324 UINTN DebugDirectoryEntryFileOffset;\r
325 UINTN SectionHeaderOffset;\r
326 EFI_IMAGE_SECTION_HEADER SectionHeader;\r
327 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
328\r
329 if (NULL == ImageContext) {\r
330 return EFI_INVALID_PARAMETER;\r
331 }\r
332 //\r
333 // Assume success\r
334 //\r
335 ImageContext->ImageError = EFI_IMAGE_ERROR_SUCCESS;\r
336\r
337 Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr);\r
338 if (EFI_ERROR (Status)) {\r
339 return Status;\r
340 }\r
341 //\r
342 // Verify machine type\r
343 //\r
344 Status = PeCoffLoaderCheckImageType (ImageContext, &PeHdr, &TeHdr);\r
345 if (EFI_ERROR (Status)) {\r
346 return Status;\r
347 }\r
348 //\r
349 // Retrieve the base address of the image\r
350 //\r
351 if (!(ImageContext->IsTeImage)) {\r
352 ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;\r
353 } else {\r
354 ImageContext->ImageAddress = (EFI_PHYSICAL_ADDRESS) (TeHdr.ImageBase);\r
355 }\r
356 //\r
357 // Initialize the alternate destination address to 0 indicating that it\r
358 // should not be used.\r
359 //\r
360 ImageContext->DestinationAddress = 0;\r
361\r
362 //\r
363 // Initialize the codeview pointer.\r
364 //\r
365 ImageContext->CodeView = NULL;\r
366 ImageContext->PdbPointer = NULL;\r
367\r
368 //\r
369 // Three cases with regards to relocations:\r
370 // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable\r
371 // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable\r
372 // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but\r
373 // has no base relocs to apply\r
374 // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.\r
375 //\r
376 // Look at the file header to determine if relocations have been stripped, and\r
377 // save this info in the image context for later use.\r
378 //\r
379 if ((!(ImageContext->IsTeImage)) && ((PeHdr.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
380 ImageContext->RelocationsStripped = TRUE;\r
381 } else {\r
382 ImageContext->RelocationsStripped = FALSE;\r
383 }\r
384\r
385 if (!(ImageContext->IsTeImage)) {\r
386 ImageContext->ImageSize = (UINT64) PeHdr.OptionalHeader.SizeOfImage;\r
387 ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment;\r
388 ImageContext->SizeOfHeaders = PeHdr.OptionalHeader.SizeOfHeaders;\r
389\r
390 //\r
391 // Modify ImageSize to contain .PDB file name if required and initialize\r
392 // PdbRVA field...\r
393 //\r
394 if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
395 DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
396\r
397 DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
398\r
399 //\r
400 // Determine the file offset of the debug directory... This means we walk\r
401 // the sections to find which section contains the RVA of the debug\r
402 // directory\r
403 //\r
404 DebugDirectoryEntryFileOffset = 0;\r
405\r
406 SectionHeaderOffset = (UINTN)(\r
407 ImageContext->PeCoffHeaderOffset +\r
408 sizeof (UINT32) + \r
409 sizeof (EFI_IMAGE_FILE_HEADER) + \r
410 PeHdr.FileHeader.SizeOfOptionalHeader\r
411 );\r
412\r
413 for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index++) {\r
414 //\r
415 // Read section header from file\r
416 //\r
417 Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
418 Status = ImageContext->ImageRead (\r
419 ImageContext->Handle,\r
420 SectionHeaderOffset,\r
421 &Size,\r
422 &SectionHeader\r
423 );\r
424 if (EFI_ERROR (Status)) {\r
425 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
426 return Status;\r
427 }\r
428\r
429 if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&\r
430 DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
431 DebugDirectoryEntryFileOffset =\r
432 DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;\r
433 break;\r
434 }\r
435\r
436 SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
437 }\r
438\r
439 if (DebugDirectoryEntryFileOffset != 0) {\r
440 for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {\r
441 //\r
442 // Read next debug directory entry\r
443 //\r
444 Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
445 Status = ImageContext->ImageRead (\r
446 ImageContext->Handle,\r
447 DebugDirectoryEntryFileOffset,\r
448 &Size,\r
449 &DebugEntry\r
450 );\r
451 if (EFI_ERROR (Status)) {\r
452 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
453 return Status;\r
454 }\r
455\r
456 if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
457 ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
458 if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {\r
459 ImageContext->ImageSize += DebugEntry.SizeOfData;\r
460 }\r
461\r
462 return EFI_SUCCESS;\r
463 }\r
464 }\r
465 }\r
466 }\r
467 } else {\r
468 ImageContext->ImageSize = 0;\r
469 ImageContext->SectionAlignment = 4096;\r
470 ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr.BaseOfCode - (UINTN) TeHdr.StrippedSize;\r
471\r
472 DebugDirectoryEntry = &TeHdr.DataDirectory[1];\r
473 DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
474 SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));\r
475\r
476 DebugDirectoryEntryFileOffset = 0;\r
477\r
478 for (Index = 0; Index < TeHdr.NumberOfSections;) {\r
479 //\r
480 // Read section header from file\r
481 //\r
482 Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
483 Status = ImageContext->ImageRead (\r
484 ImageContext->Handle,\r
485 SectionHeaderOffset,\r
486 &Size,\r
487 &SectionHeader\r
488 );\r
489 if (EFI_ERROR (Status)) {\r
490 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
491 return Status;\r
492 }\r
493\r
494 if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&\r
495 DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
496 DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -\r
497 SectionHeader.VirtualAddress +\r
498 SectionHeader.PointerToRawData +\r
499 sizeof (EFI_TE_IMAGE_HEADER) -\r
500 TeHdr.StrippedSize;\r
501\r
502 //\r
503 // File offset of the debug directory was found, if this is not the last\r
504 // section, then skip to the last section for calculating the image size.\r
505 //\r
506 if (Index < (UINTN) TeHdr.NumberOfSections - 1) {\r
507 SectionHeaderOffset += (TeHdr.NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);\r
508 Index = TeHdr.NumberOfSections - 1;\r
509 continue;\r
510 }\r
511 }\r
512\r
513 //\r
514 // In Te image header there is not a field to describe the ImageSize.\r
515 // Actually, the ImageSize equals the RVA plus the VirtualSize of \r
516 // the last section mapped into memory (Must be rounded up to \r
517 // a mulitple of Section Alignment). Per the PE/COFF specification, the\r
518 // section headers in the Section Table must appear in order of the RVA\r
519 // values for the corresponding sections. So the ImageSize can be determined\r
520 // by the RVA and the VirtualSize of the last section header in the\r
521 // Section Table.\r
522 //\r
523 if ((++Index) == (UINTN) TeHdr.NumberOfSections) {\r
524 ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +\r
525 ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);\r
526 }\r
527\r
528 SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
529 }\r
530\r
531 if (DebugDirectoryEntryFileOffset != 0) {\r
532 for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {\r
533 //\r
534 // Read next debug directory entry\r
535 //\r
536 Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
537 Status = ImageContext->ImageRead (\r
538 ImageContext->Handle,\r
539 DebugDirectoryEntryFileOffset,\r
540 &Size,\r
541 &DebugEntry\r
542 );\r
543 if (EFI_ERROR (Status)) {\r
544 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
545 return Status;\r
546 }\r
547\r
548 if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
549 ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
550 return EFI_SUCCESS;\r
551 }\r
552 }\r
553 }\r
554 }\r
555\r
556 return EFI_SUCCESS;\r
557}\r
558\r
559STATIC\r
560VOID *\r
561PeCoffLoaderImageAddress (\r
562 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
563 IN UINTN Address\r
564 )\r
565/*++\r
566\r
567Routine Description:\r
568\r
569 Converts an image address to the loaded address\r
570\r
571Arguments:\r
572\r
573 ImageContext - The context of the image being loaded\r
574\r
575 Address - The address to be converted to the loaded address\r
576\r
577Returns:\r
578\r
579 NULL if the address can not be converted, otherwise, the converted address\r
580\r
581--*/\r
582{\r
583 if (Address >= ImageContext->ImageSize) {\r
584 ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
585 return NULL;\r
586 }\r
587\r
588 return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address);\r
589}\r
590\r
591EFI_STATUS\r
592EFIAPI\r
593PeCoffLoaderRelocateImage (\r
594 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
595 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
596 )\r
597/*++\r
598\r
599Routine Description:\r
600\r
601 Relocates a PE/COFF image in memory\r
602\r
603Arguments:\r
604\r
605 This - Calling context\r
606\r
607 ImageContext - Contains information on the loaded image to relocate\r
608\r
609Returns:\r
610\r
611 EFI_SUCCESS if the PE/COFF image was relocated\r
612 EFI_LOAD_ERROR if the image is not a valid PE/COFF image\r
613 EFI_UNSUPPORTED not support\r
614\r
615--*/\r
616{\r
617 EFI_STATUS Status;\r
618 EFI_IMAGE_NT_HEADERS *PeHdr;\r
619 EFI_TE_IMAGE_HEADER *TeHdr;\r
620 EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
621 UINT64 Adjust;\r
622 EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
623 EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
624 UINT16 *Reloc;\r
625 UINT16 *RelocEnd;\r
626 CHAR8 *Fixup;\r
627 CHAR8 *FixupBase;\r
628 UINT16 *F16;\r
629 UINT32 *F32;\r
630 CHAR8 *FixupData;\r
631 EFI_PHYSICAL_ADDRESS BaseAddress;\r
632\r
633 PeHdr = NULL;\r
634 TeHdr = NULL;\r
635 //\r
636 // Assume success\r
637 //\r
638 ImageContext->ImageError = EFI_IMAGE_ERROR_SUCCESS;\r
639\r
640 //\r
641 // If there are no relocation entries, then we are done\r
642 //\r
643 if (ImageContext->RelocationsStripped) {\r
644 return EFI_SUCCESS;\r
645 }\r
646\r
647 //\r
648 // If the destination address is not 0, use that rather than the\r
649 // image address as the relocation target.\r
650 //\r
651 if (ImageContext->DestinationAddress) {\r
652 BaseAddress = ImageContext->DestinationAddress;\r
653 } else {\r
654 BaseAddress = ImageContext->ImageAddress;\r
655 }\r
656\r
657 if (!(ImageContext->IsTeImage)) {\r
658 PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + \r
659 ImageContext->PeCoffHeaderOffset);\r
660 Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;\r
661 PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress;\r
662\r
663 //\r
664 // Find the relocation block\r
665 //\r
666 // Per the PE/COFF spec, you can't assume that a given data directory\r
667 // is present in the image. You have to check the NumberOfRvaAndSizes in\r
668 // the optional header to verify a desired directory entry is there.\r
669 //\r
670 if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
671 RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
672 RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
673 RelocBaseEnd = PeCoffLoaderImageAddress (\r
674 ImageContext,\r
675 RelocDir->VirtualAddress + RelocDir->Size - 1\r
676 );\r
677 } else {\r
678 //\r
679 // Set base and end to bypass processing below.\r
680 //\r
681 RelocBase = RelocBaseEnd = 0;\r
682 }\r
683 } else {\r
684 TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
685 Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase);\r
686 TeHdr->ImageBase = (UINT64) (BaseAddress);\r
687\r
688 //\r
689 // Find the relocation block\r
690 //\r
691 RelocDir = &TeHdr->DataDirectory[0];\r
692 RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
693 ImageContext->ImageAddress + \r
694 RelocDir->VirtualAddress +\r
695 sizeof(EFI_TE_IMAGE_HEADER) - \r
696 TeHdr->StrippedSize\r
697 );\r
698 RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
699 }\r
700 \r
701 //\r
702 // Run the relocation information and apply the fixups\r
703 //\r
704 FixupData = ImageContext->FixupData;\r
705 while (RelocBase < RelocBaseEnd) {\r
706\r
707 Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
708 RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
709 if (!(ImageContext->IsTeImage)) {\r
710 FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
711 } else {\r
712 FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
713 RelocBase->VirtualAddress +\r
714 sizeof(EFI_TE_IMAGE_HEADER) - \r
715 TeHdr->StrippedSize\r
716 );\r
717 }\r
718\r
719 if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||\r
720 (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + \r
721 (UINTN)ImageContext->ImageSize)) {\r
722 ImageContext->ImageError = EFI_IMAGE_ERROR_FAILED_RELOCATION;\r
723 return EFI_LOAD_ERROR;\r
724 }\r
725\r
726 //\r
727 // Run this relocation record\r
728 //\r
729 while (Reloc < RelocEnd) {\r
730\r
731 Fixup = FixupBase + (*Reloc & 0xFFF);\r
732 switch ((*Reloc) >> 12) {\r
733 case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
734 break;\r
735\r
736 case EFI_IMAGE_REL_BASED_HIGH:\r
737 F16 = (UINT16 *) Fixup;\r
738 *F16 = (UINT16) ((*F16 << 16) + (UINT16) Adjust);\r
739 if (FixupData != NULL) {\r
740 *(UINT16 *) FixupData = *F16;\r
741 FixupData = FixupData + sizeof (UINT16);\r
742 }\r
743 break;\r
744\r
745 case EFI_IMAGE_REL_BASED_LOW:\r
746 F16 = (UINT16 *) Fixup;\r
747 *F16 = (UINT16) (*F16 + (UINT16) Adjust);\r
748 if (FixupData != NULL) {\r
749 *(UINT16 *) FixupData = *F16;\r
750 FixupData = FixupData + sizeof (UINT16);\r
751 }\r
752 break;\r
753\r
754 case EFI_IMAGE_REL_BASED_HIGHLOW:\r
755 F32 = (UINT32 *) Fixup;\r
756 *F32 = *F32 + (UINT32) Adjust;\r
757 if (FixupData != NULL) {\r
758 FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));\r
759 *(UINT32 *) FixupData = *F32;\r
760 FixupData = FixupData + sizeof (UINT32);\r
761 }\r
762 break;\r
763\r
764 case EFI_IMAGE_REL_BASED_HIGHADJ:\r
765 //\r
766 // Return the same EFI_UNSUPPORTED return code as\r
767 // PeCoffLoaderRelocateImageEx() returns if it does not recognize\r
768 // the relocation type.\r
769 //\r
770 ImageContext->ImageError = EFI_IMAGE_ERROR_FAILED_RELOCATION;\r
771 return EFI_UNSUPPORTED;\r
772\r
773 default:\r
774 Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);\r
775 if (EFI_ERROR (Status)) {\r
776 ImageContext->ImageError = EFI_IMAGE_ERROR_FAILED_RELOCATION;\r
777 return Status;\r
778 }\r
779 }\r
780\r
781 //\r
782 // Next relocation record\r
783 //\r
784 Reloc += 1;\r
785 }\r
786\r
787 //\r
788 // Next reloc block\r
789 //\r
790 RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
791 }\r
792\r
793 return EFI_SUCCESS;\r
794}\r
795\r
796EFI_STATUS\r
797EFIAPI\r
798PeCoffLoaderLoadImage (\r
799 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,\r
800 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
801 )\r
802/*++\r
803\r
804Routine Description:\r
805\r
806 Loads a PE/COFF image into memory\r
807\r
808Arguments:\r
809\r
810 This - Calling context\r
811\r
812 ImageContext - Contains information on image to load into memory\r
813\r
814Returns:\r
815\r
816 EFI_SUCCESS if the PE/COFF image was loaded\r
817 EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer\r
818 EFI_LOAD_ERROR if the image is a runtime driver with no relocations\r
819 EFI_INVALID_PARAMETER if the image address is invalid\r
820\r
821--*/\r
822{\r
823 EFI_STATUS Status;\r
824 EFI_IMAGE_NT_HEADERS *PeHdr;\r
825 EFI_TE_IMAGE_HEADER *TeHdr;\r
826 EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT CheckContext;\r
827 EFI_IMAGE_SECTION_HEADER *FirstSection;\r
828 EFI_IMAGE_SECTION_HEADER *Section;\r
829 UINTN NumberOfSections;\r
830 UINTN Index;\r
831 CHAR8 *Base;\r
832 CHAR8 *End;\r
833 CHAR8 *MaxEnd;\r
834 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
835 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
836 UINTN Size;\r
837 UINT32 TempDebugEntryRva;\r
838\r
839 PeHdr = NULL;\r
840 TeHdr = NULL;\r
841 //\r
842 // Assume success\r
843 //\r
844 ImageContext->ImageError = EFI_IMAGE_ERROR_SUCCESS;\r
845\r
846 //\r
847 // Copy the provided context info into our local version, get what we\r
848 // can from the original image, and then use that to make sure everything\r
849 // is legit.\r
850 //\r
851 CopyMem (&CheckContext, ImageContext, sizeof (EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT));\r
852\r
853 Status = PeCoffLoaderGetImageInfo (\r
854 This,\r
855 &CheckContext\r
856 );\r
857 if (EFI_ERROR (Status)) {\r
858 return Status;\r
859 }\r
860\r
861 //\r
862 // Make sure there is enough allocated space for the image being loaded\r
863 //\r
864 if (ImageContext->ImageSize < CheckContext.ImageSize) {\r
865 ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_IMAGE_SIZE;\r
866 return EFI_BUFFER_TOO_SMALL;\r
867 }\r
868\r
869 //\r
870 // If there's no relocations, then make sure it's not a runtime driver,\r
871 // and that it's being loaded at the linked address.\r
872 //\r
873 if (CheckContext.RelocationsStripped) {\r
874 //\r
875 // If the image does not contain relocations and it is a runtime driver\r
876 // then return an error.\r
877 //\r
878 if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {\r
879 ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_SUBSYSTEM;\r
880 return EFI_LOAD_ERROR;\r
881 }\r
882 //\r
883 // If the image does not contain relocations, and the requested load address\r
884 // is not the linked address, then return an error.\r
885 //\r
886 if (CheckContext.ImageAddress != ImageContext->ImageAddress) {\r
887 ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
888 return EFI_INVALID_PARAMETER;\r
889 }\r
890 }\r
891 //\r
892 // Make sure the allocated space has the proper section alignment\r
893 //\r
894 if (!(ImageContext->IsTeImage)) {\r
895 if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {\r
896 ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;\r
897 return EFI_INVALID_PARAMETER;\r
898 }\r
899 }\r
900 //\r
901 // Read the entire PE/COFF or TE header into memory\r
902 //\r
903 if (!(ImageContext->IsTeImage)) {\r
904 Status = ImageContext->ImageRead (\r
905 ImageContext->Handle,\r
906 0,\r
907 &ImageContext->SizeOfHeaders,\r
908 (VOID *) (UINTN) ImageContext->ImageAddress\r
909 );\r
910\r
911 PeHdr = (EFI_IMAGE_NT_HEADERS *)\r
912 ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
913\r
914 FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
915 (UINTN)ImageContext->ImageAddress +\r
916 ImageContext->PeCoffHeaderOffset +\r
917 sizeof(UINT32) + \r
918 sizeof(EFI_IMAGE_FILE_HEADER) + \r
919 PeHdr->FileHeader.SizeOfOptionalHeader\r
920 );\r
921 NumberOfSections = (UINTN) (PeHdr->FileHeader.NumberOfSections);\r
922 } else {\r
923 Status = ImageContext->ImageRead (\r
924 ImageContext->Handle,\r
925 0,\r
926 &ImageContext->SizeOfHeaders,\r
927 (void *) (UINTN) ImageContext->ImageAddress\r
928 );\r
929\r
930 TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
931\r
932 FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
933 (UINTN)ImageContext->ImageAddress +\r
934 sizeof(EFI_TE_IMAGE_HEADER)\r
935 );\r
936 NumberOfSections = (UINTN) (TeHdr->NumberOfSections);\r
937\r
938 }\r
939\r
940 if (EFI_ERROR (Status)) {\r
941 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
942 return EFI_LOAD_ERROR;\r
943 }\r
944\r
945 //\r
946 // Load each section of the image\r
947 //\r
948 Section = FirstSection;\r
949 for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {\r
950\r
951 //\r
952 // Compute sections address\r
953 //\r
954 Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);\r
955 End = PeCoffLoaderImageAddress (\r
956 ImageContext,\r
957 Section->VirtualAddress + Section->Misc.VirtualSize - 1\r
958 );\r
959 if (ImageContext->IsTeImage) {\r
960 Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
961 End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
962 }\r
963\r
964 if (End > MaxEnd) {\r
965 MaxEnd = End;\r
966 }\r
967 //\r
968 // If the base start or end address resolved to 0, then fail.\r
969 //\r
970 if ((Base == NULL) || (End == NULL)) {\r
971 ImageContext->ImageError = EFI_IMAGE_ERROR_SECTION_NOT_LOADED;\r
972 return EFI_LOAD_ERROR;\r
973 }\r
974\r
975 //\r
976 // Read the section\r
977 //\r
978 Size = (UINTN) Section->Misc.VirtualSize;\r
979 if ((Size == 0) || (Size > Section->SizeOfRawData)) {\r
980 Size = (UINTN) Section->SizeOfRawData;\r
981 }\r
982\r
983 if (Section->SizeOfRawData) {\r
984 if (!(ImageContext->IsTeImage)) {\r
985 Status = ImageContext->ImageRead (\r
986 ImageContext->Handle,\r
987 Section->PointerToRawData,\r
988 &Size,\r
989 Base\r
990 );\r
991 } else {\r
992 Status = ImageContext->ImageRead (\r
993 ImageContext->Handle,\r
994 Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize,\r
995 &Size,\r
996 Base\r
997 );\r
998 }\r
999\r
1000 if (EFI_ERROR (Status)) {\r
1001 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
1002 return Status;\r
1003 }\r
1004 }\r
1005\r
1006 //\r
1007 // If raw size is less then virt size, zero fill the remaining\r
1008 //\r
1009\r
1010 if (Size < Section->Misc.VirtualSize) {\r
1011 ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);\r
1012 }\r
1013\r
1014 //\r
1015 // Next Section\r
1016 //\r
1017 Section += 1;\r
1018 }\r
1019\r
1020 //\r
1021 // Get image's entry point\r
1022 //\r
1023 if (!(ImageContext->IsTeImage)) {\r
1024 ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (\r
1025 ImageContext,\r
1026 PeHdr->OptionalHeader.AddressOfEntryPoint\r
1027 );\r
1028 } else {\r
1029 ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (\r
1030 (UINTN)ImageContext->ImageAddress +\r
1031 (UINTN)TeHdr->AddressOfEntryPoint +\r
1032 (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
1033 (UINTN) TeHdr->StrippedSize\r
1034 );\r
1035 }\r
1036\r
1037 //\r
1038 // Determine the size of the fixup data\r
1039 //\r
1040 // Per the PE/COFF spec, you can't assume that a given data directory\r
1041 // is present in the image. You have to check the NumberOfRvaAndSizes in\r
1042 // the optional header to verify a desired directory entry is there.\r
1043 //\r
1044 if (!(ImageContext->IsTeImage)) {\r
1045 if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
1046 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
1047 &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
1048 ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
1049 } else {\r
1050 ImageContext->FixupDataSize = 0;\r
1051 }\r
1052 } else {\r
1053 DirectoryEntry = &TeHdr->DataDirectory[0];\r
1054 ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
1055 }\r
1056 //\r
1057 // Consumer must allocate a buffer for the relocation fixup log.\r
1058 // Only used for runtime drivers.\r
1059 //\r
1060 ImageContext->FixupData = NULL;\r
1061\r
1062 //\r
1063 // Load the Codeview info if present\r
1064 //\r
1065 if (ImageContext->DebugDirectoryEntryRva != 0) {\r
1066 if (!(ImageContext->IsTeImage)) {\r
1067 DebugEntry = PeCoffLoaderImageAddress (\r
1068 ImageContext,\r
1069 ImageContext->DebugDirectoryEntryRva\r
1070 );\r
1071 } else {\r
1072 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
1073 ImageContext->ImageAddress +\r
1074 ImageContext->DebugDirectoryEntryRva +\r
1075 sizeof(EFI_TE_IMAGE_HEADER) -\r
1076 TeHdr->StrippedSize\r
1077 );\r
1078 }\r
1079\r
1080 if (DebugEntry != NULL) {\r
1081 TempDebugEntryRva = DebugEntry->RVA;\r
1082 if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {\r
1083 Section--;\r
1084 if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
1085 TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;\r
1086 } else {\r
1087 TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;\r
1088 }\r
1089 }\r
1090\r
1091 if (TempDebugEntryRva != 0) {\r
1092 if (!(ImageContext->IsTeImage)) {\r
1093 ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);\r
1094 } else {\r
1095 ImageContext->CodeView = (VOID *)(\r
1096 (UINTN)ImageContext->ImageAddress +\r
1097 (UINTN)TempDebugEntryRva +\r
1098 (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
1099 (UINTN) TeHdr->StrippedSize\r
1100 );\r
1101 }\r
1102\r
1103 if (ImageContext->CodeView == NULL) {\r
1104 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
1105 return EFI_LOAD_ERROR;\r
1106 }\r
1107\r
1108 if (DebugEntry->RVA == 0) {\r
1109 Size = DebugEntry->SizeOfData;\r
1110 if (!(ImageContext->IsTeImage)) {\r
1111 Status = ImageContext->ImageRead (\r
1112 ImageContext->Handle,\r
1113 DebugEntry->FileOffset,\r
1114 &Size,\r
1115 ImageContext->CodeView\r
1116 );\r
1117 } else {\r
1118 Status = ImageContext->ImageRead (\r
1119 ImageContext->Handle,\r
1120 DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize,\r
1121 &Size,\r
1122 ImageContext->CodeView\r
1123 );\r
1124 //\r
1125 // Should we apply fix up to this field according to the size difference between PE and TE?\r
1126 // Because now we maintain TE header fields unfixed, this field will also remain as they are\r
1127 // in original PE image.\r
1128 //\r
1129 }\r
1130\r
1131 if (EFI_ERROR (Status)) {\r
1132 ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;\r
1133 return EFI_LOAD_ERROR;\r
1134 }\r
1135\r
1136 DebugEntry->RVA = TempDebugEntryRva;\r
1137 }\r
1138\r
1139 switch (*(UINT32 *) ImageContext->CodeView) {\r
1140 case CODEVIEW_SIGNATURE_NB10:\r
1141 ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
1142 break;\r
1143\r
1144 case CODEVIEW_SIGNATURE_RSDS:\r
1145 ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
1146 break;\r
1147\r
1148 default:\r
1149 break;\r
1150 }\r
1151 }\r
1152 }\r
1153 }\r
1154\r
1155 return Status;\r
1156}\r
1157\r
1158EFI_STATUS\r
1159EFIAPI\r
1160PeCoffLoaderUnloadImage (\r
1161 IN EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
1162 )\r
1163/*++\r
1164\r
1165Routine Description:\r
1166\r
1167 Unload a PE/COFF image from memory\r
1168\r
1169Arguments:\r
1170\r
1171 ImageContext - Contains information on image to load into memory\r
1172\r
1173Returns:\r
1174\r
1175 EFI_SUCCESS \r
1176\r
1177--*/\r
1178{\r
1179 return EFI_SUCCESS;\r
1180}\r