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