1 | /** @file
|
---|
2 |
|
---|
3 | This file contains implementation for additional PE/COFF functionality needed to use
|
---|
4 | Platform Runtime Mechanism (PRM) modules.
|
---|
5 |
|
---|
6 | Copyright (c) Microsoft Corporation
|
---|
7 | Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
---|
8 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
9 |
|
---|
10 | **/
|
---|
11 |
|
---|
12 | #include <IndustryStandard/PeImage.h>
|
---|
13 | #include <Library/BaseLib.h>
|
---|
14 | #include <Library/DebugLib.h>
|
---|
15 | #include <Library/PeCoffLib.h>
|
---|
16 |
|
---|
17 | #include <PrmExportDescriptor.h>
|
---|
18 | #include <PrmModuleImageContext.h>
|
---|
19 |
|
---|
20 | #define _DBGMSGID_ "[PRMPECOFFLIB]"
|
---|
21 |
|
---|
22 | /**
|
---|
23 | Gets a pointer to the export directory in a given PE/COFF image.
|
---|
24 |
|
---|
25 | @param[in] ImageExportDirectory A pointer to an export directory table in a PE/COFF image.
|
---|
26 | @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
|
---|
27 | PE/COFF image context for the Image containing the PRM Module Export
|
---|
28 | Descriptor table.
|
---|
29 | @param[out] ExportDescriptor A pointer to a pointer to the PRM Module Export Descriptor table found
|
---|
30 | in the ImageExportDirectory given.
|
---|
31 |
|
---|
32 | @retval EFI_SUCCESS The PRM Module Export Descriptor table was found successfully.
|
---|
33 | @retval EFI_INVALID_PARAMETER A required parameter is NULL.
|
---|
34 | @retval EFI_NOT_FOUND The PRM Module Export Descriptor table was not found in the given
|
---|
35 | ImageExportDirectory.
|
---|
36 |
|
---|
37 | **/
|
---|
38 | EFI_STATUS
|
---|
39 | GetPrmModuleExportDescriptorTable (
|
---|
40 | IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
|
---|
41 | IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
|
---|
42 | OUT PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT **ExportDescriptor
|
---|
43 | )
|
---|
44 | {
|
---|
45 | UINTN Index;
|
---|
46 | EFI_PHYSICAL_ADDRESS CurrentImageAddress;
|
---|
47 | UINT16 PrmModuleExportDescriptorOrdinal;
|
---|
48 | CONST CHAR8 *CurrentExportName;
|
---|
49 | UINT16 *OrdinalTable;
|
---|
50 | UINT32 *ExportNamePointerTable;
|
---|
51 | UINT32 *ExportAddressTable;
|
---|
52 | PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *TempExportDescriptor;
|
---|
53 |
|
---|
54 | DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __func__));
|
---|
55 |
|
---|
56 | if ((ImageExportDirectory == NULL) ||
|
---|
57 | (PeCoffLoaderImageContext == NULL) ||
|
---|
58 | (PeCoffLoaderImageContext->ImageAddress == 0) ||
|
---|
59 | (ExportDescriptor == NULL))
|
---|
60 | {
|
---|
61 | return EFI_INVALID_PARAMETER;
|
---|
62 | }
|
---|
63 |
|
---|
64 | *ExportDescriptor = NULL;
|
---|
65 |
|
---|
66 | DEBUG ((
|
---|
67 | DEBUG_INFO,
|
---|
68 | " %a %a: %d exported names found in this image.\n",
|
---|
69 | _DBGMSGID_,
|
---|
70 | __func__,
|
---|
71 | ImageExportDirectory->NumberOfNames
|
---|
72 | ));
|
---|
73 |
|
---|
74 | //
|
---|
75 | // The export name pointer table and export ordinal table form two parallel arrays associated by index.
|
---|
76 | //
|
---|
77 | CurrentImageAddress = PeCoffLoaderImageContext->ImageAddress;
|
---|
78 | ExportAddressTable = (UINT32 *)((UINTN)CurrentImageAddress + ImageExportDirectory->AddressOfFunctions);
|
---|
79 | ExportNamePointerTable = (UINT32 *)((UINTN)CurrentImageAddress + ImageExportDirectory->AddressOfNames);
|
---|
80 | OrdinalTable = (UINT16 *)((UINTN)CurrentImageAddress + ImageExportDirectory->AddressOfNameOrdinals);
|
---|
81 |
|
---|
82 | for (Index = 0; Index < ImageExportDirectory->NumberOfNames; Index++) {
|
---|
83 | CurrentExportName = (CONST CHAR8 *)((UINTN)CurrentImageAddress + ExportNamePointerTable[Index]);
|
---|
84 | DEBUG ((
|
---|
85 | DEBUG_INFO,
|
---|
86 | " %a %a: Export Name[0x%x] - %a.\n",
|
---|
87 | _DBGMSGID_,
|
---|
88 | __func__,
|
---|
89 | Index,
|
---|
90 | CurrentExportName
|
---|
91 | ));
|
---|
92 | if (
|
---|
93 | AsciiStrnCmp (
|
---|
94 | PRM_STRING (PRM_MODULE_EXPORT_DESCRIPTOR_NAME),
|
---|
95 | CurrentExportName,
|
---|
96 | AsciiStrLen (PRM_STRING (PRM_MODULE_EXPORT_DESCRIPTOR_NAME))
|
---|
97 | ) == 0)
|
---|
98 | {
|
---|
99 | PrmModuleExportDescriptorOrdinal = OrdinalTable[Index];
|
---|
100 | DEBUG ((
|
---|
101 | DEBUG_INFO,
|
---|
102 | " %a %a: PRM Module Export Descriptor found. Ordinal = %d.\n",
|
---|
103 | _DBGMSGID_,
|
---|
104 | __func__,
|
---|
105 | PrmModuleExportDescriptorOrdinal
|
---|
106 | ));
|
---|
107 | if (PrmModuleExportDescriptorOrdinal >= ImageExportDirectory->NumberOfFunctions) {
|
---|
108 | DEBUG ((DEBUG_ERROR, "%a %a: The PRM Module Export Descriptor ordinal value is invalid.\n", _DBGMSGID_, __func__));
|
---|
109 | return EFI_NOT_FOUND;
|
---|
110 | }
|
---|
111 |
|
---|
112 | TempExportDescriptor = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *)((UINTN)CurrentImageAddress + ExportAddressTable[PrmModuleExportDescriptorOrdinal]);
|
---|
113 | if (TempExportDescriptor->Header.Signature == PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE) {
|
---|
114 | *ExportDescriptor = TempExportDescriptor;
|
---|
115 | DEBUG ((DEBUG_INFO, " %a %a: PRM Module Export Descriptor found at 0x%x.\n", _DBGMSGID_, __func__, (UINTN)ExportDescriptor));
|
---|
116 | } else {
|
---|
117 | DEBUG ((
|
---|
118 | DEBUG_INFO,
|
---|
119 | " %a %a: PRM Module Export Descriptor found at 0x%x but signature check failed.\n",
|
---|
120 | _DBGMSGID_,
|
---|
121 | __func__,
|
---|
122 | (UINTN)TempExportDescriptor
|
---|
123 | ));
|
---|
124 | }
|
---|
125 |
|
---|
126 | DEBUG ((DEBUG_INFO, " %a %a: Exiting export iteration since export descriptor found.\n", _DBGMSGID_, __func__));
|
---|
127 | return EFI_SUCCESS;
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 | return EFI_NOT_FOUND;
|
---|
132 | }
|
---|
133 |
|
---|
134 | /**
|
---|
135 | Gets a pointer to the export directory in a given PE/COFF image.
|
---|
136 |
|
---|
137 | @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
|
---|
138 | and already relocated to the memory base address. RVAs in the image given
|
---|
139 | should be valid.
|
---|
140 | @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
|
---|
141 | PE/COFF image context for the Image given.
|
---|
142 | @param[out] ImageExportDirectory A pointer to a pointer to the export directory found in the Image given.
|
---|
143 |
|
---|
144 | @retval EFI_SUCCESS The export directory was found successfully.
|
---|
145 | @retval EFI_INVALID_PARAMETER A required parameter is NULL.
|
---|
146 | @retval EFI_UNSUPPORTED The PE/COFF image given is not supported as a PRM Module.
|
---|
147 | @retval EFI_NOT_FOUND The image export directory could not be found for this image.
|
---|
148 |
|
---|
149 | **/
|
---|
150 | EFI_STATUS
|
---|
151 | GetExportDirectoryInPeCoffImage (
|
---|
152 | IN VOID *Image,
|
---|
153 | IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
|
---|
154 | OUT EFI_IMAGE_EXPORT_DIRECTORY **ImageExportDirectory
|
---|
155 | )
|
---|
156 | {
|
---|
157 | UINT16 Magic;
|
---|
158 | UINT32 NumberOfRvaAndSizes;
|
---|
159 | EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
|
---|
160 | EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
|
---|
161 | EFI_IMAGE_EXPORT_DIRECTORY *ExportDirectory;
|
---|
162 |
|
---|
163 | if ((Image == NULL) || (PeCoffLoaderImageContext == NULL) || (ImageExportDirectory == NULL)) {
|
---|
164 | return EFI_INVALID_PARAMETER;
|
---|
165 | }
|
---|
166 |
|
---|
167 | DirectoryEntry = NULL;
|
---|
168 | ExportDirectory = NULL;
|
---|
169 |
|
---|
170 | //
|
---|
171 | // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
|
---|
172 | // image instead of using the Magic field. Some systems might generate a PE32+
|
---|
173 | // image with PE32 magic.
|
---|
174 | //
|
---|
175 | switch (PeCoffLoaderImageContext->Machine) {
|
---|
176 | case EFI_IMAGE_MACHINE_IA32:
|
---|
177 | //
|
---|
178 | // Assume PE32 image with IA32 Machine field.
|
---|
179 | //
|
---|
180 | Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
|
---|
181 | break;
|
---|
182 | case EFI_IMAGE_MACHINE_X64:
|
---|
183 | case EFI_IMAGE_MACHINE_AARCH64:
|
---|
184 | //
|
---|
185 | // Assume PE32+ image with X64 Machine field
|
---|
186 | //
|
---|
187 | Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
---|
188 | break;
|
---|
189 | default:
|
---|
190 | //
|
---|
191 | // For unknown Machine field, use Magic in optional header
|
---|
192 | //
|
---|
193 | DEBUG ((
|
---|
194 | DEBUG_WARN,
|
---|
195 | "%a %a: The machine type for this image is not valid for a PRM module.\n",
|
---|
196 | _DBGMSGID_,
|
---|
197 | __func__
|
---|
198 | ));
|
---|
199 | return EFI_UNSUPPORTED;
|
---|
200 | }
|
---|
201 |
|
---|
202 | OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(
|
---|
203 | (UINTN)Image +
|
---|
204 | PeCoffLoaderImageContext->PeCoffHeaderOffset
|
---|
205 | );
|
---|
206 |
|
---|
207 | //
|
---|
208 | // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
|
---|
209 | //
|
---|
210 | if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
|
---|
211 | DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __func__));
|
---|
212 | return EFI_UNSUPPORTED;
|
---|
213 | }
|
---|
214 |
|
---|
215 | if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
---|
216 | //
|
---|
217 | // Use the PE32 offset to get the Export Directory Entry
|
---|
218 | //
|
---|
219 | NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32->OptionalHeader.NumberOfRvaAndSizes;
|
---|
220 | DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHeaderPtrUnion.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
|
---|
221 | } else if (OptionalHeaderPtrUnion.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
---|
222 | //
|
---|
223 | // Use the PE32+ offset get the Export Directory Entry
|
---|
224 | //
|
---|
225 | NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
|
---|
226 | DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
|
---|
227 | } else {
|
---|
228 | return EFI_UNSUPPORTED;
|
---|
229 | }
|
---|
230 |
|
---|
231 | if ((NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_EXPORT) || (DirectoryEntry->VirtualAddress == 0)) {
|
---|
232 | //
|
---|
233 | // The export directory is not present
|
---|
234 | //
|
---|
235 | return EFI_NOT_FOUND;
|
---|
236 | } else if (((UINT32)(~0) - DirectoryEntry->VirtualAddress) < DirectoryEntry->Size) {
|
---|
237 | //
|
---|
238 | // The directory address overflows
|
---|
239 | //
|
---|
240 | DEBUG ((DEBUG_ERROR, "%a %a: The export directory entry in this image results in overflow.\n", _DBGMSGID_, __func__));
|
---|
241 | return EFI_UNSUPPORTED;
|
---|
242 | } else {
|
---|
243 | DEBUG ((DEBUG_INFO, "%a %a: Export Directory Entry found in the image at 0x%x.\n", _DBGMSGID_, __func__, (UINTN)OptionalHeaderPtrUnion.Pe32));
|
---|
244 | DEBUG ((DEBUG_INFO, " %a %a: Directory Entry Virtual Address = 0x%x.\n", _DBGMSGID_, __func__, DirectoryEntry->VirtualAddress));
|
---|
245 |
|
---|
246 | ExportDirectory = (EFI_IMAGE_EXPORT_DIRECTORY *)((UINTN)Image + DirectoryEntry->VirtualAddress);
|
---|
247 | DEBUG ((
|
---|
248 | DEBUG_INFO,
|
---|
249 | " %a %a: Export Directory Table found successfully at 0x%x. Name address = 0x%x. Name = %a.\n",
|
---|
250 | _DBGMSGID_,
|
---|
251 | __func__,
|
---|
252 | (UINTN)ExportDirectory,
|
---|
253 | ((UINTN)Image + ExportDirectory->Name),
|
---|
254 | (CHAR8 *)((UINTN)Image + ExportDirectory->Name)
|
---|
255 | ));
|
---|
256 | }
|
---|
257 |
|
---|
258 | *ImageExportDirectory = ExportDirectory;
|
---|
259 |
|
---|
260 | return EFI_SUCCESS;
|
---|
261 | }
|
---|
262 |
|
---|
263 | /**
|
---|
264 | Returns the image major and image minor version in a given PE/COFF image.
|
---|
265 |
|
---|
266 | @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
|
---|
267 | and already relocated to the memory base address. RVAs in the image given
|
---|
268 | should be valid.
|
---|
269 | @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
|
---|
270 | PE/COFF image context for the Image given.
|
---|
271 | @param[out] ImageMajorVersion A pointer to a UINT16 buffer to hold the image major version.
|
---|
272 | @param[out] ImageMinorVersion A pointer to a UINT16 buffer to hold the image minor version.
|
---|
273 |
|
---|
274 | @retval EFI_SUCCESS The image version was read successfully.
|
---|
275 | @retval EFI_INVALID_PARAMETER A required parameter is NULL.
|
---|
276 | @retval EFI_UNSUPPORTED The PE/COFF image given is not supported.
|
---|
277 |
|
---|
278 | **/
|
---|
279 | EFI_STATUS
|
---|
280 | GetImageVersionInPeCoffImage (
|
---|
281 | IN VOID *Image,
|
---|
282 | IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
|
---|
283 | OUT UINT16 *ImageMajorVersion,
|
---|
284 | OUT UINT16 *ImageMinorVersion
|
---|
285 | )
|
---|
286 | {
|
---|
287 | EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
|
---|
288 | UINT16 Magic;
|
---|
289 |
|
---|
290 | DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __func__));
|
---|
291 |
|
---|
292 | if ((Image == NULL) || (PeCoffLoaderImageContext == NULL) || (ImageMajorVersion == NULL) || (ImageMinorVersion == NULL)) {
|
---|
293 | return EFI_INVALID_PARAMETER;
|
---|
294 | }
|
---|
295 |
|
---|
296 | //
|
---|
297 | // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
|
---|
298 | // image instead of using the Magic field. Some systems might generate a PE32+
|
---|
299 | // image with PE32 magic.
|
---|
300 | //
|
---|
301 | switch (PeCoffLoaderImageContext->Machine) {
|
---|
302 | case EFI_IMAGE_MACHINE_IA32:
|
---|
303 | //
|
---|
304 | // Assume PE32 image
|
---|
305 | //
|
---|
306 | Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
|
---|
307 | break;
|
---|
308 | case EFI_IMAGE_MACHINE_X64:
|
---|
309 | case EFI_IMAGE_MACHINE_AARCH64:
|
---|
310 | //
|
---|
311 | // Assume PE32+ image
|
---|
312 | //
|
---|
313 | Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
---|
314 | break;
|
---|
315 | default:
|
---|
316 | //
|
---|
317 | // For unknown Machine field, use Magic in optional header
|
---|
318 | //
|
---|
319 | DEBUG ((
|
---|
320 | DEBUG_WARN,
|
---|
321 | "%a %a: The machine type for this image is not valid for a PRM module.\n",
|
---|
322 | _DBGMSGID_,
|
---|
323 | __func__
|
---|
324 | ));
|
---|
325 | return EFI_UNSUPPORTED;
|
---|
326 | }
|
---|
327 |
|
---|
328 | OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(
|
---|
329 | (UINTN)Image +
|
---|
330 | PeCoffLoaderImageContext->PeCoffHeaderOffset
|
---|
331 | );
|
---|
332 | //
|
---|
333 | // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
|
---|
334 | //
|
---|
335 | if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
|
---|
336 | DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __func__));
|
---|
337 | return EFI_UNSUPPORTED;
|
---|
338 | }
|
---|
339 |
|
---|
340 | if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
---|
341 | //
|
---|
342 | // Use the PE32 offset to get the Export Directory Entry
|
---|
343 | //
|
---|
344 | *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MajorImageVersion;
|
---|
345 | *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MinorImageVersion;
|
---|
346 | } else {
|
---|
347 | //
|
---|
348 | // Use the PE32+ offset to get the Export Directory Entry
|
---|
349 | //
|
---|
350 | *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MajorImageVersion;
|
---|
351 | *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MinorImageVersion;
|
---|
352 | }
|
---|
353 |
|
---|
354 | DEBUG ((DEBUG_INFO, " %a %a - Image Major Version: 0x%02x.\n", _DBGMSGID_, __func__, *ImageMajorVersion));
|
---|
355 | DEBUG ((DEBUG_INFO, " %a %a - Image Minor Version: 0x%02x.\n", _DBGMSGID_, __func__, *ImageMinorVersion));
|
---|
356 |
|
---|
357 | return EFI_SUCCESS;
|
---|
358 | }
|
---|
359 |
|
---|
360 | /**
|
---|
361 | Gets the address of an entry in an image export table by ASCII name.
|
---|
362 |
|
---|
363 | @param[in] ExportName A pointer to an ASCII name string of the entry name.
|
---|
364 | @param[in] ImageBaseAddress The base address of the PE/COFF image.
|
---|
365 | @param[in] ImageExportDirectory A pointer to the export directory in the image.
|
---|
366 | @param[out] ExportPhysicalAddress A pointer that will be updated with the address of the address of the
|
---|
367 | export entry if found.
|
---|
368 |
|
---|
369 | @retval EFI_SUCCESS The export entry was found successfully.
|
---|
370 | @retval EFI_INVALID_PARAMETER A required pointer argument is NULL.
|
---|
371 | @retval EFI_NOT_FOUND An entry with the given ExportName was not found.
|
---|
372 |
|
---|
373 | **/
|
---|
374 | EFI_STATUS
|
---|
375 | GetExportEntryAddress (
|
---|
376 | IN CONST CHAR8 *ExportName,
|
---|
377 | IN EFI_PHYSICAL_ADDRESS ImageBaseAddress,
|
---|
378 | IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
|
---|
379 | OUT EFI_PHYSICAL_ADDRESS *ExportPhysicalAddress
|
---|
380 | )
|
---|
381 | {
|
---|
382 | UINTN ExportNameIndex;
|
---|
383 | UINT16 CurrentExportOrdinal;
|
---|
384 | UINT32 *ExportAddressTable;
|
---|
385 | UINT32 *ExportNamePointerTable;
|
---|
386 | UINT16 *OrdinalTable;
|
---|
387 | CONST CHAR8 *ExportNameTablePointerName;
|
---|
388 |
|
---|
389 | if ((ExportName == NULL) || (ImageBaseAddress == 0) || (ImageExportDirectory == NULL) || (ExportPhysicalAddress == NULL)) {
|
---|
390 | return EFI_INVALID_PARAMETER;
|
---|
391 | }
|
---|
392 |
|
---|
393 | *ExportPhysicalAddress = 0;
|
---|
394 |
|
---|
395 | ExportAddressTable = (UINT32 *)((UINTN)ImageBaseAddress + ImageExportDirectory->AddressOfFunctions);
|
---|
396 | ExportNamePointerTable = (UINT32 *)((UINTN)ImageBaseAddress + ImageExportDirectory->AddressOfNames);
|
---|
397 | OrdinalTable = (UINT16 *)((UINTN)ImageBaseAddress + ImageExportDirectory->AddressOfNameOrdinals);
|
---|
398 |
|
---|
399 | for (ExportNameIndex = 0; ExportNameIndex < ImageExportDirectory->NumberOfNames; ExportNameIndex++) {
|
---|
400 | ExportNameTablePointerName = (CONST CHAR8 *)((UINTN)ImageBaseAddress + ExportNamePointerTable[ExportNameIndex]);
|
---|
401 |
|
---|
402 | if (AsciiStrnCmp (ExportName, ExportNameTablePointerName, PRM_HANDLER_NAME_MAXIMUM_LENGTH) == 0) {
|
---|
403 | CurrentExportOrdinal = OrdinalTable[ExportNameIndex];
|
---|
404 |
|
---|
405 | ASSERT (CurrentExportOrdinal < ImageExportDirectory->NumberOfFunctions);
|
---|
406 | if (CurrentExportOrdinal >= ImageExportDirectory->NumberOfFunctions) {
|
---|
407 | DEBUG ((DEBUG_ERROR, " %a %a: The export ordinal value is invalid.\n", _DBGMSGID_, __func__));
|
---|
408 | break;
|
---|
409 | }
|
---|
410 |
|
---|
411 | *ExportPhysicalAddress = (EFI_PHYSICAL_ADDRESS)((UINTN)ImageBaseAddress + ExportAddressTable[CurrentExportOrdinal]);
|
---|
412 | return EFI_SUCCESS;
|
---|
413 | }
|
---|
414 | }
|
---|
415 |
|
---|
416 | return EFI_NOT_FOUND;
|
---|
417 | }
|
---|