All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Graf <agraf@suse.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 3/9] efi_loader: Add PE image loader
Date: Fri, 15 Jan 2016 00:45:46 +0100	[thread overview]
Message-ID: <5698332A.4040800@suse.de> (raw)
In-Reply-To: <20151226162633.GX25034@bivouac.eciton.net>



On 26.12.15 17:26, Leif Lindholm wrote:
> 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 <agraf@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?

Uh, sure, I can try. I'm not sure it'll end up more readable than now
though :).

> 
> Assigning a specific 128MB pool for LOADER_DATA memory can have
> unexpected side effects.

Like for example?

> 
>> + * 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.

That's the idea, yes :).

> 
>> + */
>> +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 = &sections[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)

I think I have a reasonably elegant solution now. I hope.

> 
>> +	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?

True.


Alex

  reply	other threads:[~2016-01-14 23:45 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-22 13:57 [U-Boot] [PATCH 0/9] EFI payload / application support Alexander Graf
2015-12-22 13:57 ` [U-Boot] [PATCH 1/9] disk/part.c: Expose a list of available block drivers Alexander Graf
2016-01-14 19:18   ` Tom Rini
2016-01-14 23:11   ` Simon Glass
2016-01-14 23:33     ` Alexander Graf
2016-01-15  0:46       ` Simon Glass
2016-01-15  1:04         ` Alexander Graf
2015-12-22 13:57 ` [U-Boot] [PATCH 2/9] include/efi_api.h: Add more detailed API definitions Alexander Graf
2015-12-22 13:57 ` [U-Boot] [PATCH 3/9] efi_loader: Add PE image loader Alexander Graf
2015-12-26 16:26   ` Leif Lindholm
2016-01-14 23:45     ` Alexander Graf [this message]
2016-01-15 12:29       ` Leif Lindholm
2015-12-22 13:57 ` [U-Boot] [PATCH 4/9] efi_loader: Add boot time services Alexander Graf
2015-12-22 14:15   ` Andreas Färber
2015-12-22 14:31     ` Alexander Graf
2015-12-26 18:09   ` Leif Lindholm
2016-01-15  0:13     ` Alexander Graf
2016-01-15 13:02       ` Leif Lindholm
2016-01-15 14:14         ` Alexander Graf
2016-01-15 14:21           ` Leif Lindholm
2016-01-15 17:04             ` Alexander Graf
2016-01-15  3:40     ` Alexander Graf
2015-12-22 13:57 ` [U-Boot] [PATCH 5/9] efi_loader: Add console interface Alexander Graf
2015-12-22 13:57 ` [U-Boot] [PATCH 6/9] efi_loader: Add runtime services Alexander Graf
2015-12-26 18:33   ` Leif Lindholm
2016-01-15  0:26     ` Alexander Graf
2016-01-15 13:52       ` Leif Lindholm
2016-01-15 14:15         ` Alexander Graf
2016-01-15 14:22           ` Leif Lindholm
2015-12-22 13:57 ` [U-Boot] [PATCH 7/9] efi_loader: Add disk interfaces Alexander Graf
2016-01-15  1:37   ` Simon Glass
2016-01-15  2:40     ` Alexander Graf
2015-12-22 13:57 ` [U-Boot] [PATCH 8/9] efi_loader: Add "bootefi" command Alexander Graf
2015-12-24 11:15   ` Matwey V. Kornilov
2015-12-25  9:02     ` Alexander Graf
2015-12-25  9:25       ` Andreas Färber
2015-12-25  9:40         ` Matwey V. Kornilov
2015-12-25 17:04           ` Tom Rini
2015-12-26 18:55         ` Leif Lindholm
2015-12-27 15:33           ` Alexander Graf
2015-12-26 18:45       ` Leif Lindholm
2015-12-25 16:58     ` Tom Rini
2015-12-22 13:57 ` [U-Boot] [PATCH 9/9] efi_loader: hook up in build environment Alexander Graf
2015-12-22 18:28 ` [U-Boot] [PATCH 0/9] EFI payload / application support Matwey V. Kornilov
2015-12-22 20:32   ` Alexander Graf
2015-12-25  3:29 ` Tom Rini
2015-12-25  8:53   ` Alexander Graf
2015-12-25 16:50     ` Tom Rini
2015-12-25 16:53       ` Matwey V. Kornilov
2015-12-25 17:00         ` Tom Rini
2016-01-15  3:00       ` Alexander Graf
2016-01-15  3:06         ` Tom Rini
2015-12-25 19:34 ` Blibbet
2015-12-26 15:31 ` Leif Lindholm
2015-12-26 16:27   ` Alexander Graf
2015-12-26 19:34     ` Leif Lindholm
2016-01-04 16:25       ` Alexander Graf
2016-01-04 16:56         ` Tom Rini
2016-01-04 18:03           ` Andreas Färber
2016-01-04 18:41             ` Andreas Färber
2016-01-04 19:54               ` Tom Rini
2016-01-04 22:37                 ` Dennis Gilmore
2016-01-04 22:48                   ` Alexander Graf
2016-01-15  3:40             ` Peter Robinson
2016-01-04 20:11           ` Matwey V. Kornilov
2016-01-15  3:32           ` Peter Robinson
2015-12-27 18:10   ` Tom Rini
2015-12-27 18:39     ` Leif Lindholm
2015-12-27 19:48       ` Tom Rini
2016-01-05 20:18       ` Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5698332A.4040800@suse.de \
    --to=agraf@suse.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.