summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/boot/sys/boot/common/self_reloc.c20
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: