summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libexec/ld.so/m88k/rtld_machine.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/libexec/ld.so/m88k/rtld_machine.c b/libexec/ld.so/m88k/rtld_machine.c
index 77f92b04067..e36f70963b5 100644
--- a/libexec/ld.so/m88k/rtld_machine.c
+++ b/libexec/ld.so/m88k/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.16 2016/09/16 02:17:57 guenther Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.17 2016/09/16 02:20:08 guenther Exp $ */
/*
* Copyright (c) 2013 Miodrag Vallat.
@@ -65,6 +65,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
{
int i;
int numrela;
+ int relrela;
int fails = 0;
struct load_list *llist;
Elf32_Addr loff;
@@ -74,6 +75,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
loff = object->obj_base;
numrela = object->Dyn.info[relasz] / sizeof(Elf32_Rela);
+ relrela = rel == DT_RELA ? object->relacount : 0;
+
relas = (Elf32_Rela *)(object->Dyn.info[rel]);
#ifdef DL_PRINTF_DEBUG
@@ -84,6 +87,11 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
if (relas == NULL)
return(0);
+ if (relrela > numrela) {
+ _dl_printf("relacount > numrel: %d > %d\n", relrela, numrela);
+ _dl_exit(20);
+ }
+
/*
* Change protection of all write protected segments in the object
* so we can do relocations such as DISP26. After relocation,
@@ -99,7 +107,14 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
}
}
- for (i = 0; i < numrela; i++, relas++) {
+ /* tight loop for leading RELATIVE relocs */
+ for (i = 0; i < relrela; i++, relas++) {
+ Elf32_Addr *r_addr;
+
+ r_addr = (Elf32_Addr *)(relas->r_offset + loff);
+ *r_addr = relas->r_addend + loff;
+ }
+ for (; i < numrela; i++, relas++) {
Elf32_Addr *r_addr = (Elf32_Addr *)(relas->r_offset + loff);
Elf32_Addr ooff, addend, newval;
const Elf32_Sym *sym, *this;