1 /*++
2
3 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13 PeLoader.c
14
15 Abstract:
16
17 Revision History:
18
19 --*/
20 #include "EfiLdr.h"
21 #include "Debug.h"
22 #include "Support.h"
23
24 EFI_STATUS
25 EfiLdrPeCoffLoadPeRelocate (
26 IN EFILDR_LOADED_IMAGE *Image,
27 IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,
28 IN UINTN Adjust,
29 IN UINTN *NumberOfMemoryMapEntries,
30 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
31 );
32
33 EFI_STATUS
34 EfiLdrPeCoffImageRead (
35 IN VOID *FHand,
36 IN UINTN Offset,
37 IN OUT UINTN ReadSize,
38 OUT VOID *Buffer
39 );
40
41 VOID *
42 EfiLdrPeCoffImageAddress (
43 IN EFILDR_LOADED_IMAGE *Image,
44 IN UINTN Address
45 );
46
47
48 EFI_STATUS
49 EfiLdrPeCoffSetImageType (
50 IN OUT EFILDR_LOADED_IMAGE *Image,
51 IN UINTN ImageType
52 );
53
54 EFI_STATUS
55 EfiLdrPeCoffCheckImageMachineType (
56 IN UINT16 MachineType
57 );
58
59 EFI_STATUS
EfiLdrGetPeImageInfo(IN VOID * FHand,OUT UINT64 * ImageBase,OUT UINT32 * ImageSize)60 EfiLdrGetPeImageInfo (
61 IN VOID *FHand,
62 OUT UINT64 *ImageBase,
63 OUT UINT32 *ImageSize
64 )
65 {
66 EFI_STATUS Status;
67 EFI_IMAGE_DOS_HEADER DosHdr;
68 EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;
69
70 ZeroMem (&DosHdr, sizeof(DosHdr));
71 ZeroMem (&PeHdr, sizeof(PeHdr));
72
73 //
74 // Read image headers
75 //
76
77 EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr);
78 if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
79 return EFI_UNSUPPORTED;
80 }
81
82 EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr);
83
84 if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
85 return EFI_UNSUPPORTED;
86 }
87
88 //
89 // Verify machine type
90 //
91
92 Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine);
93 if (EFI_ERROR(Status)) {
94 return Status;
95 }
96
97 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
98 *ImageBase = (UINT32)PeHdr.Pe32.OptionalHeader.ImageBase;
99 } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
100 *ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;
101 } else {
102 return EFI_UNSUPPORTED;
103 }
104
105 *ImageSize = PeHdr.Pe32.OptionalHeader.SizeOfImage;
106
107 return EFI_SUCCESS;
108 }
109
110 EFI_STATUS
EfiLdrPeCoffLoadPeImage(IN VOID * FHand,IN EFILDR_LOADED_IMAGE * Image,IN UINTN * NumberOfMemoryMapEntries,IN EFI_MEMORY_DESCRIPTOR * EfiMemoryDescriptor)111 EfiLdrPeCoffLoadPeImage (
112 IN VOID *FHand,
113 IN EFILDR_LOADED_IMAGE *Image,
114 IN UINTN *NumberOfMemoryMapEntries,
115 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
116 )
117 {
118 EFI_IMAGE_DOS_HEADER DosHdr;
119 EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;
120 EFI_IMAGE_SECTION_HEADER *FirstSection;
121 EFI_IMAGE_SECTION_HEADER *Section;
122 UINTN Index;
123 EFI_STATUS Status;
124 UINT8 *Base;
125 UINT8 *End;
126 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
127 UINTN DirCount;
128 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY TempDebugEntry;
129 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
130 UINTN CodeViewSize;
131 UINTN CodeViewOffset;
132 UINTN CodeViewFileOffset;
133 UINTN OptionalHeaderSize;
134 UINTN PeHeaderSize;
135 UINT32 NumberOfRvaAndSizes;
136 EFI_IMAGE_DATA_DIRECTORY *DataDirectory;
137 UINT64 ImageBase;
138 CHAR8 PrintBuffer[256];
139
140 ZeroMem (&DosHdr, sizeof(DosHdr));
141 ZeroMem (&PeHdr, sizeof(PeHdr));
142
143 //
144 // Read image headers
145 //
146
147 EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr);
148 if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
149 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Dos header signature not found\n");
150 PrintString (PrintBuffer);
151 PrintHeader ('F');
152 return EFI_UNSUPPORTED;
153 }
154
155 EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr);
156
157 if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
158 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: PE image header signature not found\n");
159 PrintString (PrintBuffer);
160 PrintHeader ('G');
161 return EFI_UNSUPPORTED;
162 }
163
164 //
165 // Set the image subsystem type
166 //
167
168 Status = EfiLdrPeCoffSetImageType (Image, PeHdr.Pe32.OptionalHeader.Subsystem);
169 if (EFI_ERROR(Status)) {
170 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Subsystem type not known\n");
171 PrintString (PrintBuffer);
172 PrintHeader ('H');
173 return Status;
174 }
175
176 //
177 // Verify machine type
178 //
179
180 Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine);
181 if (EFI_ERROR(Status)) {
182 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Incorrect machine type\n");
183 PrintString (PrintBuffer);
184 PrintHeader ('I');
185 return Status;
186 }
187
188 //
189 // Compute the amount of memory needed to load the image and
190 // allocate it. This will include all sections plus the codeview debug info.
191 // Since the codeview info is actually outside of the image, we calculate
192 // its size seperately and add it to the total.
193 //
194 // Memory starts off as data
195 //
196
197 CodeViewSize = 0;
198 CodeViewFileOffset = 0;
199 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
200 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
201 } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
202 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
203 } else {
204 return EFI_UNSUPPORTED;
205 }
206 for (DirCount = 0;
207 (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && (CodeViewSize == 0);
208 DirCount++) {
209 Status = EfiLdrPeCoffImageRead (
210 FHand,
211 DirectoryEntry->VirtualAddress + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),
212 sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),
213 &TempDebugEntry
214 );
215 if (!EFI_ERROR (Status)) {
216 if (TempDebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
217 CodeViewSize = TempDebugEntry.SizeOfData;
218 CodeViewFileOffset = TempDebugEntry.FileOffset;
219 }
220 }
221 }
222
223 CodeViewOffset = PeHdr.Pe32.OptionalHeader.SizeOfImage + PeHdr.Pe32.OptionalHeader.SectionAlignment;
224 Image->NoPages = EFI_SIZE_TO_PAGES (CodeViewOffset + CodeViewSize);
225
226 //
227 // Compute the amount of memory needed to load the image and
228 // allocate it. Memory starts off as data
229 //
230
231 Image->ImageBasePage = (EFI_PHYSICAL_ADDRESS)FindSpace (Image->NoPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesCode, EFI_MEMORY_WB);
232 if (Image->ImageBasePage == 0) {
233 return EFI_OUT_OF_RESOURCES;
234 }
235
236 if (EFI_ERROR(Status)) {
237 PrintHeader ('J');
238 return Status;
239 }
240
241 AsciiSPrint (PrintBuffer, 256, "LoadPe: new image base %lx\n", Image->ImageBasePage);
242 PrintString (PrintBuffer);
243 Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageBasePage;
244 Image->Info.ImageSize = (Image->NoPages << EFI_PAGE_SHIFT) - 1;
245 Image->ImageBase = (UINT8 *)(UINTN)Image->ImageBasePage;
246 Image->ImageEof = Image->ImageBase + Image->Info.ImageSize;
247 Image->ImageAdjust = Image->ImageBase;
248
249 //
250 // Copy the Image header to the base location
251 //
252 Status = EfiLdrPeCoffImageRead (
253 FHand,
254 0,
255 PeHdr.Pe32.OptionalHeader.SizeOfHeaders,
256 Image->ImageBase
257 );
258
259 if (EFI_ERROR(Status)) {
260 PrintHeader ('K');
261 return Status;
262 }
263
264 //
265 // Load each directory of the image into memory...
266 // Save the address of the Debug directory for later
267 //
268 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
269 NumberOfRvaAndSizes = PeHdr.Pe32.OptionalHeader.NumberOfRvaAndSizes;
270 DataDirectory = PeHdr.Pe32.OptionalHeader.DataDirectory;
271 } else {
272 NumberOfRvaAndSizes = PeHdr.Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;
273 DataDirectory = PeHdr.Pe32Plus.OptionalHeader.DataDirectory;
274 }
275 DebugEntry = NULL;
276 for (Index = 0; Index < NumberOfRvaAndSizes; Index++) {
277 if ((DataDirectory[Index].VirtualAddress != 0) && (DataDirectory[Index].Size != 0)) {
278 Status = EfiLdrPeCoffImageRead (
279 FHand,
280 DataDirectory[Index].VirtualAddress,
281 DataDirectory[Index].Size,
282 Image->ImageBase + DataDirectory[Index].VirtualAddress
283 );
284 if (EFI_ERROR(Status)) {
285 return Status;
286 }
287 if (Index == EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
288 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (Image->ImageBase + DataDirectory[Index].VirtualAddress);
289 }
290 }
291 }
292
293 //
294 // Load each section of the image
295 //
296
297 // BUGBUG: change this to use the in memory copy
298 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
299 OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32);
300 PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS32);
301 } else {
302 OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64);
303 PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS64);
304 }
305 FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
306 Image->ImageBase +
307 DosHdr.e_lfanew +
308 PeHeaderSize +
309 PeHdr.Pe32.FileHeader.SizeOfOptionalHeader -
310 OptionalHeaderSize
311 );
312
313 Section = FirstSection;
314 for (Index=0; Index < PeHdr.Pe32.FileHeader.NumberOfSections; Index += 1) {
315
316 //
317 // Compute sections address
318 //
319
320 Base = EfiLdrPeCoffImageAddress (Image, (UINTN)Section->VirtualAddress);
321 End = EfiLdrPeCoffImageAddress (Image, (UINTN)(Section->VirtualAddress + Section->Misc.VirtualSize));
322
323 if (EFI_ERROR(Status) || !Base || !End) {
324 // DEBUG((D_LOAD|D_ERROR, "LoadPe: Section %d was not loaded\n", Index));
325 PrintHeader ('L');
326 return EFI_LOAD_ERROR;
327 }
328
329 // DEBUG((D_LOAD, "LoadPe: Section %d, loaded at %x\n", Index, Base));
330
331 //
332 // Read the section
333 //
334
335 if (Section->SizeOfRawData) {
336 Status = EfiLdrPeCoffImageRead (FHand, Section->PointerToRawData, Section->SizeOfRawData, Base);
337 if (EFI_ERROR(Status)) {
338 PrintHeader ('M');
339 return Status;
340 }
341 }
342
343 //
344 // If raw size is less then virt size, zero fill the remaining
345 //
346
347 if (Section->SizeOfRawData < Section->Misc.VirtualSize) {
348 ZeroMem (
349 Base + Section->SizeOfRawData,
350 Section->Misc.VirtualSize - Section->SizeOfRawData
351 );
352 }
353
354 //
355 // Next Section
356 //
357
358 Section += 1;
359 }
360
361 //
362 // Copy in CodeView information if it exists
363 //
364 if (CodeViewSize != 0) {
365 Status = EfiLdrPeCoffImageRead (FHand, CodeViewFileOffset, CodeViewSize, Image->ImageBase + CodeViewOffset);
366 DebugEntry->RVA = (UINT32) (CodeViewOffset);
367 }
368
369 //
370 // Apply relocations only if needed
371 //
372 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
373 ImageBase = (UINT64)PeHdr.Pe32.OptionalHeader.ImageBase;
374 } else {
375 ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;
376 }
377 if ((UINTN)(Image->ImageBase) != (UINTN) (ImageBase)) {
378 Status = EfiLdrPeCoffLoadPeRelocate (
379 Image,
380 &DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC],
381 (UINTN) Image->ImageBase - (UINTN)ImageBase,
382 NumberOfMemoryMapEntries,
383 EfiMemoryDescriptor
384 );
385
386 if (EFI_ERROR(Status)) {
387 PrintHeader ('N');
388 return Status;
389 }
390 }
391
392 //
393 // Use exported EFI specific interface if present, else use the image's entry point
394 //
395 Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)
396 (EfiLdrPeCoffImageAddress(
397 Image,
398 PeHdr.Pe32.OptionalHeader.AddressOfEntryPoint
399 ));
400
401 return Status;
402 }
403
404 EFI_STATUS
EfiLdrPeCoffLoadPeRelocate(IN EFILDR_LOADED_IMAGE * Image,IN EFI_IMAGE_DATA_DIRECTORY * RelocDir,IN UINTN Adjust,IN UINTN * NumberOfMemoryMapEntries,IN EFI_MEMORY_DESCRIPTOR * EfiMemoryDescriptor)405 EfiLdrPeCoffLoadPeRelocate (
406 IN EFILDR_LOADED_IMAGE *Image,
407 IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,
408 IN UINTN Adjust,
409 IN UINTN *NumberOfMemoryMapEntries,
410 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
411 )
412 {
413 EFI_IMAGE_BASE_RELOCATION *RelocBase;
414 EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
415 UINT16 *Reloc;
416 UINT16 *RelocEnd;
417 UINT8 *Fixup;
418 UINT8 *FixupBase;
419 UINT16 *F16;
420 UINT32 *F32;
421 UINT64 *F64;
422 UINT8 *FixupData;
423 UINTN NoFixupPages;
424
425 //
426 // Find the relocation block
427 //
428
429 RelocBase = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress);
430 RelocBaseEnd = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);
431 if (!RelocBase || !RelocBaseEnd) {
432 PrintHeader ('O');
433 return EFI_LOAD_ERROR;
434 }
435
436 NoFixupPages = EFI_SIZE_TO_PAGES(RelocDir->Size / sizeof(UINT16) * sizeof(UINTN));
437 Image->FixupData = (UINT8*) FindSpace (NoFixupPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
438 if (Image->FixupData == 0) {
439 return EFI_OUT_OF_RESOURCES;
440 }
441
442 //
443 // Run the whole relocation block
444 //
445
446 FixupData = Image->FixupData;
447 while (RelocBase < RelocBaseEnd) {
448
449 Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));
450 RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);
451 FixupBase = EfiLdrPeCoffImageAddress (Image, RelocBase->VirtualAddress);
452 if ((UINT8 *) RelocEnd < Image->ImageBase || (UINT8 *) RelocEnd > Image->ImageEof) {
453 PrintHeader ('P');
454 return EFI_LOAD_ERROR;
455 }
456
457 //
458 // Run this relocation record
459 //
460
461 while (Reloc < RelocEnd) {
462
463 Fixup = FixupBase + (*Reloc & 0xFFF);
464 switch ((*Reloc) >> 12) {
465
466 case EFI_IMAGE_REL_BASED_ABSOLUTE:
467 break;
468
469 case EFI_IMAGE_REL_BASED_HIGH:
470 F16 = (UINT16 *) Fixup;
471 *F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16));
472 if (FixupData != NULL) {
473 *(UINT16 *) FixupData = *F16;
474 FixupData = FixupData + sizeof(UINT16);
475 }
476 break;
477
478 case EFI_IMAGE_REL_BASED_LOW:
479 F16 = (UINT16 *) Fixup;
480 *F16 = (UINT16) (*F16 + (UINT16) Adjust);
481 if (FixupData != NULL) {
482 *(UINT16 *) FixupData = *F16;
483 FixupData = FixupData + sizeof(UINT16);
484 }
485 break;
486
487 case EFI_IMAGE_REL_BASED_HIGHLOW:
488 F32 = (UINT32 *) Fixup;
489 *F32 = *F32 + (UINT32) Adjust;
490 if (FixupData != NULL) {
491 FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));
492 *(UINT32 *) FixupData = *F32;
493 FixupData = FixupData + sizeof(UINT32);
494 }
495 break;
496
497 case EFI_IMAGE_REL_BASED_DIR64:
498 F64 = (UINT64 *) Fixup;
499 *F64 = *F64 + (UINT64) Adjust;
500 if (FixupData != NULL) {
501 FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64));
502 *(UINT64 *) FixupData = *F64;
503 FixupData = FixupData + sizeof(UINT64);
504 }
505 break;
506
507 case EFI_IMAGE_REL_BASED_HIGHADJ:
508 CpuDeadLoop(); // BUGBUG: not done
509 break;
510
511 default:
512 // DEBUG((D_LOAD|D_ERROR, "PeRelocate: unknown fixed type\n"));
513 PrintHeader ('Q');
514 CpuDeadLoop();
515 return EFI_LOAD_ERROR;
516 }
517
518 // Next reloc record
519 Reloc += 1;
520 }
521
522 // next reloc block
523 RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
524 }
525
526 //
527 // Add Fixup data to whole Image (assume Fixup data just below the image), so that there is no hole in the descriptor.
528 // Because only NoPages or ImageBasePage will be used in EfiLoader(), we update these 2 fields.
529 //
530 Image->NoPages += NoFixupPages;
531 Image->ImageBasePage -= (NoFixupPages << EFI_PAGE_SHIFT);
532
533 return EFI_SUCCESS;
534 }
535
536 EFI_STATUS
EfiLdrPeCoffImageRead(IN VOID * FHand,IN UINTN Offset,IN OUT UINTN ReadSize,OUT VOID * Buffer)537 EfiLdrPeCoffImageRead (
538 IN VOID *FHand,
539 IN UINTN Offset,
540 IN OUT UINTN ReadSize,
541 OUT VOID *Buffer
542 )
543 {
544 CopyMem (Buffer, (VOID *)((UINTN)FHand + Offset), ReadSize);
545
546 return EFI_SUCCESS;
547 }
548
549 VOID *
EfiLdrPeCoffImageAddress(IN EFILDR_LOADED_IMAGE * Image,IN UINTN Address)550 EfiLdrPeCoffImageAddress (
551 IN EFILDR_LOADED_IMAGE *Image,
552 IN UINTN Address
553 )
554 {
555 UINT8 *FixedAddress;
556
557 FixedAddress = Image->ImageAdjust + Address;
558
559 if ((FixedAddress < Image->ImageBase) || (FixedAddress > Image->ImageEof)) {
560 // DEBUG((D_LOAD|D_ERROR, "PeCoffImageAddress: pointer is outside of image\n"));
561 FixedAddress = NULL;
562 }
563
564 // DEBUG((
565 // D_LOAD,
566 // "PeCoffImageAddress: ImageBase %x, ImageEof %x, Address %x, FixedAddress %x\n",
567 // Image->ImageBase,
568 // Image->ImageEof,
569 // Address,
570 // FixedAddress
571 // ));
572 return FixedAddress;
573 }
574
575
576 EFI_STATUS
EfiLdrPeCoffSetImageType(IN OUT EFILDR_LOADED_IMAGE * Image,IN UINTN ImageType)577 EfiLdrPeCoffSetImageType (
578 IN OUT EFILDR_LOADED_IMAGE *Image,
579 IN UINTN ImageType
580 )
581 {
582 EFI_MEMORY_TYPE CodeType;
583 EFI_MEMORY_TYPE DataType;
584
585 switch (ImageType) {
586 case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
587 CodeType = EfiLoaderCode;
588 DataType = EfiLoaderData;
589 break;
590
591 case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
592 CodeType = EfiBootServicesCode;
593 DataType = EfiBootServicesData;
594 break;
595
596 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
597 CodeType = EfiRuntimeServicesCode;
598 DataType = EfiRuntimeServicesData;
599 break;
600
601 default:
602 return EFI_INVALID_PARAMETER;
603 }
604
605 Image->Type = ImageType;
606 Image->Info.ImageCodeType = CodeType;
607 Image->Info.ImageDataType = DataType;
608
609 return EFI_SUCCESS;
610 }
611
612 EFI_STATUS
EfiLdrPeCoffCheckImageMachineType(IN UINT16 MachineType)613 EfiLdrPeCoffCheckImageMachineType (
614 IN UINT16 MachineType
615 )
616 {
617 EFI_STATUS Status;
618
619 Status = EFI_UNSUPPORTED;
620
621 #ifdef MDE_CPU_IA32
622 if (MachineType == EFI_IMAGE_MACHINE_IA32) {
623 Status = EFI_SUCCESS;
624 }
625 #endif
626
627 #ifdef MDE_CPU_X64
628 if (MachineType == EFI_IMAGE_MACHINE_X64) {
629 Status = EFI_SUCCESS;
630 }
631 #endif
632
633 #ifdef MDE_CPU_IPF
634 if (MachineType == EFI_IMAGE_MACHINE_IA64) {
635 Status = EFI_SUCCESS;
636 }
637 #endif
638
639 return Status;
640 }
641
642