summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.elf_so/arch/mips/mips_reloc.c77
1 files changed, 47 insertions, 30 deletions
diff --git a/libexec/ld.elf_so/arch/mips/mips_reloc.c b/libexec/ld.elf_so/arch/mips/mips_reloc.c
index cdddf69c75c..fb6d4c31c27 100644
--- a/libexec/ld.elf_so/arch/mips/mips_reloc.c
+++ b/libexec/ld.elf_so/arch/mips/mips_reloc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mips_reloc.c,v 1.44 2003/09/24 10:25:26 mycroft Exp $ */
+/* $NetBSD: mips_reloc.c,v 1.45 2003/11/19 19:41:57 simonb Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
@@ -43,6 +43,31 @@ void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
caddr_t _rtld_bind(Elf_Word, Elf_Addr, Elf_Addr, Elf_Addr);
+/*
+ * It is possible for the compiler to emit relocations for unaligned data.
+ * We handle this situation with these inlines.
+ */
+#define RELOC_ALIGNED_P(x) \
+ (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
+
+static __inline Elf_Addr
+load_ptr(void *where)
+{
+ Elf_Addr res;
+
+ memcpy(&res, where, sizeof(res));
+
+ return res;
+}
+
+static __inline void
+store_ptr(void *where, Elf_Addr val)
+{
+
+ memcpy(where, &val, sizeof(val));
+}
+
+
void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
@@ -114,7 +139,11 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
sym = symtab + ELF_R_SYM(rel->r_info);
assert(sym->st_info ==
ELF_ST_INFO(STB_LOCAL, STT_SECTION));
- *where += (Elf_Addr)(sym->st_value + relocbase);
+ if (__predict_true(RELOC_ALIGNED_P(where)))
+ *where += (Elf_Addr)(sym->st_value + relocbase);
+ else
+ store_ptr(where, load_ptr(where) +
+ (Elf_Addr)(sym->st_value + relocbase));
break;
default:
@@ -123,30 +152,6 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
}
}
-/*
- * It is possible for the compiler to emit relocations for unaligned data.
- * We handle this situation with these inlines.
- */
-#define RELOC_ALIGNED_P(x) \
- (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
-
-static __inline Elf_Addr
-load_ptr(void *where)
-{
- Elf_Addr res;
-
- memcpy(&res, where, sizeof(res));
-
- return (res);
-}
-
-static __inline void
-store_ptr(void *where, Elf_Addr val)
-{
-
- memcpy(where, &val, sizeof(val));
-}
-
int
_rtld_relocate_nonplt_objects(const Obj_Entry *obj)
{
@@ -252,9 +257,15 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj)
def = obj->symtab + symnum;
if (symnum >= obj->gotsym) {
- tmp = *where;
+ if (__predict_true(RELOC_ALIGNED_P(where)))
+ tmp = *where;
+ else
+ tmp = load_ptr(where);
tmp += got[obj->local_gotno + symnum - obj->gotsym];
- *where = tmp;
+ if (__predict_true(RELOC_ALIGNED_P(where)))
+ *where = tmp;
+ else
+ store_ptr(where, tmp);
rdbg(("REL32/G %s in %s --> %p in %s",
obj->strtab + def->st_name, obj->path,
@@ -276,7 +287,10 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj)
*
* --rkb, Oct 6, 2001
*/
- tmp = *where;
+ if (__predict_true(RELOC_ALIGNED_P(where)))
+ tmp = *where;
+ else
+ tmp = load_ptr(where);
if (def->st_info ==
ELF_ST_INFO(STB_LOCAL, STT_SECTION)
@@ -287,7 +301,10 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj)
tmp += (Elf_Addr)def->st_value;
tmp += (Elf_Addr)obj->relocbase;
- *where = tmp;
+ if (__predict_true(RELOC_ALIGNED_P(where)))
+ *where = tmp;
+ else
+ store_ptr(where, tmp);
rdbg(("REL32/L %s in %s --> %p in %s",
obj->strtab + def->st_name, obj->path,