summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Fogelstrom <pefo@cvs.openbsd.org>2004-09-30 17:56:19 +0000
committerPer Fogelstrom <pefo@cvs.openbsd.org>2004-09-30 17:56:19 +0000
commiteda9a471b99b628dce0b5a6c72cdaf5531dbe1c8 (patch)
tree567f32b0328338921eb3cfa832c7bc30e374ff4d
parentf655b90ed52c41c320917925d65489e87897ec3a (diff)
handle unaligned in local relocs as well (c++)
-rw-r--r--libexec/ld.so/mips64/rtld_machine.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/libexec/ld.so/mips64/rtld_machine.c b/libexec/ld.so/mips64/rtld_machine.c
index 99d838a9e60..27c2c4fe3d9 100644
--- a/libexec/ld.so/mips64/rtld_machine.c
+++ b/libexec/ld.so/mips64/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.3 2004/09/21 08:40:45 pefo Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.4 2004/09/30 17:56:18 pefo Exp $ */
/*
* Copyright (c) 1998-2004 Opsycon AB, Sweden.
@@ -116,15 +116,22 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
}
switch (ELF64_R_TYPE(relocs->r_info)) {
+ /* XXX Handle non aligned relocs. .eh_frame
+ * XXX in libstdc++ seems to have them... */
+ u_int64_t robj;
+
case R_MIPS_REL32_64:
if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
(ELF64_ST_TYPE(sym->st_info) == STT_SECTION ||
ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
- *(u_int64_t *)r_addr += loff + sym->st_value;
+ if ((long)r_addr & 7) {
+ _dl_bcopy((char *)r_addr, &robj, sizeof(robj));
+ robj += loff + sym->st_value;
+ _dl_bcopy(&robj, (char *)r_addr, sizeof(robj));
+ } else {
+ *(u_int64_t *)r_addr += loff + sym->st_value;
+ }
} else if (this && ((long)r_addr & 7)) {
- /* XXX Handle non aligned relocs. .eh_frame
- * XXX in libstdc++ seems to have them... */
- u_int64_t robj;
_dl_bcopy((char *)r_addr, &robj, sizeof(robj));
robj += this->st_value + ooff;
_dl_bcopy(&robj, (char *)r_addr, sizeof(robj));