| /*++ | |
| Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| Module Name: | |
| PeLoader.c | |
| Abstract: | |
| Revision History: | |
| --*/ | |
| #include "EfiLdr.h" | |
| #include "Debug.h" | |
| #include "Support.h" | |
| 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 | |
| ); | |
| EFI_STATUS | |
| EfiLdrPeCoffImageRead ( | |
| IN VOID *FHand, | |
| IN UINTN Offset, | |
| IN OUT UINTN ReadSize, | |
| OUT VOID *Buffer | |
| ); | |
| VOID * | |
| EfiLdrPeCoffImageAddress ( | |
| IN EFILDR_LOADED_IMAGE *Image, | |
| IN UINTN Address | |
| ); | |
| EFI_STATUS | |
| EfiLdrPeCoffSetImageType ( | |
| IN OUT EFILDR_LOADED_IMAGE *Image, | |
| IN UINTN ImageType | |
| ); | |
| EFI_STATUS | |
| EfiLdrPeCoffCheckImageMachineType ( | |
| IN UINT16 MachineType | |
| ); | |
| EFI_STATUS | |
| EfiLdrGetPeImageInfo ( | |
| IN VOID *FHand, | |
| OUT UINT64 *ImageBase, | |
| OUT UINT32 *ImageSize | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_IMAGE_DOS_HEADER DosHdr; | |
| EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr; | |
| ZeroMem (&DosHdr, sizeof(DosHdr)); | |
| ZeroMem (&PeHdr, sizeof(PeHdr)); | |
| // | |
| // Read image headers | |
| // | |
| EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr); | |
| if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr); | |
| if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| // | |
| // Verify machine type | |
| // | |
| Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine); | |
| if (EFI_ERROR(Status)) { | |
| return Status; | |
| } | |
| if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { | |
| *ImageBase = (UINT32)PeHdr.Pe32.OptionalHeader.ImageBase; | |
| } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { | |
| *ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase; | |
| } else { | |
| return EFI_UNSUPPORTED; | |
| } | |
| *ImageSize = PeHdr.Pe32.OptionalHeader.SizeOfImage; | |
| return EFI_SUCCESS; | |
| } | |
| EFI_STATUS | |
| EfiLdrPeCoffLoadPeImage ( | |
| IN VOID *FHand, | |
| IN EFILDR_LOADED_IMAGE *Image, | |
| IN UINTN *NumberOfMemoryMapEntries, | |
| IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor | |
| ) | |
| { | |
| EFI_IMAGE_DOS_HEADER DosHdr; | |
| EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr; | |
| EFI_IMAGE_SECTION_HEADER *FirstSection; | |
| EFI_IMAGE_SECTION_HEADER *Section; | |
| UINTN Index; | |
| EFI_STATUS Status; | |
| UINT8 *Base; | |
| UINT8 *End; | |
| EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; | |
| UINTN DirCount; | |
| EFI_IMAGE_DEBUG_DIRECTORY_ENTRY TempDebugEntry; | |
| EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; | |
| UINTN CodeViewSize; | |
| UINTN CodeViewOffset; | |
| UINTN CodeViewFileOffset; | |
| UINTN OptionalHeaderSize; | |
| UINTN PeHeaderSize; | |
| UINT32 NumberOfRvaAndSizes; | |
| EFI_IMAGE_DATA_DIRECTORY *DataDirectory; | |
| UINT64 ImageBase; | |
| CHAR8 PrintBuffer[256]; | |
| ZeroMem (&DosHdr, sizeof(DosHdr)); | |
| ZeroMem (&PeHdr, sizeof(PeHdr)); | |
| // | |
| // Read image headers | |
| // | |
| EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr); | |
| if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) { | |
| AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Dos header signature not found\n"); | |
| PrintString (PrintBuffer); | |
| PrintHeader ('F'); | |
| return EFI_UNSUPPORTED; | |
| } | |
| EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr); | |
| if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { | |
| AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: PE image header signature not found\n"); | |
| PrintString (PrintBuffer); | |
| PrintHeader ('G'); | |
| return EFI_UNSUPPORTED; | |
| } | |
| // | |
| // Set the image subsystem type | |
| // | |
| Status = EfiLdrPeCoffSetImageType (Image, PeHdr.Pe32.OptionalHeader.Subsystem); | |
| if (EFI_ERROR(Status)) { | |
| AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Subsystem type not known\n"); | |
| PrintString (PrintBuffer); | |
| PrintHeader ('H'); | |
| return Status; | |
| } | |
| // | |
| // Verify machine type | |
| // | |
| Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine); | |
| if (EFI_ERROR(Status)) { | |
| AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Incorrect machine type\n"); | |
| PrintString (PrintBuffer); | |
| PrintHeader ('I'); | |
| return Status; | |
| } | |
| // | |
| // Compute the amount of memory needed to load the image and | |
| // allocate it. This will include all sections plus the codeview debug info. | |
| // Since the codeview info is actually outside of the image, we calculate | |
| // its size seperately and add it to the total. | |
| // | |
| // Memory starts off as data | |
| // | |
| CodeViewSize = 0; | |
| CodeViewFileOffset = 0; | |
| if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { | |
| DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); | |
| } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { | |
| DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); | |
| } else { | |
| return EFI_UNSUPPORTED; | |
| } | |
| for (DirCount = 0; | |
| (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && (CodeViewSize == 0); | |
| DirCount++) { | |
| Status = EfiLdrPeCoffImageRead ( | |
| FHand, | |
| DirectoryEntry->VirtualAddress + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), | |
| sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), | |
| &TempDebugEntry | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| if (TempDebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { | |
| CodeViewSize = TempDebugEntry.SizeOfData; | |
| CodeViewFileOffset = TempDebugEntry.FileOffset; | |
| } | |
| } | |
| } | |
| CodeViewOffset = PeHdr.Pe32.OptionalHeader.SizeOfImage + PeHdr.Pe32.OptionalHeader.SectionAlignment; | |
| Image->NoPages = EFI_SIZE_TO_PAGES (CodeViewOffset + CodeViewSize); | |
| // | |
| // Compute the amount of memory needed to load the image and | |
| // allocate it. Memory starts off as data | |
| // | |
| Image->ImageBasePage = (EFI_PHYSICAL_ADDRESS)FindSpace (Image->NoPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesCode, EFI_MEMORY_WB); | |
| if (Image->ImageBasePage == 0) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| if (EFI_ERROR(Status)) { | |
| PrintHeader ('J'); | |
| return Status; | |
| } | |
| AsciiSPrint (PrintBuffer, 256, "LoadPe: new image base %lx\n", Image->ImageBasePage); | |
| PrintString (PrintBuffer); | |
| Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageBasePage; | |
| Image->Info.ImageSize = (Image->NoPages << EFI_PAGE_SHIFT) - 1; | |
| Image->ImageBase = (UINT8 *)(UINTN)Image->ImageBasePage; | |
| Image->ImageEof = Image->ImageBase + Image->Info.ImageSize; | |
| Image->ImageAdjust = Image->ImageBase; | |
| // | |
| // Copy the Image header to the base location | |
| // | |
| Status = EfiLdrPeCoffImageRead ( | |
| FHand, | |
| 0, | |
| PeHdr.Pe32.OptionalHeader.SizeOfHeaders, | |
| Image->ImageBase | |
| ); | |
| if (EFI_ERROR(Status)) { | |
| PrintHeader ('K'); | |
| return Status; | |
| } | |
| // | |
| // Load each directory of the image into memory... | |
| // Save the address of the Debug directory for later | |
| // | |
| if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { | |
| NumberOfRvaAndSizes = PeHdr.Pe32.OptionalHeader.NumberOfRvaAndSizes; | |
| DataDirectory = PeHdr.Pe32.OptionalHeader.DataDirectory; | |
| } else { | |
| NumberOfRvaAndSizes = PeHdr.Pe32Plus.OptionalHeader.NumberOfRvaAndSizes; | |
| DataDirectory = PeHdr.Pe32Plus.OptionalHeader.DataDirectory; | |
| } | |
| DebugEntry = NULL; | |
| for (Index = 0; Index < NumberOfRvaAndSizes; Index++) { | |
| if ((DataDirectory[Index].VirtualAddress != 0) && (DataDirectory[Index].Size != 0)) { | |
| Status = EfiLdrPeCoffImageRead ( | |
| FHand, | |
| DataDirectory[Index].VirtualAddress, | |
| DataDirectory[Index].Size, | |
| Image->ImageBase + DataDirectory[Index].VirtualAddress | |
| ); | |
| if (EFI_ERROR(Status)) { | |
| return Status; | |
| } | |
| if (Index == EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { | |
| DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (Image->ImageBase + DataDirectory[Index].VirtualAddress); | |
| } | |
| } | |
| } | |
| // | |
| // Load each section of the image | |
| // | |
| // BUGBUG: change this to use the in memory copy | |
| if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { | |
| OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32); | |
| PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS32); | |
| } else { | |
| OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64); | |
| PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS64); | |
| } | |
| FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( | |
| Image->ImageBase + | |
| DosHdr.e_lfanew + | |
| PeHeaderSize + | |
| PeHdr.Pe32.FileHeader.SizeOfOptionalHeader - | |
| OptionalHeaderSize | |
| ); | |
| Section = FirstSection; | |
| for (Index=0; Index < PeHdr.Pe32.FileHeader.NumberOfSections; Index += 1) { | |
| // | |
| // Compute sections address | |
| // | |
| Base = EfiLdrPeCoffImageAddress (Image, (UINTN)Section->VirtualAddress); | |
| End = EfiLdrPeCoffImageAddress (Image, (UINTN)(Section->VirtualAddress + Section->Misc.VirtualSize)); | |
| if (EFI_ERROR(Status) || !Base || !End) { | |
| // DEBUG((D_LOAD|D_ERROR, "LoadPe: Section %d was not loaded\n", Index)); | |
| PrintHeader ('L'); | |
| return EFI_LOAD_ERROR; | |
| } | |
| // DEBUG((D_LOAD, "LoadPe: Section %d, loaded at %x\n", Index, Base)); | |
| // | |
| // Read the section | |
| // | |
| if (Section->SizeOfRawData) { | |
| Status = EfiLdrPeCoffImageRead (FHand, Section->PointerToRawData, Section->SizeOfRawData, Base); | |
| if (EFI_ERROR(Status)) { | |
| PrintHeader ('M'); | |
| return Status; | |
| } | |
| } | |
| // | |
| // If raw size is less then virt size, zero fill the remaining | |
| // | |
| if (Section->SizeOfRawData < Section->Misc.VirtualSize) { | |
| ZeroMem ( | |
| Base + Section->SizeOfRawData, | |
| Section->Misc.VirtualSize - Section->SizeOfRawData | |
| ); | |
| } | |
| // | |
| // Next Section | |
| // | |
| Section += 1; | |
| } | |
| // | |
| // Copy in CodeView information if it exists | |
| // | |
| if (CodeViewSize != 0) { | |
| Status = EfiLdrPeCoffImageRead (FHand, CodeViewFileOffset, CodeViewSize, Image->ImageBase + CodeViewOffset); | |
| DebugEntry->RVA = (UINT32) (CodeViewOffset); | |
| } | |
| // | |
| // Apply relocations only if needed | |
| // | |
| if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { | |
| ImageBase = (UINT64)PeHdr.Pe32.OptionalHeader.ImageBase; | |
| } else { | |
| ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase; | |
| } | |
| if ((UINTN)(Image->ImageBase) != (UINTN) (ImageBase)) { | |
| Status = EfiLdrPeCoffLoadPeRelocate ( | |
| Image, | |
| &DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC], | |
| (UINTN) Image->ImageBase - (UINTN)ImageBase, | |
| NumberOfMemoryMapEntries, | |
| EfiMemoryDescriptor | |
| ); | |
| if (EFI_ERROR(Status)) { | |
| PrintHeader ('N'); | |
| return Status; | |
| } | |
| } | |
| // | |
| // Use exported EFI specific interface if present, else use the image's entry point | |
| // | |
| Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN) | |
| (EfiLdrPeCoffImageAddress( | |
| Image, | |
| PeHdr.Pe32.OptionalHeader.AddressOfEntryPoint | |
| )); | |
| return Status; | |
| } | |
| 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 | |
| ) | |
| { | |
| EFI_IMAGE_BASE_RELOCATION *RelocBase; | |
| EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; | |
| UINT16 *Reloc; | |
| UINT16 *RelocEnd; | |
| UINT8 *Fixup; | |
| UINT8 *FixupBase; | |
| UINT16 *F16; | |
| UINT32 *F32; | |
| UINT64 *F64; | |
| UINT8 *FixupData; | |
| UINTN NoFixupPages; | |
| // | |
| // Find the relocation block | |
| // | |
| RelocBase = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress); | |
| RelocBaseEnd = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size); | |
| if (!RelocBase || !RelocBaseEnd) { | |
| PrintHeader ('O'); | |
| return EFI_LOAD_ERROR; | |
| } | |
| NoFixupPages = EFI_SIZE_TO_PAGES(RelocDir->Size / sizeof(UINT16) * sizeof(UINTN)); | |
| Image->FixupData = (UINT8*) FindSpace (NoFixupPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB); | |
| if (Image->FixupData == 0) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| // | |
| // Run the whole relocation block | |
| // | |
| FixupData = Image->FixupData; | |
| while (RelocBase < RelocBaseEnd) { | |
| Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION)); | |
| RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock); | |
| FixupBase = EfiLdrPeCoffImageAddress (Image, RelocBase->VirtualAddress); | |
| if ((UINT8 *) RelocEnd < Image->ImageBase || (UINT8 *) RelocEnd > Image->ImageEof) { | |
| PrintHeader ('P'); | |
| return EFI_LOAD_ERROR; | |
| } | |
| // | |
| // Run this relocation record | |
| // | |
| while (Reloc < RelocEnd) { | |
| Fixup = FixupBase + (*Reloc & 0xFFF); | |
| switch ((*Reloc) >> 12) { | |
| case EFI_IMAGE_REL_BASED_ABSOLUTE: | |
| break; | |
| case EFI_IMAGE_REL_BASED_HIGH: | |
| F16 = (UINT16 *) Fixup; | |
| *F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16)); | |
| if (FixupData != NULL) { | |
| *(UINT16 *) FixupData = *F16; | |
| FixupData = FixupData + sizeof(UINT16); | |
| } | |
| break; | |
| case EFI_IMAGE_REL_BASED_LOW: | |
| F16 = (UINT16 *) Fixup; | |
| *F16 = (UINT16) (*F16 + (UINT16) Adjust); | |
| if (FixupData != NULL) { | |
| *(UINT16 *) FixupData = *F16; | |
| FixupData = FixupData + sizeof(UINT16); | |
| } | |
| break; | |
| case EFI_IMAGE_REL_BASED_HIGHLOW: | |
| F32 = (UINT32 *) Fixup; | |
| *F32 = *F32 + (UINT32) Adjust; | |
| if (FixupData != NULL) { | |
| FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32)); | |
| *(UINT32 *) FixupData = *F32; | |
| FixupData = FixupData + sizeof(UINT32); | |
| } | |
| break; | |
| case EFI_IMAGE_REL_BASED_DIR64: | |
| F64 = (UINT64 *) Fixup; | |
| *F64 = *F64 + (UINT64) Adjust; | |
| if (FixupData != NULL) { | |
| FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64)); | |
| *(UINT64 *) FixupData = *F64; | |
| FixupData = FixupData + sizeof(UINT64); | |
| } | |
| break; | |
| case EFI_IMAGE_REL_BASED_HIGHADJ: | |
| CpuDeadLoop(); // BUGBUG: not done | |
| break; | |
| default: | |
| // DEBUG((D_LOAD|D_ERROR, "PeRelocate: unknown fixed type\n")); | |
| PrintHeader ('Q'); | |
| CpuDeadLoop(); | |
| return EFI_LOAD_ERROR; | |
| } | |
| // Next reloc record | |
| Reloc += 1; | |
| } | |
| // next reloc block | |
| RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; | |
| } | |
| // | |
| // Add Fixup data to whole Image (assume Fixup data just below the image), so that there is no hole in the descriptor. | |
| // Because only NoPages or ImageBasePage will be used in EfiLoader(), we update these 2 fields. | |
| // | |
| Image->NoPages += NoFixupPages; | |
| Image->ImageBasePage -= (NoFixupPages << EFI_PAGE_SHIFT); | |
| return EFI_SUCCESS; | |
| } | |
| EFI_STATUS | |
| EfiLdrPeCoffImageRead ( | |
| IN VOID *FHand, | |
| IN UINTN Offset, | |
| IN OUT UINTN ReadSize, | |
| OUT VOID *Buffer | |
| ) | |
| { | |
| CopyMem (Buffer, (VOID *)((UINTN)FHand + Offset), ReadSize); | |
| return EFI_SUCCESS; | |
| } | |
| VOID * | |
| EfiLdrPeCoffImageAddress ( | |
| IN EFILDR_LOADED_IMAGE *Image, | |
| IN UINTN Address | |
| ) | |
| { | |
| UINT8 *FixedAddress; | |
| FixedAddress = Image->ImageAdjust + Address; | |
| if ((FixedAddress < Image->ImageBase) || (FixedAddress > Image->ImageEof)) { | |
| // DEBUG((D_LOAD|D_ERROR, "PeCoffImageAddress: pointer is outside of image\n")); | |
| FixedAddress = NULL; | |
| } | |
| // DEBUG(( | |
| // D_LOAD, | |
| // "PeCoffImageAddress: ImageBase %x, ImageEof %x, Address %x, FixedAddress %x\n", | |
| // Image->ImageBase, | |
| // Image->ImageEof, | |
| // Address, | |
| // FixedAddress | |
| // )); | |
| return FixedAddress; | |
| } | |
| EFI_STATUS | |
| EfiLdrPeCoffSetImageType ( | |
| IN OUT EFILDR_LOADED_IMAGE *Image, | |
| IN UINTN ImageType | |
| ) | |
| { | |
| EFI_MEMORY_TYPE CodeType; | |
| EFI_MEMORY_TYPE DataType; | |
| switch (ImageType) { | |
| case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION: | |
| CodeType = EfiLoaderCode; | |
| DataType = EfiLoaderData; | |
| break; | |
| case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: | |
| CodeType = EfiBootServicesCode; | |
| DataType = EfiBootServicesData; | |
| break; | |
| case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: | |
| CodeType = EfiRuntimeServicesCode; | |
| DataType = EfiRuntimeServicesData; | |
| break; | |
| default: | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| Image->Type = ImageType; | |
| Image->Info.ImageCodeType = CodeType; | |
| Image->Info.ImageDataType = DataType; | |
| return EFI_SUCCESS; | |
| } | |
| EFI_STATUS | |
| EfiLdrPeCoffCheckImageMachineType ( | |
| IN UINT16 MachineType | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = EFI_UNSUPPORTED; | |
| #ifdef MDE_CPU_IA32 | |
| if (MachineType == EFI_IMAGE_MACHINE_IA32) { | |
| Status = EFI_SUCCESS; | |
| } | |
| #endif | |
| #ifdef MDE_CPU_X64 | |
| if (MachineType == EFI_IMAGE_MACHINE_X64) { | |
| Status = EFI_SUCCESS; | |
| } | |
| #endif | |
| #ifdef MDE_CPU_IPF | |
| if (MachineType == EFI_IMAGE_MACHINE_IA64) { | |
| Status = EFI_SUCCESS; | |
| } | |
| #endif | |
| return Status; | |
| } | |