summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2019-10-05 20:49:48 +0000
committerguenther <guenther@openbsd.org>2019-10-05 20:49:48 +0000
commitd4afc0cdd6611cbc5904e12dde624de5e3d65254 (patch)
treeadb41d5786909dbdbe23136bbd951cdb3e4fac89 /libexec
parentfix build errors of aac(4) (diff)
downloadwireguard-openbsd-d4afc0cdd6611cbc5904e12dde624de5e3d65254.tar.xz
wireguard-openbsd-d4afc0cdd6611cbc5904e12dde624de5e3d65254.zip
Tighten handling of pure relative DIR32 relocations and those referencing
sections; despite being a RELA arch, ld.so was making assumptions about the initialization of the targeted location. Add the relative relocation optimization, handling relocations covered by the DT_RELACOUNT value in a tight loop. ok mpi@ deraadt@
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.so/hppa/rtld_machine.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/libexec/ld.so/hppa/rtld_machine.c b/libexec/ld.so/hppa/rtld_machine.c
index c7be3288356..4bc60aef068 100644
--- a/libexec/ld.so/hppa/rtld_machine.c
+++ b/libexec/ld.so/hppa/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.39 2019/08/06 04:01:42 guenther Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.40 2019/10/05 20:49:48 guenther Exp $ */
/*
* Copyright (c) 2004 Michael Shalayeff
@@ -105,10 +105,12 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
{
Elf_RelA *rela;
Elf_Addr loff;
+ int num_relative;
int i, numrela, fails = 0;
loff = object->obj_base;
numrela = object->Dyn.info[relasz] / sizeof(Elf_RelA);
+ num_relative = rel == DT_RELA ? object->relacount : 0;
rela = (Elf_RelA *)(object->Dyn.info[rel]);
#ifdef DEBUG
@@ -153,7 +155,12 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
if (object->obj_type == OBJTYPE_EXE)
_hppa_dl_set_dp(object->dyn.pltgot);
- for (i = 0; i < numrela; i++, rela++) {
+ /* tight loop for leading relative relocs */
+ for (i = 0; i < num_relative; i++, rela++) {
+ Elf_Addr *where = (Elf_Addr *)(rela->r_offset + loff);
+ *where = rela->r_addend + loff;
+ }
+ for (; i < numrela; i++, rela++) {
struct sym_res sr;
const Elf_Sym *sym;
Elf_Addr *pt;
@@ -199,16 +206,10 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
#endif
} else {
/*
- * XXX should objects ever get their
- * sections loaded nonsequential this
- * would have to get a section number
- * (ELF_R_SYM(rela->r_info))-1 and then:
- * *pt = sect->addr + rela->r_addend;
+ * Either a relative relocation (symbol 0)
+ * or a relocation against a local section
*/
- if (ELF_R_SYM(rela->r_info))
- *pt += loff;
- else
- *pt += loff + rela->r_addend;
+ *pt = loff + sym->st_value + rela->r_addend;
#ifdef DEBUG
DL_DEB(("[%x]DIR32: %s @ 0x%x\n", i,
object->load_name, *pt));