3 Copyright (c) 2005 - 2010, 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
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.
27 #include "PeCoffLoaderEx.h"
29 #ifdef EFI_NT_EMULATOR
31 #include "EfiHobLib.h"
32 #include EFI_PPI_DEFINITION (NtLoadAsDll)
37 PeCoffLoaderGetPeHeader (
38 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
,
39 OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
44 PeCoffLoaderImageAddress (
45 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
,
51 PeCoffLoaderGetImageInfo (
52 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*This
,
53 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
58 PeCoffLoaderRelocateImage (
59 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*This
,
60 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
65 PeCoffLoaderLoadImage (
66 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*This
,
67 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
72 PeCoffLoaderUnloadImage (
73 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
76 #if defined (EFI_DEBUG_ITP_BREAK) && !defined (_CONSOLE)
78 AsmEfiSetBreakSupport (
83 EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoader
= {
84 PeCoffLoaderGetImageInfo
,
85 PeCoffLoaderLoadImage
,
86 PeCoffLoaderRelocateImage
,
87 PeCoffLoaderUnloadImage
90 #ifdef EFI_NT_EMULATOR
91 EFI_NT_LOAD_AS_DLL_PPI
*mPeCoffLoaderWinNtLoadAsDll
= NULL
;
95 InstallEfiPeiPeCoffLoader (
96 IN EFI_PEI_SERVICES
**PeiServices
,
97 IN OUT EFI_PEI_PE_COFF_LOADER_PROTOCOL
**This
,
98 IN EFI_PEI_PPI_DESCRIPTOR
*ThisPpi
104 Install PE/COFF loader PPI
108 PeiServices - General purpose services available to every PEIM
110 This - Pointer to get Pei PE coff loader protocol as output
112 ThisPpi - Passed in as EFI_NT_LOAD_AS_DLL_PPI on NT_EMULATOR platform
122 Status
= EFI_SUCCESS
;
124 #ifdef EFI_NT_EMULATOR
126 // For use by PEI Core and Modules
128 if (NULL
!= PeiServices
) {
129 Status
= (**PeiServices
).LocatePpi (
131 &gEfiNtLoadAsDllPpiGuid
,
134 &mPeCoffLoaderWinNtLoadAsDll
138 // Now in SecMain or ERM usage, bind appropriately
140 PEI_ASSERT (PeiServices
, (NULL
!= ThisPpi
));
142 mPeCoffLoaderWinNtLoadAsDll
= (EFI_NT_LOAD_AS_DLL_PPI
*) ThisPpi
;
143 PEI_ASSERT (PeiServices
, (NULL
!= mPeCoffLoaderWinNtLoadAsDll
));
148 *This
= &mPeCoffLoader
;
156 PeCoffLoaderGetPeHeader (
157 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
,
158 OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
164 Retrieves the PE or TE Header from a PE/COFF or TE image
168 ImageContext - The context of the image being loaded
170 PeHdr - The buffer in which to return the PE32, PE32+, or TE header
174 EFI_SUCCESS if the PE or TE Header is read,
175 Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.
180 EFI_IMAGE_DOS_HEADER DosHdr
;
185 // Read the DOS image header to check for it's existance
187 Size
= sizeof (EFI_IMAGE_DOS_HEADER
);
188 Status
= ImageContext
->ImageRead (
189 ImageContext
->Handle
,
194 if (EFI_ERROR (Status
)) {
195 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
199 ImageContext
->PeCoffHeaderOffset
= 0;
200 if (DosHdr
.e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
202 // DOS image header is present, so read the PE header after the DOS image
205 ImageContext
->PeCoffHeaderOffset
= DosHdr
.e_lfanew
;
209 // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much
210 // data, but that should not hurt anythine. Hdr.Pe32->OptionalHeader.Magic
211 // determins if this is a PE32 or PE32+ image. The magic is in the same
212 // location in both images.
214 Size
= sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION
);
215 Status
= ImageContext
->ImageRead (
216 ImageContext
->Handle
,
217 ImageContext
->PeCoffHeaderOffset
,
221 if (EFI_ERROR (Status
)) {
222 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
227 // Use Signature to figure out if we understand the image format
229 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
230 ImageContext
->IsTeImage
= TRUE
;
231 ImageContext
->Machine
= Hdr
.Te
->Machine
;
232 ImageContext
->ImageType
= (UINT16
)(Hdr
.Te
->Subsystem
);
233 ImageContext
->ImageSize
= 0;
234 ImageContext
->SectionAlignment
= 4096;
235 ImageContext
->SizeOfHeaders
= sizeof (EFI_TE_IMAGE_HEADER
) + (UINTN
)Hdr
.Te
->BaseOfCode
- (UINTN
)Hdr
.Te
->StrippedSize
;
237 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
238 ImageContext
->IsTeImage
= FALSE
;
239 ImageContext
->Machine
= Hdr
.Pe32
->FileHeader
.Machine
;
242 // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
243 // It is for backward-compatibility consideration, because
244 // some system will generate PE32+ image with PE32 Magic.
246 if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA32
) {
247 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
248 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA64
) {
249 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
250 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_X64
) {
251 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
253 Magic
= Hdr
.Pe32
->OptionalHeader
.Magic
;
256 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
||
257 Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
259 // PE32 and PE32+ have the same offset for these fields.
260 // We use PE32 for both PE32 and PE32+ headers here.
262 ImageContext
->ImageType
= Hdr
.Pe32
->OptionalHeader
.Subsystem
;
263 ImageContext
->ImageSize
= (UINT64
)Hdr
.Pe32
->OptionalHeader
.SizeOfImage
;
264 ImageContext
->SectionAlignment
= Hdr
.Pe32
->OptionalHeader
.SectionAlignment
;
265 ImageContext
->SizeOfHeaders
= Hdr
.Pe32
->OptionalHeader
.SizeOfHeaders
;
268 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_MACHINE_TYPE
;
269 return EFI_UNSUPPORTED
;
272 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_MACHINE_TYPE
;
273 return EFI_UNSUPPORTED
;
276 if (!PeCoffLoaderImageFormatSupported (ImageContext
->Machine
)) {
278 // If the PE/COFF loader does not support the image type return
279 // unsupported. This library can suport lots of types of images
280 // this does not mean the user of this library can call the entry
281 // point of the image.
283 return EFI_UNSUPPORTED
;
291 PeCoffLoaderCheckImageType (
292 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
298 Checks the PE or TE header of a PE/COFF or TE image to determine if it supported
302 ImageContext - The context of the image being loaded
306 EFI_SUCCESS if the PE/COFF or TE image is supported
307 EFI_UNSUPPORTED of the PE/COFF or TE image is not supported.
311 switch (ImageContext
->ImageType
) {
313 case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
:
314 ImageContext
->ImageCodeMemoryType
= EfiLoaderCode
;
315 ImageContext
->ImageDataMemoryType
= EfiLoaderData
;
318 case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
:
319 ImageContext
->ImageCodeMemoryType
= EfiBootServicesCode
;
320 ImageContext
->ImageDataMemoryType
= EfiBootServicesData
;
323 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
:
324 case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER
:
325 ImageContext
->ImageCodeMemoryType
= EfiRuntimeServicesCode
;
326 ImageContext
->ImageDataMemoryType
= EfiRuntimeServicesData
;
330 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_SUBSYSTEM
;
331 return EFI_UNSUPPORTED
;
339 PeCoffLoaderGetImageInfo (
340 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*This
,
341 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
347 Retrieves information on a PE/COFF image
351 This - Calling context
353 ImageContext - The context of the image being loaded
357 EFI_SUCCESS if the information on the PE/COFF image was collected.
358 EFI_UNSUPPORTED of the PE/COFF image is not supported.
359 Otherwise, the error status from reading the PE/COFF image using the
360 ImageContext->ImageRead() function
362 EFI_INVALID_PARAMETER - ImageContext is NULL.
367 EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData
;
368 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
369 EFI_IMAGE_DATA_DIRECTORY
*DebugDirectoryEntry
;
372 UINTN DebugDirectoryEntryRva
;
373 UINTN DebugDirectoryEntryFileOffset
;
374 UINTN SectionHeaderOffset
;
375 EFI_IMAGE_SECTION_HEADER SectionHeader
;
376 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry
;
377 UINT32 NumberOfRvaAndSizes
;
380 if (NULL
== ImageContext
) {
381 return EFI_INVALID_PARAMETER
;
387 ImageContext
->ImageError
= EFI_IMAGE_ERROR_SUCCESS
;
389 Hdr
.Union
= &HdrData
;
390 Status
= PeCoffLoaderGetPeHeader (ImageContext
, Hdr
);
391 if (EFI_ERROR (Status
)) {
396 // Verify machine type
398 Status
= PeCoffLoaderCheckImageType (ImageContext
);
399 if (EFI_ERROR (Status
)) {
403 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
406 // Retrieve the base address of the image
408 if (!(ImageContext
->IsTeImage
)) {
411 // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
412 // It is for backward-compatibility consideration, because
413 // some system will generate PE32+ image with PE32 Magic.
415 if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA32
) {
416 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
417 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA64
) {
418 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
419 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_X64
) {
420 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
422 Magic
= Hdr
.Pe32
->OptionalHeader
.Magic
;
425 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
429 ImageContext
->ImageAddress
= Hdr
.Pe32
->OptionalHeader
.ImageBase
;
434 ImageContext
->ImageAddress
= Hdr
.Pe32Plus
->OptionalHeader
.ImageBase
;
437 ImageContext
->ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(Hdr
.Te
->ImageBase
+ Hdr
.Te
->StrippedSize
- sizeof (EFI_TE_IMAGE_HEADER
));
441 // Initialize the alternate destination address to 0 indicating that it
442 // should not be used.
444 ImageContext
->DestinationAddress
= 0;
447 // Initialize the codeview pointer.
449 ImageContext
->CodeView
= NULL
;
450 ImageContext
->PdbPointer
= NULL
;
453 // Three cases with regards to relocations:
454 // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable
455 // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable
456 // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but
457 // has no base relocs to apply
458 // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.
460 // Look at the file header to determine if relocations have been stripped, and
461 // save this info in the image context for later use.
463 if ((!(ImageContext
->IsTeImage
)) && ((Hdr
.Pe32
->FileHeader
.Characteristics
& EFI_IMAGE_FILE_RELOCS_STRIPPED
) != 0)) {
464 ImageContext
->RelocationsStripped
= TRUE
;
466 ImageContext
->RelocationsStripped
= FALSE
;
469 if (!(ImageContext
->IsTeImage
)) {
471 // Use PE32 to access fields that have same offset in PE32 and PE32+
473 ImageContext
->ImageSize
= (UINT64
) Hdr
.Pe32
->OptionalHeader
.SizeOfImage
;
474 ImageContext
->SectionAlignment
= Hdr
.Pe32
->OptionalHeader
.SectionAlignment
;
475 ImageContext
->SizeOfHeaders
= Hdr
.Pe32
->OptionalHeader
.SizeOfHeaders
;
476 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
480 NumberOfRvaAndSizes
= Hdr
.Pe32
->OptionalHeader
.NumberOfRvaAndSizes
;
481 DebugDirectoryEntry
= (EFI_IMAGE_DATA_DIRECTORY
*)&(Hdr
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG
]);
486 NumberOfRvaAndSizes
= Hdr
.Pe32Plus
->OptionalHeader
.NumberOfRvaAndSizes
;
487 DebugDirectoryEntry
= (EFI_IMAGE_DATA_DIRECTORY
*)&(Hdr
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG
]);
490 if (NumberOfRvaAndSizes
> EFI_IMAGE_DIRECTORY_ENTRY_DEBUG
) {
492 DebugDirectoryEntryRva
= DebugDirectoryEntry
->VirtualAddress
;
495 // Determine the file offset of the debug directory... This means we walk
496 // the sections to find which section contains the RVA of the debug
499 DebugDirectoryEntryFileOffset
= 0;
501 SectionHeaderOffset
= (UINTN
)(
502 ImageContext
->PeCoffHeaderOffset
+
504 sizeof (EFI_IMAGE_FILE_HEADER
) +
505 Hdr
.Pe32
->FileHeader
.SizeOfOptionalHeader
508 for (Index
= 0; Index
< Hdr
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
510 // Read section header from file
512 Size
= sizeof (EFI_IMAGE_SECTION_HEADER
);
513 Status
= ImageContext
->ImageRead (
514 ImageContext
->Handle
,
519 if (EFI_ERROR (Status
)) {
520 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
524 if (DebugDirectoryEntryRva
>= SectionHeader
.VirtualAddress
&&
525 DebugDirectoryEntryRva
< SectionHeader
.VirtualAddress
+ SectionHeader
.Misc
.VirtualSize
) {
527 DebugDirectoryEntryFileOffset
= DebugDirectoryEntryRva
- SectionHeader
.VirtualAddress
+ SectionHeader
.PointerToRawData
;
531 SectionHeaderOffset
+= sizeof (EFI_IMAGE_SECTION_HEADER
);
534 if (DebugDirectoryEntryFileOffset
!= 0) {
535 for (Index
= 0; Index
< DebugDirectoryEntry
->Size
; Index
++) {
537 // Read next debug directory entry
539 Size
= sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
);
540 Status
= ImageContext
->ImageRead (
541 ImageContext
->Handle
,
542 DebugDirectoryEntryFileOffset
,
546 if (EFI_ERROR (Status
)) {
547 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
551 if (DebugEntry
.Type
== EFI_IMAGE_DEBUG_TYPE_CODEVIEW
) {
552 ImageContext
->DebugDirectoryEntryRva
= (UINT32
) (DebugDirectoryEntryRva
+ Index
* sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
));
553 if (DebugEntry
.RVA
== 0 && DebugEntry
.FileOffset
!= 0) {
554 ImageContext
->ImageSize
+= DebugEntry
.SizeOfData
;
564 // Because Te image only extracts base relocations and debug directory entries from
565 // Pe image and in Te image header there is not a field to describe the imagesize,
566 // we use the largest VirtualAddress plus Size in each directory entry to describe the imagesize
568 ImageContext
->ImageSize
= (UINT64
) (Hdr
.Te
->DataDirectory
[0].VirtualAddress
+ Hdr
.Te
->DataDirectory
[0].Size
);
569 ImageContext
->SectionAlignment
= 4096;
570 ImageContext
->SizeOfHeaders
= sizeof (EFI_TE_IMAGE_HEADER
) + (UINTN
) Hdr
.Te
->BaseOfCode
- (UINTN
) Hdr
.Te
->StrippedSize
;
572 DebugDirectoryEntry
= &Hdr
.Te
->DataDirectory
[1];
573 DebugDirectoryEntryRva
= DebugDirectoryEntry
->VirtualAddress
;
574 SectionHeaderOffset
= (UINTN
)(sizeof (EFI_TE_IMAGE_HEADER
));
576 DebugDirectoryEntryFileOffset
= 0;
578 for (Index
= 0; Index
< Hdr
.Te
->NumberOfSections
; Index
++) {
580 // Read section header from file
582 Size
= sizeof (EFI_IMAGE_SECTION_HEADER
);
583 Status
= ImageContext
->ImageRead (
584 ImageContext
->Handle
,
589 if (EFI_ERROR (Status
)) {
590 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
594 if (DebugDirectoryEntryRva
>= SectionHeader
.VirtualAddress
&&
595 DebugDirectoryEntryRva
< SectionHeader
.VirtualAddress
+ SectionHeader
.Misc
.VirtualSize
) {
596 DebugDirectoryEntryFileOffset
= DebugDirectoryEntryRva
-
597 SectionHeader
.VirtualAddress
+
598 SectionHeader
.PointerToRawData
+
599 sizeof (EFI_TE_IMAGE_HEADER
) -
600 Hdr
.Te
->StrippedSize
;
604 SectionHeaderOffset
+= sizeof (EFI_IMAGE_SECTION_HEADER
);
607 if (DebugDirectoryEntryFileOffset
!= 0) {
608 for (Index
= 0; Index
< DebugDirectoryEntry
->Size
; Index
++) {
610 // Read next debug directory entry
612 Size
= sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
);
613 Status
= ImageContext
->ImageRead (
614 ImageContext
->Handle
,
615 DebugDirectoryEntryFileOffset
,
619 if (EFI_ERROR (Status
)) {
620 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
624 if (DebugEntry
.Type
== EFI_IMAGE_DEBUG_TYPE_CODEVIEW
) {
625 ImageContext
->DebugDirectoryEntryRva
= (UINT32
) (DebugDirectoryEntryRva
+ Index
* sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
));
637 PeCoffLoaderImageAddress (
638 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
,
645 Converts an image address to the loaded address
649 ImageContext - The context of the image being loaded
651 Address - The address to be converted to the loaded address
655 NULL if the address can not be converted, otherwise, the converted address
659 if (Address
>= ImageContext
->ImageSize
) {
660 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS
;
664 return (CHAR8
*) ((UINTN
) ImageContext
->ImageAddress
+ Address
);
669 PeCoffLoaderRelocateImage (
670 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*This
,
671 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
677 Relocates a PE/COFF image in memory
681 This - Calling context
683 ImageContext - Contains information on the loaded image to relocate
687 EFI_SUCCESS if the PE/COFF image was relocated
688 EFI_LOAD_ERROR if the image is not a valid PE/COFF image
689 EFI_UNSUPPORTED not support
694 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
695 EFI_IMAGE_DATA_DIRECTORY
*RelocDir
;
697 EFI_IMAGE_BASE_RELOCATION
*RelocBase
;
698 EFI_IMAGE_BASE_RELOCATION
*RelocBaseEnd
;
707 EFI_PHYSICAL_ADDRESS BaseAddress
;
708 UINT32 NumberOfRvaAndSizes
;
710 #ifdef EFI_NT_EMULATOR
717 if (NULL
== ImageContext
) {
718 return EFI_INVALID_PARAMETER
;
724 ImageContext
->ImageError
= EFI_IMAGE_ERROR_SUCCESS
;
727 // If there are no relocation entries, then we are done
729 if (ImageContext
->RelocationsStripped
) {
734 // If the destination address is not 0, use that rather than the
735 // image address as the relocation target.
737 if (ImageContext
->DestinationAddress
!= 0) {
738 BaseAddress
= ImageContext
->DestinationAddress
;
740 BaseAddress
= ImageContext
->ImageAddress
;
743 if (!(ImageContext
->IsTeImage
)) {
744 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*)((UINTN
)ImageContext
->ImageAddress
+ ImageContext
->PeCoffHeaderOffset
);
747 // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
748 // It is for backward-compatibility consideration, because
749 // some system will generate PE32+ image with PE32 Magic.
751 if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA32
) {
752 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
753 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA64
) {
754 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
755 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_X64
) {
756 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
758 Magic
= Hdr
.Pe32
->OptionalHeader
.Magic
;
761 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
765 Adjust
= (UINT64
)BaseAddress
- Hdr
.Pe32
->OptionalHeader
.ImageBase
;
766 Hdr
.Pe32
->OptionalHeader
.ImageBase
= (UINT32
)BaseAddress
;
768 NumberOfRvaAndSizes
= Hdr
.Pe32
->OptionalHeader
.NumberOfRvaAndSizes
;
769 RelocDir
= &Hdr
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC
];
774 Adjust
= (UINT64
) BaseAddress
- Hdr
.Pe32Plus
->OptionalHeader
.ImageBase
;
775 Hdr
.Pe32Plus
->OptionalHeader
.ImageBase
= (UINT64
)BaseAddress
;
777 NumberOfRvaAndSizes
= Hdr
.Pe32Plus
->OptionalHeader
.NumberOfRvaAndSizes
;
778 RelocDir
= &Hdr
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC
];
782 // Find the relocation block
783 // Per the PE/COFF spec, you can't assume that a given data directory
784 // is present in the image. You have to check the NumberOfRvaAndSizes in
785 // the optional header to verify a desired directory entry is there.
788 if (NumberOfRvaAndSizes
> EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC
&& RelocDir
->Size
> 0) {
789 RelocBase
= PeCoffLoaderImageAddress (ImageContext
, RelocDir
->VirtualAddress
);
790 RelocBaseEnd
= PeCoffLoaderImageAddress (
792 RelocDir
->VirtualAddress
+ RelocDir
->Size
- 1
794 if ((RelocBase
== NULL
) || (RelocBaseEnd
== NULL
)) {
796 // If the base start or end address resolved to 0, then fail.
798 return EFI_LOAD_ERROR
;
802 // Set base and end to bypass processing below.
804 RelocBase
= RelocBaseEnd
= 0;
807 Hdr
.Te
= (EFI_TE_IMAGE_HEADER
*)(UINTN
)(ImageContext
->ImageAddress
);
808 Adjust
= (UINT64
) (BaseAddress
- Hdr
.Te
->StrippedSize
+ sizeof (EFI_TE_IMAGE_HEADER
) - Hdr
.Te
->ImageBase
);
809 Hdr
.Te
->ImageBase
= (UINT64
) (BaseAddress
- Hdr
.Te
->StrippedSize
+ sizeof (EFI_TE_IMAGE_HEADER
));
812 // Find the relocation block
814 RelocDir
= &Hdr
.Te
->DataDirectory
[0];
815 if (RelocDir
->Size
> 0) {
816 RelocBase
= (EFI_IMAGE_BASE_RELOCATION
*)(UINTN
)(
817 ImageContext
->ImageAddress
+
818 RelocDir
->VirtualAddress
+
819 sizeof(EFI_TE_IMAGE_HEADER
) -
822 RelocBaseEnd
= (EFI_IMAGE_BASE_RELOCATION
*) ((UINTN
) RelocBase
+ (UINTN
) RelocDir
->Size
- 1);
825 // Set base and end to bypass processing below.
833 // Run the relocation information and apply the fixups
835 FixupData
= ImageContext
->FixupData
;
836 while (RelocBase
< RelocBaseEnd
) {
838 Reloc
= (UINT16
*) ((CHAR8
*) RelocBase
+ sizeof (EFI_IMAGE_BASE_RELOCATION
));
839 RelocEnd
= (UINT16
*) ((CHAR8
*) RelocBase
+ RelocBase
->SizeOfBlock
);
840 if (!(ImageContext
->IsTeImage
)) {
841 FixupBase
= PeCoffLoaderImageAddress (ImageContext
, RelocBase
->VirtualAddress
);
843 if (FixupBase
== NULL
) {
845 // If the FixupBase address resolved to 0, then fail.
847 return EFI_LOAD_ERROR
;
850 FixupBase
= (CHAR8
*)(UINTN
)(ImageContext
->ImageAddress
+
851 RelocBase
->VirtualAddress
+
852 sizeof(EFI_TE_IMAGE_HEADER
) -
857 if ((CHAR8
*) RelocEnd
< (CHAR8
*) ((UINTN
) ImageContext
->ImageAddress
) ||
858 (CHAR8
*) RelocEnd
> (CHAR8
*)((UINTN
)ImageContext
->ImageAddress
+
859 (UINTN
)ImageContext
->ImageSize
)) {
860 ImageContext
->ImageError
= EFI_IMAGE_ERROR_FAILED_RELOCATION
;
861 return EFI_LOAD_ERROR
;
865 // Run this relocation record
867 while (Reloc
< RelocEnd
) {
869 Fixup
= FixupBase
+ (*Reloc
& 0xFFF);
870 switch ((*Reloc
) >> 12) {
871 case EFI_IMAGE_REL_BASED_ABSOLUTE
:
874 case EFI_IMAGE_REL_BASED_HIGH
:
875 F16
= (UINT16
*) Fixup
;
876 *F16
= (UINT16
) (*F16
+ (UINT16
)(((UINT32
)Adjust
) >> 16));
877 if (FixupData
!= NULL
) {
878 *(UINT16
*) FixupData
= *F16
;
879 FixupData
= FixupData
+ sizeof (UINT16
);
883 case EFI_IMAGE_REL_BASED_LOW
:
884 F16
= (UINT16
*) Fixup
;
885 *F16
= (UINT16
) (*F16
+ (UINT16
) Adjust
);
886 if (FixupData
!= NULL
) {
887 *(UINT16
*) FixupData
= *F16
;
888 FixupData
= FixupData
+ sizeof (UINT16
);
892 case EFI_IMAGE_REL_BASED_HIGHLOW
:
893 F32
= (UINT32
*) Fixup
;
894 *F32
= *F32
+ (UINT32
) Adjust
;
895 if (FixupData
!= NULL
) {
896 FixupData
= ALIGN_POINTER (FixupData
, sizeof (UINT32
));
897 *(UINT32
*) FixupData
= *F32
;
898 FixupData
= FixupData
+ sizeof (UINT32
);
902 case EFI_IMAGE_REL_BASED_DIR64
:
906 F64
= (UINT64
*) Fixup
;
907 *F64
= *F64
+ (UINT64
) Adjust
;
908 if (FixupData
!= NULL
) {
909 FixupData
= ALIGN_POINTER (FixupData
, sizeof(UINT64
));
910 *(UINT64
*)(FixupData
) = *F64
;
911 FixupData
= FixupData
+ sizeof(UINT64
);
915 case EFI_IMAGE_REL_BASED_HIGHADJ
:
917 // Return the same EFI_UNSUPPORTED return code as
918 // PeCoffLoaderRelocateImageEx() returns if it does not recognize
919 // the relocation type.
921 ImageContext
->ImageError
= EFI_IMAGE_ERROR_FAILED_RELOCATION
;
922 return EFI_UNSUPPORTED
;
926 // The common code does not handle some of the stranger IPF relocations
927 // PeCoffLoaderRelocateImageEx () addes support for these complex fixups
928 // on IPF and is a No-Op on other archtiectures.
930 Status
= PeCoffLoaderRelocateImageEx (Reloc
, Fixup
, &FixupData
, Adjust
);
931 if (EFI_ERROR (Status
)) {
932 ImageContext
->ImageError
= EFI_IMAGE_ERROR_FAILED_RELOCATION
;
938 // Next relocation record
946 RelocBase
= (EFI_IMAGE_BASE_RELOCATION
*) RelocEnd
;
949 #ifdef EFI_NT_EMULATOR
950 DllEntryPoint
= NULL
;
951 ImageContext
->ModHandle
= NULL
;
953 // Load the DLL if it's not an EBC image.
955 if ((ImageContext
->PdbPointer
!= NULL
) &&
956 (ImageContext
->Machine
!= EFI_IMAGE_MACHINE_EBC
)) {
957 Status
= mPeCoffLoaderWinNtLoadAsDll
->Entry (
958 ImageContext
->PdbPointer
,
963 if (!EFI_ERROR (Status
) && DllEntryPoint
!= NULL
) {
964 ImageContext
->EntryPoint
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) DllEntryPoint
;
965 ImageContext
->ModHandle
= ModHandle
;
975 PeCoffLoaderLoadImage (
976 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*This
,
977 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
983 Loads a PE/COFF image into memory
987 This - Calling context
989 ImageContext - Contains information on image to load into memory
993 EFI_SUCCESS if the PE/COFF image was loaded
994 EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer
995 EFI_LOAD_ERROR if the image is a runtime driver with no relocations
996 EFI_INVALID_PARAMETER if the image address is invalid
1001 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
1002 EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT CheckContext
;
1003 EFI_IMAGE_SECTION_HEADER
*FirstSection
;
1004 EFI_IMAGE_SECTION_HEADER
*Section
;
1005 UINTN NumberOfSections
;
1010 EFI_IMAGE_DATA_DIRECTORY
*DirectoryEntry
;
1011 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*DebugEntry
;
1013 UINT32 TempDebugEntryRva
;
1014 UINT32 NumberOfRvaAndSizes
;
1017 if (NULL
== ImageContext
) {
1018 return EFI_INVALID_PARAMETER
;
1024 ImageContext
->ImageError
= EFI_IMAGE_ERROR_SUCCESS
;
1027 // Copy the provided context info into our local version, get what we
1028 // can from the original image, and then use that to make sure everything
1031 CopyMem (&CheckContext
, ImageContext
, sizeof (EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
));
1033 Status
= PeCoffLoaderGetImageInfo (This
, &CheckContext
);
1034 if (EFI_ERROR (Status
)) {
1039 // Make sure there is enough allocated space for the image being loaded
1041 if (ImageContext
->ImageSize
< CheckContext
.ImageSize
) {
1042 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_IMAGE_SIZE
;
1043 return EFI_BUFFER_TOO_SMALL
;
1045 if (ImageContext
->ImageAddress
== 0) {
1047 // Image cannot be loaded into 0 address.
1049 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS
;
1050 return EFI_INVALID_PARAMETER
;
1053 // If there's no relocations, then make sure it's not a runtime driver,
1054 // and that it's being loaded at the linked address.
1056 if (CheckContext
.RelocationsStripped
) {
1058 // If the image does not contain relocations and it is a runtime driver
1059 // then return an error.
1061 if (CheckContext
.ImageType
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
) {
1062 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_SUBSYSTEM
;
1063 return EFI_LOAD_ERROR
;
1066 // If the image does not contain relocations, and the requested load address
1067 // is not the linked address, then return an error.
1069 if (CheckContext
.ImageAddress
!= ImageContext
->ImageAddress
) {
1070 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS
;
1071 return EFI_INVALID_PARAMETER
;
1075 // Make sure the allocated space has the proper section alignment
1077 if (!(ImageContext
->IsTeImage
)) {
1078 if ((ImageContext
->ImageAddress
& (CheckContext
.SectionAlignment
- 1)) != 0) {
1079 ImageContext
->ImageError
= EFI_IMAGE_ERROR_INVALID_SECTION_ALIGNMENT
;
1080 return EFI_INVALID_PARAMETER
;
1084 // Read the entire PE/COFF or TE header into memory
1086 if (!(ImageContext
->IsTeImage
)) {
1087 Status
= ImageContext
->ImageRead (
1088 ImageContext
->Handle
,
1090 &ImageContext
->SizeOfHeaders
,
1091 (VOID
*) (UINTN
) ImageContext
->ImageAddress
1094 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*)((UINTN
)ImageContext
->ImageAddress
+ ImageContext
->PeCoffHeaderOffset
);
1096 FirstSection
= (EFI_IMAGE_SECTION_HEADER
*) (
1097 (UINTN
)ImageContext
->ImageAddress
+
1098 ImageContext
->PeCoffHeaderOffset
+
1100 sizeof(EFI_IMAGE_FILE_HEADER
) +
1101 Hdr
.Pe32
->FileHeader
.SizeOfOptionalHeader
1103 NumberOfSections
= (UINTN
) (Hdr
.Pe32
->FileHeader
.NumberOfSections
);
1105 Status
= ImageContext
->ImageRead (
1106 ImageContext
->Handle
,
1108 &ImageContext
->SizeOfHeaders
,
1109 (VOID
*)(UINTN
)ImageContext
->ImageAddress
1112 Hdr
.Te
= (EFI_TE_IMAGE_HEADER
*)(UINTN
)(ImageContext
->ImageAddress
);
1114 FirstSection
= (EFI_IMAGE_SECTION_HEADER
*) (
1115 (UINTN
)ImageContext
->ImageAddress
+
1116 sizeof(EFI_TE_IMAGE_HEADER
)
1118 NumberOfSections
= (UINTN
) (Hdr
.Te
->NumberOfSections
);
1122 if (EFI_ERROR (Status
)) {
1123 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
1124 return EFI_LOAD_ERROR
;
1128 // Load each section of the image
1130 Section
= FirstSection
;
1131 for (Index
= 0, MaxEnd
= NULL
; Index
< NumberOfSections
; Index
++) {
1134 // Compute sections address
1136 Base
= PeCoffLoaderImageAddress (ImageContext
, Section
->VirtualAddress
);
1137 End
= PeCoffLoaderImageAddress (
1139 Section
->VirtualAddress
+ Section
->Misc
.VirtualSize
- 1
1141 if (ImageContext
->IsTeImage
) {
1142 Base
= (CHAR8
*)((UINTN
) Base
+ sizeof (EFI_TE_IMAGE_HEADER
) - (UINTN
)Hdr
.Te
->StrippedSize
);
1143 End
= (CHAR8
*)((UINTN
) End
+ sizeof (EFI_TE_IMAGE_HEADER
) - (UINTN
)Hdr
.Te
->StrippedSize
);
1150 // If the base start or end address resolved to 0, then fail.
1152 if ((Base
== NULL
) || (End
== NULL
)) {
1153 ImageContext
->ImageError
= EFI_IMAGE_ERROR_SECTION_NOT_LOADED
;
1154 return EFI_LOAD_ERROR
;
1160 Size
= (UINTN
) Section
->Misc
.VirtualSize
;
1161 if ((Size
== 0) || (Size
> Section
->SizeOfRawData
)) {
1162 Size
= (UINTN
) Section
->SizeOfRawData
;
1165 if (Section
->SizeOfRawData
) {
1166 if (!(ImageContext
->IsTeImage
)) {
1167 Status
= ImageContext
->ImageRead (
1168 ImageContext
->Handle
,
1169 Section
->PointerToRawData
,
1174 Status
= ImageContext
->ImageRead (
1175 ImageContext
->Handle
,
1176 Section
->PointerToRawData
+ sizeof (EFI_TE_IMAGE_HEADER
) - (UINTN
)Hdr
.Te
->StrippedSize
,
1182 if (EFI_ERROR (Status
)) {
1183 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
1189 // If raw size is less then virt size, zero fill the remaining
1192 if (Size
< Section
->Misc
.VirtualSize
) {
1193 ZeroMem (Base
+ Size
, Section
->Misc
.VirtualSize
- Size
);
1202 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
1205 // Get image's entry point
1207 if (!(ImageContext
->IsTeImage
)) {
1210 // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
1211 // It is for backward-compatibility consideration, because
1212 // some system will generate PE32+ image with PE32 Magic.
1214 if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA32
) {
1215 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
;
1216 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_IA64
) {
1217 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
1218 } else if (Hdr
.Pe32
->FileHeader
.Machine
== EFI_IMAGE_MACHINE_X64
) {
1219 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
1221 Magic
= Hdr
.Pe32
->OptionalHeader
.Magic
;
1225 // Sizes of AddressOfEntryPoint are different so we need to do this safely
1227 ImageContext
->EntryPoint
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PeCoffLoaderImageAddress (
1229 (UINTN
)Hdr
.Pe32
->OptionalHeader
.AddressOfEntryPoint
1233 ImageContext
->EntryPoint
= (EFI_PHYSICAL_ADDRESS
) (
1234 (UINTN
)ImageContext
->ImageAddress
+
1235 (UINTN
)Hdr
.Te
->AddressOfEntryPoint
+
1236 (UINTN
)sizeof(EFI_TE_IMAGE_HEADER
) -
1237 (UINTN
)Hdr
.Te
->StrippedSize
1242 // Determine the size of the fixup data
1244 // Per the PE/COFF spec, you can't assume that a given data directory
1245 // is present in the image. You have to check the NumberOfRvaAndSizes in
1246 // the optional header to verify a desired directory entry is there.
1248 if (!(ImageContext
->IsTeImage
)) {
1249 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1253 NumberOfRvaAndSizes
= Hdr
.Pe32
->OptionalHeader
.NumberOfRvaAndSizes
;
1254 DirectoryEntry
= (EFI_IMAGE_DATA_DIRECTORY
*)&Hdr
.Pe32
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC
];
1259 NumberOfRvaAndSizes
= Hdr
.Pe32Plus
->OptionalHeader
.NumberOfRvaAndSizes
;
1260 DirectoryEntry
= (EFI_IMAGE_DATA_DIRECTORY
*)&Hdr
.Pe32Plus
->OptionalHeader
.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC
];
1263 if (NumberOfRvaAndSizes
> EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC
) {
1264 ImageContext
->FixupDataSize
= DirectoryEntry
->Size
/ sizeof (UINT16
) * sizeof (UINTN
);
1266 ImageContext
->FixupDataSize
= 0;
1269 DirectoryEntry
= &Hdr
.Te
->DataDirectory
[0];
1270 ImageContext
->FixupDataSize
= DirectoryEntry
->Size
/ sizeof (UINT16
) * sizeof (UINTN
);
1273 // Consumer must allocate a buffer for the relocation fixup log.
1274 // Only used for runtime drivers.
1276 ImageContext
->FixupData
= NULL
;
1279 // Load the Codeview info if present
1281 if (ImageContext
->DebugDirectoryEntryRva
!= 0) {
1282 if (!(ImageContext
->IsTeImage
)) {
1283 DebugEntry
= PeCoffLoaderImageAddress (
1285 ImageContext
->DebugDirectoryEntryRva
1288 DebugEntry
= (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*)(UINTN
)(
1289 ImageContext
->ImageAddress
+
1290 ImageContext
->DebugDirectoryEntryRva
+
1291 sizeof(EFI_TE_IMAGE_HEADER
) -
1292 Hdr
.Te
->StrippedSize
1296 if (DebugEntry
!= NULL
) {
1297 TempDebugEntryRva
= DebugEntry
->RVA
;
1298 if (DebugEntry
->RVA
== 0 && DebugEntry
->FileOffset
!= 0) {
1300 if ((UINTN
)Section
->SizeOfRawData
< Section
->Misc
.VirtualSize
) {
1301 TempDebugEntryRva
= Section
->VirtualAddress
+ Section
->Misc
.VirtualSize
;
1303 TempDebugEntryRva
= Section
->VirtualAddress
+ Section
->SizeOfRawData
;
1307 if (TempDebugEntryRva
!= 0) {
1308 if (!(ImageContext
->IsTeImage
)) {
1309 ImageContext
->CodeView
= PeCoffLoaderImageAddress (ImageContext
, TempDebugEntryRva
);
1311 ImageContext
->CodeView
= (VOID
*)(
1312 (UINTN
)ImageContext
->ImageAddress
+
1313 (UINTN
)TempDebugEntryRva
+
1314 (UINTN
)sizeof (EFI_TE_IMAGE_HEADER
) -
1315 (UINTN
) Hdr
.Te
->StrippedSize
1319 if (ImageContext
->CodeView
== NULL
) {
1320 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
1321 return EFI_LOAD_ERROR
;
1324 if (DebugEntry
->RVA
== 0) {
1325 Size
= DebugEntry
->SizeOfData
;
1326 if (!(ImageContext
->IsTeImage
)) {
1327 Status
= ImageContext
->ImageRead (
1328 ImageContext
->Handle
,
1329 DebugEntry
->FileOffset
,
1331 ImageContext
->CodeView
1334 Status
= ImageContext
->ImageRead (
1335 ImageContext
->Handle
,
1336 DebugEntry
->FileOffset
+ sizeof (EFI_TE_IMAGE_HEADER
) - Hdr
.Te
->StrippedSize
,
1338 ImageContext
->CodeView
1341 // Should we apply fix up to this field according to the size difference between PE and TE?
1342 // Because now we maintain TE header fields unfixed, this field will also remain as they are
1343 // in original PE image.
1347 if (EFI_ERROR (Status
)) {
1348 ImageContext
->ImageError
= EFI_IMAGE_ERROR_IMAGE_READ
;
1349 return EFI_LOAD_ERROR
;
1352 DebugEntry
->RVA
= TempDebugEntryRva
;
1355 switch (*(UINT32
*) ImageContext
->CodeView
) {
1356 case CODEVIEW_SIGNATURE_NB10
:
1357 ImageContext
->PdbPointer
= (CHAR8
*)ImageContext
->CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
);
1360 case CODEVIEW_SIGNATURE_RSDS
:
1361 ImageContext
->PdbPointer
= (CHAR8
*)ImageContext
->CodeView
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY
);
1371 #if defined (EFI_DEBUG_ITP_BREAK) && !defined (_CONSOLE)
1372 AsmEfiSetBreakSupport ((UINTN
)(ImageContext
->ImageAddress
));
1380 PeCoffLoaderUnloadImage (
1381 IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
1385 Routine Description:
1387 Unload a PE/COFF image from memory
1391 ImageContext - Contains information on image to load into memory
1399 #ifdef EFI_NT_EMULATOR
1401 // Calling Win32 API free library
1403 mPeCoffLoaderWinNtLoadAsDll
->FreeLibrary (ImageContext
->ModHandle
);