summaryrefslogtreecommitdiff
path: root/libexec/ld.so/sparc/rtld_machine.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/ld.so/sparc/rtld_machine.c')
-rw-r--r--libexec/ld.so/sparc/rtld_machine.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/libexec/ld.so/sparc/rtld_machine.c b/libexec/ld.so/sparc/rtld_machine.c
index 73ccd4ffc3b..48c16f7fe98 100644
--- a/libexec/ld.so/sparc/rtld_machine.c
+++ b/libexec/ld.so/sparc/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.10 2002/11/23 19:14:25 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.11 2002/12/18 19:20:02 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -44,6 +44,7 @@
#include <nlist.h>
#include <link.h>
+#include <signal.h>
#include "syscall.h"
#include "archdep.h"
@@ -335,6 +336,7 @@ _dl_bind(elf_object_t *object, Elf_Word reloff)
const char *symn;
Elf_Addr value;
Elf_RelA *rela;
+ sigset_t omask, nmask;
rela = (Elf_RelA *)(object->Dyn.info[DT_JMPREL] + reloff);
@@ -353,8 +355,33 @@ _dl_bind(elf_object_t *object, Elf_Word reloff)
value = ooff + this->st_value;
+ /* if PLT is protected, allow the write */
+ if (object->plt_addr != NULL && object->plt_size != 0) {
+ sigfillset(&nmask);
+ _dl_sigprocmask(SIG_BLOCK, &nmask, &omask);
+#if 0
+ _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+#else
+ _dl_mprotect((void*)addr,sizeof (Elf_Addr) * 3,
+ PROT_READ|PROT_WRITE|PROT_EXEC);
+#endif
+ }
+
_dl_reloc_plt(addr, value);
+ /* if PLT is (to be protected, change back to RO/X */
+ if (object->plt_addr != NULL && object->plt_size != 0) {
+#if 0
+ _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ PROT_READ|PROT_EXEC);
+#else
+ _dl_mprotect((void*)addr,sizeof (Elf_Addr) * 3,
+ PROT_READ|PROT_EXEC);
+#endif
+ _dl_sigprocmask(SIG_SETMASK, &omask, NULL);
+ }
+
return (value);
}
@@ -363,6 +390,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
{
Elf_Addr *pltgot;
extern void _dl_bind_start(void); /* XXX */
+ Elf_Addr ooff;
+ const Elf_Sym *this;
pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT];
@@ -393,11 +422,45 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
__asm __volatile("nop;nop;nop;nop;nop");
}
+ this = NULL;
+ ooff = _dl_find_symbol("__got_start", object, &this,
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
+ NULL);
+ if (this != NULL)
+ object->got_addr = ooff + this->st_value;
+
+ this = NULL;
+ ooff = _dl_find_symbol("__got_end", object, &this,
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
+ NULL);
+ if (this != NULL)
+ object->got_size = ooff + this->st_value - object->got_addr;
+
+ this = NULL;
+ ooff = _dl_find_symbol("__plt_start", object, &this,
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
+ NULL);
+ if (this != NULL)
+ object->plt_addr = ooff + this->st_value;
+
+ this = NULL;
+ ooff = _dl_find_symbol("__plt_end", object, &this,
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
+ NULL);
+ if (this != NULL)
+ object->plt_size = ooff + this->st_value - object->plt_addr;
+
if (object->obj_type == OBJTYPE_LDR || !lazy || pltgot == NULL) {
_dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
return;
}
+ if (object->got_addr != NULL && object->got_size != 0)
+ _dl_mprotect((void*)object->got_addr, object->got_size,
+ PROT_READ);
+ if (object->plt_addr != NULL && object->plt_size != 0)
+ _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ PROT_READ|PROT_EXEC);
}