On Tue, Dec 22, 2015 at 02:57:50PM +0100, Alexander Graf wrote: > EFI uses the PE binary format for its application images. Add support to EFI > PE > binaries as well as all necessary bits for the "EFI image loader" interfaces. > > Signed-off-by: Alexander Graf <ag...@suse.de> > --- > include/efi_loader.h | 37 +++++ > include/pe.h | 277 > ++++++++++++++++++++++++++++++++++++++ > lib/efi_loader/efi_image_loader.c | 203 ++++++++++++++++++++++++++++ > 3 files changed, 517 insertions(+) > create mode 100644 include/efi_loader.h > create mode 100644 include/pe.h > create mode 100644 lib/efi_loader/efi_image_loader.c > > diff --git a/include/efi_loader.h b/include/efi_loader.h > new file mode 100644 > index 0000000..da82354 > --- /dev/null > +++ b/include/efi_loader.h > @@ -0,0 +1,37 @@ > +/* > + * EFI application loader > + * > + * Copyright (c) 2015 Alexander Graf > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA > + * > + * SPDX-License-Identifier: LGPL-2.1+ > + */ > + > +#include <part_efi.h> > +#include <efi_api.h> > +#include <linux/list.h> > + > +extern const efi_guid_t efi_guid_device_path; > +extern const efi_guid_t efi_guid_loaded_image; > + > +efi_status_t efi_return_handle(void *handle, > + efi_guid_t *protocol, void **protocol_interface, > + void *agent_handle, void *controller_handle, > + uint32_t attributes); > +void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info); > + > +#define EFI_LOADER_POOL_SIZE (128 * 1024 * 1024) > +void *efi_loader_alloc(uint64_t len); > diff --git a/include/pe.h b/include/pe.h > new file mode 100644 > index 0000000..009b0c5 > --- /dev/null > +++ b/include/pe.h > @@ -0,0 +1,277 @@ > +/* > + * Portable Executable binary format structures > + * > + * Copyright (c) 2015 Alexander Graf > + * > + * Based on wine code > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA > + * > + * SPDX-License-Identifier: LGPL-2.1+ > + */ > + > +#ifndef _PE_H > +#define _PE_H > + > +typedef struct _IMAGE_DOS_HEADER { > + uint16_t e_magic; /* 00: MZ Header signature */ > + uint16_t e_cblp; /* 02: Bytes on last page of file */ > + uint16_t e_cp; /* 04: Pages in file */ > + uint16_t e_crlc; /* 06: Relocations */ > + uint16_t e_cparhdr; /* 08: Size of header in paragraphs */ > + uint16_t e_minalloc; /* 0a: Minimum extra paragraphs needed */ > + uint16_t e_maxalloc; /* 0c: Maximum extra paragraphs needed */ > + uint16_t e_ss; /* 0e: Initial (relative) SS value */ > + uint16_t e_sp; /* 10: Initial SP value */ > + uint16_t e_csum; /* 12: Checksum */ > + uint16_t e_ip; /* 14: Initial IP value */ > + uint16_t e_cs; /* 16: Initial (relative) CS value */ > + uint16_t e_lfarlc; /* 18: File address of relocation table */ > + uint16_t e_ovno; /* 1a: Overlay number */ > + uint16_t e_res[4]; /* 1c: Reserved words */ > + uint16_t e_oemid; /* 24: OEM identifier (for e_oeminfo) */ > + uint16_t e_oeminfo; /* 26: OEM information; e_oemid specific */ > + uint16_t e_res2[10]; /* 28: Reserved words */ > + uint32_t e_lfanew; /* 3c: Offset to extended header */ > +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; > + > +#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ > +#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ > + > +#define IMAGE_FILE_MACHINE_ARM 0x01c0 > +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 > +#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 > +#define IMAGE_FILE_MACHINE_AMD64 0x8664 > +#define IMAGE_FILE_MACHINE_ARM64 0xaa64 > +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b > +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b > +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 > + > +typedef struct _IMAGE_FILE_HEADER { > + uint16_t Machine; > + uint16_t NumberOfSections; > + uint32_t TimeDateStamp; > + uint32_t PointerToSymbolTable; > + uint32_t NumberOfSymbols; > + uint16_t SizeOfOptionalHeader; > + uint16_t Characteristics; > +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; > + > +typedef struct _IMAGE_DATA_DIRECTORY { > + uint32_t VirtualAddress; > + uint32_t Size; > +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; > + > +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 > + > +typedef struct _IMAGE_OPTIONAL_HEADER64 { > + uint16_t Magic; /* 0x20b */ > + uint8_t MajorLinkerVersion; > + uint8_t MinorLinkerVersion; > + uint32_t SizeOfCode; > + uint32_t SizeOfInitializedData; > + uint32_t SizeOfUninitializedData; > + uint32_t AddressOfEntryPoint; > + uint32_t BaseOfCode; > + uint64_t ImageBase; > + uint32_t SectionAlignment; > + uint32_t FileAlignment; > + uint16_t MajorOperatingSystemVersion; > + uint16_t MinorOperatingSystemVersion; > + uint16_t MajorImageVersion; > + uint16_t MinorImageVersion; > + uint16_t MajorSubsystemVersion; > + uint16_t MinorSubsystemVersion; > + uint32_t Win32VersionValue; > + uint32_t SizeOfImage; > + uint32_t SizeOfHeaders; > + uint32_t CheckSum; > + uint16_t Subsystem; > + uint16_t DllCharacteristics; > + uint64_t SizeOfStackReserve; > + uint64_t SizeOfStackCommit; > + uint64_t SizeOfHeapReserve; > + uint64_t SizeOfHeapCommit; > + uint32_t LoaderFlags; > + uint32_t NumberOfRvaAndSizes; > + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; > +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; > + > +typedef struct _IMAGE_NT_HEADERS64 { > + uint32_t Signature; > + IMAGE_FILE_HEADER FileHeader; > + IMAGE_OPTIONAL_HEADER64 OptionalHeader; > +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; > + > +typedef struct _IMAGE_OPTIONAL_HEADER { > + > + /* Standard fields */ > + > + uint16_t Magic; /* 0x10b or 0x107 */ /* 0x00 */ > + uint8_t MajorLinkerVersion; > + uint8_t MinorLinkerVersion; > + uint32_t SizeOfCode; > + uint32_t SizeOfInitializedData; > + uint32_t SizeOfUninitializedData; > + uint32_t AddressOfEntryPoint; /* 0x10 */ > + uint32_t BaseOfCode; > + uint32_t BaseOfData; > + > + /* NT additional fields */ > + > + uint32_t ImageBase; > + uint32_t SectionAlignment; /* 0x20 */ > + uint32_t FileAlignment; > + uint16_t MajorOperatingSystemVersion; > + uint16_t MinorOperatingSystemVersion; > + uint16_t MajorImageVersion; > + uint16_t MinorImageVersion; > + uint16_t MajorSubsystemVersion; /* 0x30 */ > + uint16_t MinorSubsystemVersion; > + uint32_t Win32VersionValue; > + uint32_t SizeOfImage; > + uint32_t SizeOfHeaders; > + uint32_t CheckSum; /* 0x40 */ > + uint16_t Subsystem; > + uint16_t DllCharacteristics; > + uint32_t SizeOfStackReserve; > + uint32_t SizeOfStackCommit; > + uint32_t SizeOfHeapReserve; /* 0x50 */ > + uint32_t SizeOfHeapCommit; > + uint32_t LoaderFlags; > + uint32_t NumberOfRvaAndSizes; > + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; > /* 0x60 */ > + /* 0xE0 */ > +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; > + > +typedef struct _IMAGE_NT_HEADERS { > + uint32_t Signature; /* "PE"\0\0 */ /* 0x00 */ > + IMAGE_FILE_HEADER FileHeader; /* 0x04 */ > + IMAGE_OPTIONAL_HEADER32 OptionalHeader; /* 0x18 */ > +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; > + > +#define IMAGE_SIZEOF_SHORT_NAME 8 > + > +typedef struct _IMAGE_SECTION_HEADER { > + uint8_t Name[IMAGE_SIZEOF_SHORT_NAME]; > + union { > + uint32_t PhysicalAddress; > + uint32_t VirtualSize; > + } Misc; > + uint32_t VirtualAddress; > + uint32_t SizeOfRawData; > + uint32_t PointerToRawData; > + uint32_t PointerToRelocations; > + uint32_t PointerToLinenumbers; > + uint16_t NumberOfRelocations; > + uint16_t NumberOfLinenumbers; > + uint32_t Characteristics; > +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; > + > +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 > + > +typedef struct _IMAGE_BASE_RELOCATION > +{ > + uint32_t VirtualAddress; > + uint32_t SizeOfBlock; > + /* WORD TypeOffset[1]; */ > +} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; > + > +typedef struct _IMAGE_RELOCATION > +{ > + union { > + uint32_t VirtualAddress; > + uint32_t RelocCount; > + } DUMMYUNIONNAME; > + uint32_t SymbolTableIndex; > + uint16_t Type; > +} IMAGE_RELOCATION, *PIMAGE_RELOCATION; > + > +#define IMAGE_SIZEOF_RELOCATION 10 > + > +/* generic relocation types */ > +#define IMAGE_REL_BASED_ABSOLUTE 0 > +#define IMAGE_REL_BASED_HIGH 1 > +#define IMAGE_REL_BASED_LOW 2 > +#define IMAGE_REL_BASED_HIGHLOW 3 > +#define IMAGE_REL_BASED_HIGHADJ 4 > +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 > +#define IMAGE_REL_BASED_ARM_MOV32A 5 /* yes, 5 too */ > +#define IMAGE_REL_BASED_ARM_MOV32 5 /* yes, 5 too */ > +#define IMAGE_REL_BASED_SECTION 6 > +#define IMAGE_REL_BASED_REL 7 > +#define IMAGE_REL_BASED_ARM_MOV32T 7 /* yes, 7 too */ > +#define IMAGE_REL_BASED_THUMB_MOV32 7 /* yes, 7 too */ > +#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 > +#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ > +#define IMAGE_REL_BASED_DIR64 10 > +#define IMAGE_REL_BASED_HIGH3ADJ 11 > + > +/* ARM relocation types */ > +#define IMAGE_REL_ARM_ABSOLUTE 0x0000 > +#define IMAGE_REL_ARM_ADDR 0x0001 > +#define IMAGE_REL_ARM_ADDR32NB 0x0002 > +#define IMAGE_REL_ARM_BRANCH24 0x0003 > +#define IMAGE_REL_ARM_BRANCH11 0x0004 > +#define IMAGE_REL_ARM_TOKEN 0x0005 > +#define IMAGE_REL_ARM_GPREL12 0x0006 > +#define IMAGE_REL_ARM_GPREL7 0x0007 > +#define IMAGE_REL_ARM_BLX24 0x0008 > +#define IMAGE_REL_ARM_BLX11 0x0009 > +#define IMAGE_REL_ARM_SECTION 0x000E > +#define IMAGE_REL_ARM_SECREL 0x000F > +#define IMAGE_REL_ARM_MOV32A 0x0010 > +#define IMAGE_REL_ARM_MOV32T 0x0011 > +#define IMAGE_REL_ARM_BRANCH20T 0x0012 > +#define IMAGE_REL_ARM_BRANCH24T 0x0014 > +#define IMAGE_REL_ARM_BLX23T 0x0015 > + > +/* ARM64 relocation types */ > +#define IMAGE_REL_ARM64_ABSOLUTE 0x0000 > +#define IMAGE_REL_ARM64_ADDR32 0x0001 > +#define IMAGE_REL_ARM64_ADDR32NB 0x0002 > +#define IMAGE_REL_ARM64_BRANCH26 0x0003 > +#define IMAGE_REL_ARM64_PAGEBASE_REL21 0x0004 > +#define IMAGE_REL_ARM64_REL21 0x0005 > +#define IMAGE_REL_ARM64_PAGEOFFSET_12A 0x0006 > +#define IMAGE_REL_ARM64_PAGEOFFSET_12L 0x0007 > +#define IMAGE_REL_ARM64_SECREL 0x0008 > +#define IMAGE_REL_ARM64_SECREL_LOW12A 0x0009 > +#define IMAGE_REL_ARM64_SECREL_HIGH12A 0x000A > +#define IMAGE_REL_ARM64_SECREL_LOW12L 0x000B > +#define IMAGE_REL_ARM64_TOKEN 0x000C > +#define IMAGE_REL_ARM64_SECTION 0x000D > +#define IMAGE_REL_ARM64_ADDR64 0x000E > + > +/* AMD64 relocation types */ > +#define IMAGE_REL_AMD64_ABSOLUTE 0x0000 > +#define IMAGE_REL_AMD64_ADDR64 0x0001 > +#define IMAGE_REL_AMD64_ADDR32 0x0002 > +#define IMAGE_REL_AMD64_ADDR32NB 0x0003 > +#define IMAGE_REL_AMD64_REL32 0x0004 > +#define IMAGE_REL_AMD64_REL32_1 0x0005 > +#define IMAGE_REL_AMD64_REL32_2 0x0006 > +#define IMAGE_REL_AMD64_REL32_3 0x0007 > +#define IMAGE_REL_AMD64_REL32_4 0x0008 > +#define IMAGE_REL_AMD64_REL32_5 0x0009 > +#define IMAGE_REL_AMD64_SECTION 0x000A > +#define IMAGE_REL_AMD64_SECREL 0x000B > +#define IMAGE_REL_AMD64_SECREL7 0x000C > +#define IMAGE_REL_AMD64_TOKEN 0x000D > +#define IMAGE_REL_AMD64_SREL32 0x000E > +#define IMAGE_REL_AMD64_PAIR 0x000F > +#define IMAGE_REL_AMD64_SSPAN32 0x0010 > + > +#endif /* _PE_H */ > diff --git a/lib/efi_loader/efi_image_loader.c > b/lib/efi_loader/efi_image_loader.c > new file mode 100644 > index 0000000..688e177 > --- /dev/null > +++ b/lib/efi_loader/efi_image_loader.c > @@ -0,0 +1,203 @@ > +/* > + * EFI image loader > + * > + * based partly on wine code > + * > + * Copyright (c) 2015 Alexander Graf > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA > + * > + * SPDX-License-Identifier: LGPL-2.1+ > + */ > + > +#include <common.h> > +#include <pe.h> > +#include <efi_loader.h> > +#include <asm/global_data.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +#define ROUND_UP(val, round) ((val + (round - 1)) & ~(round - 1)) > +#define MB (1024 * 1024) > + > +const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID; > +const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID; > + > +efi_status_t efi_return_handle(void *handle, efi_guid_t *protocol, > + void **protocol_interface, void *agent_handle, > + void *controller_handle, uint32_t attributes) > +{ > + *protocol_interface = handle; > + return EFI_SUCCESS; > +} > + > +/* > + * EFI payloads potentially want to load pretty big images into memory, > + * so our small malloc region isn't enough for them. However, they usually > + * don't need a smart allocator either. > + * > + * So instead give them a really dumb one. We just reserve > EFI_LOADER_POOL_SIZE > + * bytes from 16MB below the malloc region start to give the stack some > space.
Is there any chance you could break out the memory allocation and memory map management as a separate patch, rather than spread across 3,4 and 6? Assigning a specific 128MB pool for LOADER_DATA memory can have unexpected side effects. > + * Then every allocation gets a 4k aligned chunk from it. We never free. Never freeing LOADER_DATA should not be an issue in and of itself. It all gets zapped by the OS anyway. > + */ > +void *efi_loader_alloc(uint64_t len) > +{ > + static unsigned long loader_pool; > + void *r; > + > + if (!loader_pool) { > + loader_pool = gd->relocaddr - TOTAL_MALLOC_LEN - > + EFI_LOADER_POOL_SIZE - (16 * MB); > + } > + > + len = ROUND_UP(len, 4096); > + /* Out of memory */ > + if ((loader_pool + len) >= (gd->relocaddr - TOTAL_MALLOC_LEN)) > + return NULL; > + > + r = (void *)loader_pool; > + loader_pool += len; > + > + return r; > +} > + > +/* > + * This function loads all sections from a PE binary into a newly reserved > + * piece of memory. On successful load it then returns the entry point for > + * the binary. Otherwise NULL. > + */ > +void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) > +{ > + IMAGE_NT_HEADERS32 *nt; > + IMAGE_DOS_HEADER *dos; > + IMAGE_SECTION_HEADER *sections; > + int num_sections; > + void *efi_reloc; > + int i; > + const uint16_t *relocs; > + const IMAGE_BASE_RELOCATION *rel; > + const IMAGE_BASE_RELOCATION *end; > + unsigned long rel_size; > + int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC; > + void *entry; > + uint64_t image_size; > + unsigned long virt_size = 0; > + > + dos = efi; > + if (dos->e_magic != IMAGE_DOS_SIGNATURE) { > + printf("%s: Invalid DOS Signature\n", __func__); > + return NULL; > + } > + > + nt = (void *) ((char *)efi + dos->e_lfanew); > + if (nt->Signature != IMAGE_NT_SIGNATURE) { > + printf("%s: Invalid NT Signature\n", __func__); > + return NULL; > + } > + > + /* Calculate upper virtual address boundary */ > + num_sections = nt->FileHeader.NumberOfSections; > + sections = (void *)&nt->OptionalHeader + > + nt->FileHeader.SizeOfOptionalHeader; > + > + for (i = num_sections - 1; i >= 0; i--) { > + IMAGE_SECTION_HEADER *sec = §ions[i]; > + virt_size = max_t(unsigned long, virt_size, > + sec->VirtualAddress + sec->Misc.VirtualSize); > + } > + > + /* Read 32/64bit specific header bits */ I guess x86 may support 32-on-64 or 64-on-32, but ARM won't - so could probably be compile-time conditionalised somehow. (CONFIG_EFI_SUPPORTS_PE32/CONFIG_EFI_SUPPORTS_PE64) > + if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { > + IMAGE_NT_HEADERS64 *nt64 = (void *)nt; > + IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader; > + image_size = opt->SizeOfImage; > + efi_reloc = efi_loader_alloc(virt_size); > + if (!efi_reloc) { > + printf("%s: Could not allocate %ld bytes\n", > + __func__, virt_size); > + return NULL; > + } > + entry = efi_reloc + opt->AddressOfEntryPoint; > + rel_size = opt->DataDirectory[rel_idx].Size; > + rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; > + } else { ...and should still check the magic value for 32-bit? > + IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader; > + image_size = opt->SizeOfImage; > + efi_reloc = efi_loader_alloc(virt_size); > + if (!efi_reloc) { > + printf("%s: Could not allocate %ld bytes\n", > + __func__, virt_size); > + return NULL; > + } > + entry = efi_reloc + opt->AddressOfEntryPoint; > + rel_size = opt->DataDirectory[rel_idx].Size; > + rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; > + } > + > + /* Load sections into RAM */ > + for (i = num_sections - 1; i >= 0; i--) { > + IMAGE_SECTION_HEADER *sec = §ions[i]; > + memset(efi_reloc + sec->VirtualAddress, 0, > + sec->Misc.VirtualSize); > + memcpy(efi_reloc + sec->VirtualAddress, > + efi + sec->PointerToRawData, > + sec->SizeOfRawData); > + } > + > + > + /* Run through relocations */ > + end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size); > + > + while (rel < end - 1 && rel->SizeOfBlock) { > + relocs = (const uint16_t *)(rel + 1); > + i = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(uint16_t); > + while (i--) { > + uint16_t offset = (*relocs & 0xfff) + > rel->VirtualAddress; > + int type = *relocs >> 12; > + unsigned long delta = (unsigned long)efi_reloc; > + uint64_t *x64 = efi_reloc + offset; > + uint32_t *x32 = efi_reloc + offset; > + uint16_t *x16 = efi_reloc + offset; > + > + switch (type) { > + case IMAGE_REL_BASED_ABSOLUTE: > + break; > + case IMAGE_REL_BASED_HIGH: > + *x16 += ((uint32_t)delta) >> 16; > + break; > + case IMAGE_REL_BASED_LOW: > + *x16 += (uint16_t)delta; > + break; > + case IMAGE_REL_BASED_HIGHLOW: > + *x32 += (uint32_t)delta; > + break; > + case IMAGE_REL_BASED_DIR64: > + *x64 += (uint64_t)delta; > + break; > + default: > + printf("Unknown Relocation off %x type %x\n", > + offset, type); > + } > + relocs++; > + } > + rel = (const IMAGE_BASE_RELOCATION *)relocs; > + } > + > + /* Populate the loaded image interface bits */ > + loaded_image_info->image_base = efi; > + loaded_image_info->image_size = image_size; > + > + return entry; > +} > -- > 2.1.4 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot