diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2012-12-07 07:02:39 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2012-12-07 07:02:39 +0000 |
commit | 5bdf25a9c88254f5640d9463486c7c9bad8652d8 (patch) | |
tree | 47db7818f6ec0bfed2696ae433b16bb7501505de /sys/boot/i386/efi | |
parent | 59b6b1dc68694b70ded1201a7781b360d23da79c (diff) | |
download | FreeBSD-src-5bdf25a9c88254f5640d9463486c7c9bad8652d8.zip FreeBSD-src-5bdf25a9c88254f5640d9463486c7c9bad8652d8.tar.gz |
Make this work for 64 bit binaries.
Diffstat (limited to 'sys/boot/i386/efi')
-rw-r--r-- | sys/boot/i386/efi/reloc.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/sys/boot/i386/efi/reloc.c b/sys/boot/i386/efi/reloc.c index 96f9241..22c6642 100644 --- a/sys/boot/i386/efi/reloc.c +++ b/sys/boot/i386/efi/reloc.c @@ -28,21 +28,31 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> -#include <sys/elf32.h> +#include <elf.h> #include <efi.h> #include <bootstrap.h> +#ifdef __i386__ +#define ElfW_Rel Elf32_Rel +#define ElfW_Dyn Elf32_Dyn +#define ELFW_R_TYPE ELF32_R_TYPE +#elif __amd64__ +#define ElfW_Rel Elf64_Rel +#define ElfW_Dyn Elf64_Dyn +#define ELFW_R_TYPE ELF64_R_TYPE +#endif + /* - * A simple relocator for IA32 EFI binaries. + * A simple relocator for IA32/AMD64 EFI binaries. */ EFI_STATUS -_reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle, +_reloc(unsigned long ImageBase, ElfW_Dyn *dynamic, EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) { unsigned long relsz, relent; unsigned long *newaddr; - Elf32_Rel *rel; - Elf32_Dyn *dynp; + ElfW_Rel *rel; + ElfW_Dyn *dynp; /* * Find the relocation address, its size and the relocation entry. @@ -51,14 +61,17 @@ _reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle, relent = 0; for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) { switch (dynp->d_tag) { + case DT_RELA: case DT_REL: - rel = (Elf32_Rel *) ((unsigned long) dynp->d_un.d_ptr + + rel = (ElfW_Rel *) ((unsigned long) dynp->d_un.d_ptr + ImageBase); break; case DT_RELSZ: + case DT_RELASZ: relsz = dynp->d_un.d_val; break; case DT_RELENT: + case DT_RELAENT: relent = dynp->d_un.d_val; break; default: @@ -74,7 +87,7 @@ _reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle, CTASSERT(R_386_NONE == R_X86_64_NONE); CTASSERT(R_386_RELATIVE == R_X86_64_RELATIVE); for (; relsz > 0; relsz -= relent) { - switch (ELF32_R_TYPE(rel->r_info)) { + switch (ELFW_R_TYPE(rel->r_info)) { case R_386_NONE: /* No relocation needs be performed. */ break; @@ -85,9 +98,9 @@ _reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle, break; default: /* XXX: do we need other relocations ? */ - return (EFI_LOAD_ERROR); + break; } - rel = (Elf32_Rel *) ((caddr_t) rel + relent); + rel = (ElfW_Rel *) ((caddr_t) rel + relent); } return (EFI_SUCCESS); |