summaryrefslogtreecommitdiff
path: root/libexec/ld.so/hppa
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2016-06-21 15:21:43 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2016-06-21 15:21:43 +0000
commitf289116dee91e153bf3291145614fa0bda8ee9b1 (patch)
tree7c436300bf12f9ec81b0dd31c001d79600468d29 /libexec/ld.so/hppa
parent2a1bf2629227c7e6e15a6ba668b950482062ccca (diff)
Handle textrels like other architectures do.
ok kettenis guenther
Diffstat (limited to 'libexec/ld.so/hppa')
-rw-r--r--libexec/ld.so/hppa/rtld_machine.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/libexec/ld.so/hppa/rtld_machine.c b/libexec/ld.so/hppa/rtld_machine.c
index 5074534492d..6279a569bd1 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.32 2015/11/02 07:02:53 guenther Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.33 2016/06/21 15:21:42 deraadt Exp $ */
/*
* Copyright (c) 2004 Michael Shalayeff
@@ -107,6 +107,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
Elf_Addr loff;
int i, numrela, fails = 0;
size_t size;
+ struct load_list *llist;
loff = object->obj_base;
numrela = object->Dyn.info[relasz] / sizeof(Elf_RelA);
@@ -147,6 +148,17 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
}
/*
+ * unprotect some segments if we need it.
+ */
+ if ((object->dyn.textrel == 1) && (rel == DT_REL || rel == DT_RELA)) {
+ for (llist = object->load_list; llist != NULL; llist = llist->next) {
+ if (!(llist->prot & PROT_WRITE))
+ _dl_mprotect(llist->start, llist->size,
+ PROT_READ|PROT_WRITE);
+ }
+ }
+
+ /*
* this is normally done by the crt0 code but we have to make
* sure it's set here to allow constructors to call functions
* that are overridden in the user binary (that are un-pic)
@@ -289,6 +301,15 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
}
}
+ /* reprotect the unprotected segments */
+ if ((object->dyn.textrel == 1) && (rel == DT_REL || rel == DT_RELA)) {
+ for (llist = object->load_list; llist != NULL; llist = llist->next) {
+ if (!(llist->prot & PROT_WRITE))
+ _dl_mprotect(llist->start, llist->size,
+ llist->prot);
+ }
+ }
+
return (fails);
}