diff options
author | Simon Glass <sjg@chromium.org> | 2016-11-07 15:47:10 (GMT) |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2016-11-14 22:24:04 (GMT) |
commit | dd46eef2f6e0b7dce2e6bcd85ed8caca5a6b606c (patch) | |
tree | 74f90abb47c2797ccbe52d642f6d6e3795251b67 /arch/arm/lib/reloc_arm_efi.c | |
parent | c70f74a081c2005b0a4749cf8762fc14b7369ddb (diff) | |
download | u-boot-dd46eef2f6e0b7dce2e6bcd85ed8caca5a6b606c.tar.xz |
efi: arm: Add EFI app support
Add support for EFI apps on ARM. This includes start-up and relocation
code, plus a link script and some compiler setting changes.
Signed-off-by: Simon Glass <sjg@chromium.org>
[agraf: Remove whitespace change, add kconfig dep]
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/arm/lib/reloc_arm_efi.c')
-rw-r--r-- | arch/arm/lib/reloc_arm_efi.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/arm/lib/reloc_arm_efi.c b/arch/arm/lib/reloc_arm_efi.c new file mode 100644 index 0000000..d2f96ee --- /dev/null +++ b/arch/arm/lib/reloc_arm_efi.c @@ -0,0 +1,66 @@ +/* + * reloc_arm.c - position-independent ARM ELF shared object relocator + * + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org> + * Copyright (C) 1999 Hewlett-Packard Co. + * Contributed by David Mosberger <davidm@hpl.hp.com>. + * + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * This file is taken and modified from the gnu-efi project. + */ + +#include <efi.h> +#include <elf.h> + +efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image, + struct efi_system_table *systab) +{ + long relsz = 0, relent = 0; + Elf32_Rel *rel = 0; + ulong *addr; + int i; + + for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { + switch (dyn[i].d_tag) { + case DT_REL: + rel = (Elf32_Rel *)((ulong)dyn[i].d_un.d_ptr + + ldbase); + break; + case DT_RELSZ: + relsz = dyn[i].d_un.d_val; + break; + case DT_RELENT: + relent = dyn[i].d_un.d_val; + break; + default: + break; + } + } + + if (!rel && relent == 0) + return EFI_SUCCESS; + + if (!rel || relent == 0) + return EFI_LOAD_ERROR; + + while (relsz > 0) { + /* apply the relocs */ + switch (ELF32_R_TYPE(rel->r_info)) { + case R_ARM_NONE: + break; + case R_ARM_RELATIVE: + addr = (ulong *)(ldbase + rel->r_offset); + *addr += ldbase; + break; + default: + break; + } + rel = (Elf32_Rel *)((char *)rel + relent); + relsz -= relent; + } + + return EFI_SUCCESS; +} |