diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/boot/sys/boot/common/self_reloc.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/usr/src/boot/sys/boot/common/self_reloc.c b/usr/src/boot/sys/boot/common/self_reloc.c index 3b27b17c76..f82006078f 100644 --- a/usr/src/boot/sys/boot/common/self_reloc.c +++ b/usr/src/boot/sys/boot/common/self_reloc.c @@ -25,13 +25,12 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); #include <sys/types.h> #include <elf.h> #include <bootstrap.h> -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(__amd64__) #define ElfW_Rel Elf64_Rela #define ElfW_Dyn Elf64_Dyn #define ELFW_R_TYPE ELF64_R_TYPE @@ -40,10 +39,6 @@ __FBSDID("$FreeBSD$"); #define ElfW_Rel Elf32_Rel #define ElfW_Dyn Elf32_Dyn #define ELFW_R_TYPE ELF32_R_TYPE -#elif defined(__amd64__) -#define ElfW_Rel Elf64_Rel -#define ElfW_Dyn Elf64_Dyn -#define ELFW_R_TYPE ELF64_R_TYPE #else #error architecture not supported #endif @@ -99,7 +94,9 @@ self_reloc(Elf_Addr baseaddr, ElfW_Dyn *dynamic) } /* - * Perform the actual relocation. + * Perform the actual relocation. We rely on the object having been + * linked at 0, so that the difference between the load and link + * address is the same as the load address. */ for (; relsz > 0; relsz -= relent) { switch (ELFW_R_TYPE(rel->r_info)) { @@ -108,12 +105,13 @@ self_reloc(Elf_Addr baseaddr, ElfW_Dyn *dynamic) break; case RELOC_TYPE_RELATIVE: - /* Address relative to the base address. */ newaddr = (Elf_Addr *)(rel->r_offset + baseaddr); - *newaddr += baseaddr; - /* Add the addend when the ABI uses them */ #ifdef ELF_RELA - *newaddr += rel->r_addend; + /* Addend relative to the base address. */ + *newaddr = baseaddr + rel->r_addend; +#else + /* Address relative to the base address. */ + *newaddr += baseaddr; #endif break; default: |