TianoCore EDK2 master
Loading...
Searching...
No Matches
CompatImageLoaderDxe.c
Go to the documentation of this file.
1
11#include <PiDxe.h>
12
14#include <Library/DebugLib.h>
15#include <Library/PeCoffLib.h>
17
19
20#pragma pack (1)
21typedef struct {
22 UINT8 Type;
23 UINT8 Size;
24 UINT16 MachineType;
25 UINT32 EntryPoint;
27#pragma pack ()
28
30BOOLEAN
31EFIAPI
32IsImageSupported (
34 IN UINT16 ImageType,
35 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL
36 )
37{
38 return ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
39}
40
43EFIAPI
44GetCompatEntryPoint (
45 IN EFI_PHYSICAL_ADDRESS ImageBase
46 )
47{
49 UINTN PeCoffHeaderOffset;
52 UINTN NumberOfSections;
53 PE_COMPAT_TYPE1 *PeCompat;
54 UINTN PeCompatEnd;
55
56 DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageBase;
57 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
58 return NULL;
59 }
60
61 PeCoffHeaderOffset = DosHdr->e_lfanew;
62 Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageBase + PeCoffHeaderOffset);
63
64 Section = (EFI_IMAGE_SECTION_HEADER *)((UINTN)&Pe32->OptionalHeader +
65 Pe32->FileHeader.SizeOfOptionalHeader);
66 NumberOfSections = (UINTN)Pe32->FileHeader.NumberOfSections;
67
68 while (NumberOfSections--) {
69 if (!CompareMem (Section->Name, ".compat", sizeof (Section->Name))) {
70 //
71 // Dereference the section contents to find the mixed mode entry point
72 //
73 PeCompat = (PE_COMPAT_TYPE1 *)((UINTN)ImageBase + Section->VirtualAddress);
74 PeCompatEnd = (UINTN)(VOID *)PeCompat + Section->Misc.VirtualSize;
75
76 while (PeCompat->Type != 0 && (UINTN)(VOID *)PeCompat < PeCompatEnd) {
77 if ((PeCompat->Type == 1) &&
78 (PeCompat->Size >= sizeof (PE_COMPAT_TYPE1)) &&
79 EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCompat->MachineType))
80 {
81 return (EFI_IMAGE_ENTRY_POINT)((UINTN)ImageBase + PeCompat->EntryPoint);
82 }
83
84 PeCompat = (PE_COMPAT_TYPE1 *)((UINTN)PeCompat + PeCompat->Size);
85 ASSERT ((UINTN)(VOID *)PeCompat < PeCompatEnd);
86 }
87 }
88
89 Section++;
90 }
91
92 return NULL;
93}
94
97EFIAPI
98RegisterImage (
100 IN EFI_PHYSICAL_ADDRESS ImageBase,
101 IN UINT64 ImageSize,
102 IN OUT EFI_IMAGE_ENTRY_POINT *EntryPoint
103 )
104{
105 EFI_IMAGE_ENTRY_POINT CompatEntryPoint;
106
107 CompatEntryPoint = GetCompatEntryPoint (ImageBase);
108 if (CompatEntryPoint == NULL) {
109 return EFI_UNSUPPORTED;
110 }
111
112 *EntryPoint = CompatEntryPoint;
113 return EFI_SUCCESS;
114}
115
116STATIC
118EFIAPI
119UnregisterImage (
121 IN EFI_PHYSICAL_ADDRESS ImageBase
122 )
123{
124 return EFI_SUCCESS;
125}
126
127STATIC EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL mCompatLoaderPeCoffEmuProtocol = {
128 IsImageSupported,
129 RegisterImage,
130 UnregisterImage,
131 EDKII_PECOFF_IMAGE_EMULATOR_VERSION,
133};
134
136EFIAPI
137CompatImageLoaderDxeEntryPoint (
138 IN EFI_HANDLE ImageHandle,
139 IN EFI_SYSTEM_TABLE *SystemTable
140 )
141{
142 return gBS->InstallProtocolInterface (
143 &ImageHandle,
144 &gEdkiiPeCoffImageEmulatorProtocolGuid,
146 &mCompatLoaderPeCoffEmuProtocol
147 );
148}
UINT64 UINTN
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_IMAGE_MACHINE_X64
Definition: UefiBaseType.h:233
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_STATUS(EFIAPI * EFI_IMAGE_ENTRY_POINT)(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: UefiSpec.h:2108
UINT32 e_lfanew
File address of new exe header.
Definition: PeImage.h:76
UINT16 e_magic
Magic number.
Definition: PeImage.h:58