summaryrefslogtreecommitdiff
path: root/libexec/ld.so/mips64
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/ld.so/mips64')
-rw-r--r--libexec/ld.so/mips64/rtld_machine.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/libexec/ld.so/mips64/rtld_machine.c b/libexec/ld.so/mips64/rtld_machine.c
index 5acd2e8b4cb..905fe5ecf30 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.14 2010/09/11 11:13:20 kettenis Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.15 2013/05/08 20:55:14 guenther Exp $ */
/*
* Copyright (c) 1998-2004 Opsycon AB, Sweden.
@@ -50,6 +50,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
Elf64_Addr got_start, got_end;
Elf64_Rel *relocs;
const Elf64_Sym *sym, *this;
+ Elf64_Addr prev_value = 0;
+ const Elf64_Sym *prev_sym = NULL;
loff = object->obj_base;
numrel = object->Dyn.info[relsz] / sizeof(Elf64_Rel);
@@ -102,17 +104,23 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
type = ELF64_R_TYPE(relocs->r_info);
this = NULL;
- if (ELF64_R_SYM(relocs->r_info) &&
- !(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
- ELF64_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
- ooff = _dl_find_symbol(symn, &this,
- SYM_SEARCH_ALL | SYM_WARNNOTFOUND | SYM_PLT,
- sym, object, NULL);
-
- if (this == NULL) {
- if (ELF_ST_BIND(sym->st_info) != STB_WEAK)
- fails++;
- continue;
+ if (ELF64_R_SYM(relocs->r_info)) {
+ if (sym == prev_sym)
+ this = sym; /* XXX non-NULL */
+ else if (!(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
+ ELF64_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
+ ooff = _dl_find_symbol(symn, &this,
+ SYM_SEARCH_ALL | SYM_WARNNOTFOUND | SYM_PLT,
+ sym, object, NULL);
+
+ if (this == NULL) {
+ if (ELF_ST_BIND(sym->st_info) !=
+ STB_WEAK)
+ fails++;
+ continue;
+ }
+ prev_sym = sym;
+ prev_value = this->st_value + ooff;
}
}
@@ -134,10 +142,10 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
}
} else if (this && ((long)r_addr & 7)) {
_dl_bcopy((char *)r_addr, &robj, sizeof(robj));
- robj += this->st_value + ooff;
+ robj += prev_value;
_dl_bcopy(&robj, (char *)r_addr, sizeof(robj));
} else if (this) {
- *(u_int64_t *)r_addr += this->st_value + ooff;
+ *(u_int64_t *)r_addr += prev_value;
}
break;