diff --git a/xtldr/modules/CMakeLists.txt b/xtldr/modules/CMakeLists.txt index 705ca81..9f54791 100644 --- a/xtldr/modules/CMakeLists.txt +++ b/xtldr/modules/CMakeLists.txt @@ -2,5 +2,5 @@ add_subdirectory(beep) add_subdirectory(chainldr) add_subdirectory(dummy) add_subdirectory(fb_o) -add_subdirectory(pecoff_o) +add_subdirectory(pecoff) add_subdirectory(xtos_o) diff --git a/xtldr/modules/pecoff/CMakeLists.txt b/xtldr/modules/pecoff/CMakeLists.txt new file mode 100644 index 0000000..7d8f86e --- /dev/null +++ b/xtldr/modules/pecoff/CMakeLists.txt @@ -0,0 +1,27 @@ +# XT Boot Loader +PROJECT(XTLDR_PECOFF) + +# Specify include directories +include_directories( + ${EXECTOS_SOURCE_DIR}/sdk/xtdk + ${XTLDR_PECOFF_SOURCE_DIR}/includes) + +# Specify list of source code files +list(APPEND XTLDR_PECOFF_SOURCE + ${XTLDR_PECOFF_SOURCE_DIR}/globals.c + ${XTLDR_PECOFF_SOURCE_DIR}/pecoff.c) + +# Link module executable +add_executable(pecoff ${XTLDR_PECOFF_SOURCE}) + +# Add linker libraries +target_link_libraries(pecoff libxtldr libxtos) + +# Set proper binary name and install target +set_target_properties(pecoff PROPERTIES SUFFIX .efi) +set_install_target(pecoff efi/boot/xtldr/modules) + +# Set module entrypoint and subsystem +set_entrypoint(pecoff "XtLdrModuleMain") +set_linker_map(pecoff TRUE) +set_subsystem(pecoff efi_boot_service_driver) diff --git a/xtldr/modules/pecoff/globals.c b/xtldr/modules/pecoff/globals.c new file mode 100644 index 0000000..6c3afc4 --- /dev/null +++ b/xtldr/modules/pecoff/globals.c @@ -0,0 +1,16 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/pecoff/globals.c + * DESCRIPTION: Basic PE/COFF executable file format support global variables + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* XTOS PE/COFF Image Protocol */ +XTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol; + +/* EFI XT Loader Protocol */ +PXTBL_LOADER_PROTOCOL XtLdrProtocol; diff --git a/xtldr/modules/pecoff/includes/globals.h b/xtldr/modules/pecoff/includes/globals.h new file mode 100644 index 0000000..5f2af34 --- /dev/null +++ b/xtldr/modules/pecoff/includes/globals.h @@ -0,0 +1,21 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/pecoff/includes/globals.h + * DESCRIPTION: Basic PE/COFF executable file format support global variables + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTLDR_PECOFF_GLOBALS_H +#define __XTLDR_PECOFF_GLOBALS_H + +#include + + +/* XTOS PE/COFF Image Protocol */ +EXTERN XTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol; + +/* EFI XT Loader Protocol */ +EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; + +#endif /* __XTLDR_PECOFF_GLOBALS_H */ diff --git a/xtldr/modules/pecoff_o/includes/pecoff.h b/xtldr/modules/pecoff/includes/pecoff.h similarity index 68% rename from xtldr/modules/pecoff_o/includes/pecoff.h rename to xtldr/modules/pecoff/includes/pecoff.h index af30bf9..3f01fe9 100644 --- a/xtldr/modules/pecoff_o/includes/pecoff.h +++ b/xtldr/modules/pecoff/includes/pecoff.h @@ -1,15 +1,16 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/pecoff_o/includes/pecoff.h - * DESCRIPTION: PE/COFF executable file format support header + * FILE: xtldr/modules/pecoff/includes/pecoff.h + * DESCRIPTION: Basic PE/COFF executable file format support header * DEVELOPERS: Rafal Kupiec */ -#ifndef __XTLDR_MODULES_PECOFF_O_H -#define __XTLDR_MODULES_PECOFF_O_H +#ifndef __XTLDR_PECOFF_H +#define __XTLDR_PECOFF_H #include +#include /* PE/COFF image protocol related routines forward references */ @@ -23,11 +24,22 @@ EFI_STATUS PeGetMachineType(IN PVOID ImagePointer, OUT PUSHORT MachineType); +XTCDECL +EFI_STATUS +PeGetSection(IN PVOID ImagePointer, + IN PCHAR SectionName, + OUT PULONG *RawData); + XTCDECL EFI_STATUS PeGetSubSystem(IN PVOID ImagePointer, OUT PUSHORT SubSystem); +XTCDECL +EFI_STATUS +PeGetVersion(IN PVOID ImagePointer, + OUT PUSHORT Version); + XTCDECL EFI_STATUS PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, @@ -42,17 +54,15 @@ PeRelocateImage(IN PVOID ImagePointer, XTCDECL EFI_STATUS -PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image); +PeVerifyImage(IN PVOID ImagePointer); XTCDECL EFI_STATUS -PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader, - IN PPECOFF_IMAGE_PE_HEADER PeHeader, - IN SIZE_T FileSize); +PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image); XTCDECL EFI_STATUS BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable); -#endif /* __XTLDR_MODULES_PECOFF_O_H */ +#endif /* __XTLDR_PECOFF_H */ diff --git a/xtldr/modules/pecoff_o/pecoff.c b/xtldr/modules/pecoff/pecoff.c similarity index 73% rename from xtldr/modules/pecoff_o/pecoff.c rename to xtldr/modules/pecoff/pecoff.c index 1659bbe..b26f26d 100644 --- a/xtldr/modules/pecoff_o/pecoff.c +++ b/xtldr/modules/pecoff/pecoff.c @@ -1,8 +1,8 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/pecoff_o/pecoff.c - * DESCRIPTION: OLD and deprecated PE/COFF executable file format support module + * FILE: xtldr/modules/pecoff/pecoff.c + * DESCRIPTION: Basic PE/COFF executable file format support module * DEVELOPERS: Rafal Kupiec */ @@ -10,22 +10,16 @@ /* PE/COFF_O module information */ -XTBL_MODINFO = L"PE/COFF executable file format support"; - -/* EFI XT Loader Protocol */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -/* XTOS PE/COFF Image Protocol */ -XTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol; +XTBL_MODINFO = L"Basic PE/COFF executable file format support"; /** * Returns the address of the entry point. * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. + * @param ImagePointer + * Supplies a pointer to the PE/COFF context structure representing the loaded image. * * @param EntryPoint - * A pointer to the memory area where address of the image entry point will be stored. + * Supplies a pointer to the memory area where address of the image entry point will be stored. * * @return This routine returns a status code. * @@ -53,11 +47,11 @@ PeGetEntryPoint(IN PVOID ImagePointer, /** * Returns the machine type of the PE/COFF image. * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. + * @param ImagePointer + * Supplies a pointer to the PE/COFF context structure representing the loaded image. * * @param MachineType - * A pointer to the memory area where a value defined for the 'machine' field will be stored. + * Supplies a pointer to the memory area where a value defined for the 'machine' field will be stored. * * @return This routine returns a status code. * @@ -82,14 +76,74 @@ PeGetMachineType(IN PVOID ImagePointer, return STATUS_EFI_SUCCESS; } +/** + * Returns an address to the specified section in the PE/COFF image. + * + * @param ImagePointer + * Supplies a pointer to the PE/COFF context structure representing the loaded image. + * + * @param SectionName + * Supplies a name of the requested section. + * + * @param RawData + * Supplies a pointer to the memory area where the address of the requested section will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeGetSection(IN PVOID ImagePointer, + IN PCHAR SectionName, + OUT PULONG *RawData) +{ + PPECOFF_IMAGE_SECTION_HEADER SectionHeader; + PPECOFF_IMAGE_CONTEXT Image; + SIZE_T SectionNameLength; + USHORT SectionIndex; + + /* Get PE/COFF image pointer*/ + Image = ImagePointer; + + /* Validate input data */ + if(!Image || !Image->PeHeader) + { + /* Invalid parameter passed */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Find section header */ + SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&Image->PeHeader->OptionalHeader + + Image->PeHeader->FileHeader.SizeOfOptionalHeader); + + /* Get section name length */ + SectionNameLength = RtlStringLength(SectionName, 0); + + /* Iterate through all image sections */ + for(SectionIndex = 0; SectionIndex < Image->PeHeader->FileHeader.NumberOfSections; SectionIndex++) + { + /* Check section name */ + if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, SectionName, SectionNameLength) == 0) + { + /* Store section address and return */ + *RawData = Image->Data + SectionHeader[SectionIndex].PointerToRawData; + return STATUS_EFI_SUCCESS; + } + } + + /* Section not found if reached here */ + return STATUS_EFI_NOT_FOUND; +} + /** * Returns an information about subsystem that is required to run PE/COFF image. * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. + * @param ImagePointer + * Supplies a pointer to the PE/COFF context structure representing the loaded image. * * @param SubSystem - * A pointer to the memory area storing a value defined for the 'subsystem' field of the image. + * Supplies a pointer to the memory area storing a value defined for the 'subsystem' field of the image. * * @return This routine returns a status code. * @@ -114,6 +168,38 @@ PeGetSubSystem(IN PVOID ImagePointer, return STATUS_EFI_SUCCESS; } +/** + * Returns an information about major image version. + * + * @param ImagePointer + * Supplies a pointer to the PE/COFF context structure representing the loaded image. + * + * @param Version + * Supplies a pointer to the memory area storing a major image version. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeGetVersion(IN PVOID ImagePointer, + OUT PUSHORT Version) +{ + PPECOFF_IMAGE_CONTEXT Image = ImagePointer; + + /* Validate input data */ + if(!Image || !Image->PeHeader) + { + /* Invalid parameter passed */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Get image major version and return success */ + *Version = Image->PeHeader->OptionalHeader.MajorImageVersion; + return STATUS_EFI_SUCCESS; +} + /** * Loads a PE/COFF image file. * @@ -160,7 +246,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); return Status; } @@ -174,7 +260,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); return Status; } @@ -184,7 +270,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Unable to get file information */ - XtLdrProtocol->Debug.Print(L"ERROR: Failed to get file information\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Failed to get PE/COFF file information (Status Code: 0x%lx)\n", Status); return Status; } @@ -193,7 +279,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status); return Status; } @@ -211,7 +297,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Pages allocation failure */ - XtLdrProtocol->Debug.Print(L"ERROR: Pages allocation failure\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Pages allocation failure (Status Code: 0x%lx)\n", Status); XtLdrProtocol->Memory.FreePool(ImageData); return Status; } @@ -223,7 +309,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to read data */ - XtLdrProtocol->Debug.Print(L"ERROR: Unable to read PE/COFF image file\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Failed to read PE/COFF image file (Status Code: 0x%lx)\n", Status); XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); XtLdrProtocol->Memory.FreePool(ImageData); return Status; @@ -234,11 +320,11 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUINT8)Data + ImageData->DosHeader->PeHeaderOffset); /* Validate headers */ - Status = PepValidateImageHeaders(ImageData->DosHeader, ImageData->PeHeader, ImageData->FileSize); + Status = PeVerifyImage(ImageData); if(Status != STATUS_EFI_SUCCESS) { /* Header validation failed, probably broken or invalid PE/COFF image */ - XtLdrProtocol->Debug.Print(L"ERROR: Invalid PE/COFF image headers\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Invalid PE/COFF image headers (Status Code: 0x%lx)\n", Status); XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data); XtLdrProtocol->Memory.FreePool(ImageData); return Status; @@ -263,7 +349,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Pages reallocation failure */ - XtLdrProtocol->Debug.Print(L"ERROR: Pages reallocation failure\n"); + XtLdrProtocol->Debug.Print(L"ERROR: Pages reallocation failure (Status Code: 0x%lx)\n", Status); XtLdrProtocol->Memory.FreePool(ImageData); return Status; } @@ -329,7 +415,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to relocate image */ - XtLdrProtocol->Debug.Print(L"ERROR: PE/COFF image relocation failed\n"); + XtLdrProtocol->Debug.Print(L"ERROR: PE/COFF image relocation failed (Status Code: 0x%lx)\n", Status); return Status; } @@ -343,11 +429,11 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, /** * Relocates PE/COFF image to the specified address. * - * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. + * @param ImagePointer + * Supplies a pointer to the PE/COFF context structure representing the loaded image. * * @param Address - * Destination address of memory region, where image should be relocated. + * Specifies destination address of memory region, where image should be relocated. * * @return This routine returns status code. * @@ -394,11 +480,68 @@ PeRelocateImage(IN PVOID ImagePointer, return STATUS_EFI_SUCCESS; } +/** + * Validates a PE/COFF image headers. + * + * @param ImagePointer + * Supplies a pointer to the PE/COFF context structure representing the loaded image. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +PeVerifyImage(IN PVOID ImagePointer) +{ + PPECOFF_IMAGE_CONTEXT Image = ImagePointer; + + /* Validate input data */ + if(!Image || !Image->PeHeader) + { + /* Invalid parameter passed */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Validate file size */ + if(Image->FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER)) + { + /* PE/COFF image shorter than DOS header, return error*/ + return STATUS_EFI_END_OF_FILE; + } + + /* Validate DOS header */ + if(Image->DosHeader->Magic != PECOFF_IMAGE_DOS_SIGNATURE) + { + /* Invalid DOS signature, return error */ + return STATUS_EFI_INCOMPATIBLE_VERSION; + } + + /* Validate PE header */ + if(Image->PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE && + Image->PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE) + { + /* Invalid PE signature, return error */ + return STATUS_EFI_INCOMPATIBLE_VERSION; + } + + /* Validate optional header */ + if(Image->PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC && + Image->PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) + { + /* Invalid optional header signature, return error */ + return STATUS_EFI_INCOMPATIBLE_VERSION; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * Relocates a loaded PE/COFF image. * * @param Image - * A pointer to the PE/COFF context structure representing the loaded image. + * Supplies a pointer to the PE/COFF context structure representing the loaded image. * * @return This routine returns a status code. * @@ -511,61 +654,6 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) return STATUS_EFI_SUCCESS; } -/** - * Validates a PE/COFF image headers. - * - * @param DosHeader - * Pointer to the memory area with DOS header stored. - * - * @param PeHeader - * Pointer to the memory area with PE header stored. - * - * @param FileSize - * A PE/COFF image file size. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader, - IN PPECOFF_IMAGE_PE_HEADER PeHeader, - IN SIZE_T FileSize) -{ - /* Validate file size */ - if(FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER)) - { - XtLdrProtocol->Debug.Print(L"WARNING: PE/COFF image shorter than DOS header\n"); - return STATUS_EFI_END_OF_FILE; - } - - /* Validate DOS header */ - if(DosHeader->Magic != PECOFF_IMAGE_DOS_SIGNATURE) - { - XtLdrProtocol->Debug.Print(L"WARNING: Invalid DOS signature found\n"); - return STATUS_EFI_INCOMPATIBLE_VERSION; - } - - /* Validate PE header */ - if(PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE && PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE) - { - XtLdrProtocol->Debug.Print(L"WARNING: Invalid NT/XT signature found\n"); - return STATUS_EFI_INCOMPATIBLE_VERSION; - } - - /* Validate optional header */ - if(PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC && - PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) - { - XtLdrProtocol->Debug.Print(L"WARNING: Invalid optional header signature found\n"); - return STATUS_EFI_INCOMPATIBLE_VERSION; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - /** * This routine is the entry point of the XT EFI boot loader module. * @@ -596,12 +684,15 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, } /* Set routines available via PE/COFF image protocol */ - XtPeCoffProtocol.GetEntryPoint = PeGetEntryPoint; - XtPeCoffProtocol.GetMachineType = PeGetMachineType; - XtPeCoffProtocol.GetSubSystem = PeGetSubSystem; - XtPeCoffProtocol.LoadImage = PeLoadImage; - XtPeCoffProtocol.RelocateImage = PeRelocateImage; + PeCoffProtocol.GetEntryPoint = PeGetEntryPoint; + PeCoffProtocol.GetMachineType = PeGetMachineType; + PeCoffProtocol.GetSection = PeGetSection; + PeCoffProtocol.GetSubSystem = PeGetSubSystem; + PeCoffProtocol.GetVersion = PeGetVersion; + PeCoffProtocol.LoadImage = PeLoadImage; + PeCoffProtocol.RelocateImage = PeRelocateImage; + PeCoffProtocol.VerifyImage = PeVerifyImage; /* Register PE/COFF protocol */ - return XtLdrProtocol->Protocol.Install(&XtPeCoffProtocol, &Guid); + return XtLdrProtocol->Protocol.Install(&PeCoffProtocol, &Guid); } diff --git a/xtldr/modules/pecoff_o/CMakeLists.txt b/xtldr/modules/pecoff_o/CMakeLists.txt deleted file mode 100644 index d96155b..0000000 --- a/xtldr/modules/pecoff_o/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -# XT Boot Loader -PROJECT(XTLDR_PECOFF_O) - -# Specify include directories -include_directories( - ${EXECTOS_SOURCE_DIR}/sdk/xtdk - ${XTLDR_PECOFF_O_SOURCE_DIR}/includes) - -# Specify list of source code files -list(APPEND XTLDR_PECOFF_O_SOURCE - ${XTLDR_PECOFF_O_SOURCE_DIR}/pecoff.c) - -# Link bootloader executable -add_executable(pecoff_o ${XTLDR_PECOFF_O_SOURCE}) - -# Add linker libraries -target_link_libraries(pecoff_o libxtldr) - -# Set proper binary name and install target -set_target_properties(pecoff_o PROPERTIES SUFFIX .efi) -set_install_target(pecoff_o efi/boot/xtldr/modules) - -# Set module entrypoint and subsystem -set_entrypoint(pecoff_o "XtLdrModuleMain") -set_linker_map(pecoff_o TRUE) -set_subsystem(pecoff_o efi_boot_service_driver) diff --git a/xtldr/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.c index 6937e04..f7e163f 100644 --- a/xtldr/modules/xtos_o/xtos.c +++ b/xtldr/modules/xtos_o/xtos.c @@ -11,7 +11,7 @@ /* XTOS module information */ XTBL_MODINFO = L"XTOS boot protocol support"; -XTBL_MODDEPS = {L"fb_o", L"pecoff_o"}; +XTBL_MODDEPS = {L"fb_o", L"pecoff"}; /* EFI XT Loader Protocol */ PXTBL_LOADER_PROTOCOL XtLdrProtocol;