Home | History | Annotate | Download | only in EfiLdr
      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
     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
    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
    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
    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 *
    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
    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
    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