summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libexec/ld.so/alpha/rtld_machine.c36
-rw-r--r--libexec/ld.so/i386/rtld_machine.c36
-rw-r--r--libexec/ld.so/powerpc/rtld_machine.c52
-rw-r--r--libexec/ld.so/resolve.h8
-rw-r--r--libexec/ld.so/sparc/rtld_machine.c36
-rw-r--r--libexec/ld.so/sparc64/rtld_machine.c40
6 files changed, 146 insertions, 62 deletions
diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c
index e9c67279577..41eeb010bdb 100644
--- a/libexec/ld.so/alpha/rtld_machine.c
+++ b/libexec/ld.so/alpha/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.20 2003/01/17 20:41:07 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.21 2003/02/15 22:39:13 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -208,7 +208,7 @@ _dl_bind(elf_object_t *object, Elf_Word reloff)
*((int *)0) = 0; /* XXX */
}
/* if PLT is protected, allow the write */
- if (object->plt_addr != NULL && object->plt_size != 0) {
+ if (object->plt_size != 0) {
sigfillset(&nmask);
_dl_sigprocmask(SIG_BLOCK, &nmask, &omask);
_dl_mprotect(addr, sizeof(Elf_Addr),
@@ -218,7 +218,7 @@ _dl_bind(elf_object_t *object, Elf_Word reloff)
*addr = ooff + this->st_value + rela->r_addend;
/* if PLT is (to be protected, change back to RO/X */
- if (object->plt_addr != NULL && object->plt_size != 0) {
+ if (object->plt_size != 0) {
_dl_mprotect(addr, sizeof(Elf_Addr),
PROT_READ|PROT_EXEC);
_dl_sigprocmask(SIG_SETMASK, &omask, NULL);
@@ -236,11 +236,14 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
Elf_Addr *pltgot;
extern void _dl_bind_start(void); /* XXX */
Elf_Addr ooff;
+ Elf_Addr plt_addr;
const Elf_Sym *this;
pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT];
+ object->got_addr = NULL;
+ object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
@@ -255,19 +258,38 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
+ plt_addr = NULL;
+ object->plt_size = 0;
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;
+ 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;
+ object->plt_size = ooff + this->st_value - plt_addr;
+
+ if (object->got_addr == NULL)
+ object->got_start = NULL;
+ else {
+ object->got_start = ELF_TRUNC(object->got_addr, _dl_pagesz);
+ object->got_size += object->got_addr - object->got_start;
+ object->got_size = ELF_ROUND(object->got_size, _dl_pagesz);
+ }
+ if (plt_addr == NULL)
+ object->plt_start = NULL;
+ else {
+ object->plt_start = ELF_TRUNC(plt_addr, _dl_pagesz);
+ object->plt_size += plt_addr - object->plt_start;
+ object->plt_size = ELF_ROUND(object->plt_size, _dl_pagesz);
+ }
+
+
if (object->obj_type == OBJTYPE_LDR || !lazy || pltgot == NULL) {
_dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
@@ -293,8 +315,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
if (object->got_addr != NULL && object->got_size != 0)
_dl_mprotect((void*)object->got_addr, object->got_size,
PROT_READ|PROT_EXEC);
- if (object->plt_addr != NULL && object->got_size != 0)
- _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ if (object->got_size != 0)
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_EXEC);
}
diff --git a/libexec/ld.so/i386/rtld_machine.c b/libexec/ld.so/i386/rtld_machine.c
index 750bb2f4c1b..241e47faccc 100644
--- a/libexec/ld.so/i386/rtld_machine.c
+++ b/libexec/ld.so/i386/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.7 2003/02/02 16:57:58 deraadt Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.8 2003/02/15 22:39:13 drahn Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -380,18 +380,18 @@ _dl_bind(elf_object_t *object, int index)
}
/* if GOT is protected, allow the write */
- if (object->got_addr != NULL && object->got_size != 0) {
+ if (object->got_size != 0) {
sigfillset(&nmask);
_dl_sigprocmask(SIG_BLOCK, &nmask, &omask);
- _dl_mprotect((void*)object->got_addr, object->got_size,
+ _dl_mprotect((void*)object->got_start, object->got_size,
PROT_READ|PROT_WRITE);
}
_dl_reloc_plt(addr, ooff + this->st_value);
/* put the GOT back to RO */
- if (object->got_addr != NULL && object->got_size != 0) {
- _dl_mprotect((void*)object->got_addr, object->got_size,
+ if (object->got_size != 0) {
+ _dl_mprotect((void*)object->got_start, object->got_size,
PROT_READ);
_dl_sigprocmask(SIG_SETMASK, &omask, NULL);
}
@@ -419,6 +419,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
if (object->Dyn.info[DT_PLTREL] != DT_REL)
return;
+ object->got_addr = NULL;
+ object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
@@ -433,19 +435,13 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
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->got_addr == NULL)
+ object->got_start = NULL;
+ else {
+ object->got_start = ELF_TRUNC(object->got_addr, _dl_pagesz);
+ object->got_size += object->got_addr - object->got_start;
+ object->got_size = ELF_ROUND(object->got_size, _dl_pagesz);
+ }
if (!lazy) {
_dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
@@ -471,7 +467,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
}
/* PLT is already RO on i386, no point in mprotecting it, just GOT */
- if (object->got_addr != NULL && object->got_size != 0)
- _dl_mprotect((void*)object->got_addr, object->got_size,
+ if (object->got_size != 0)
+ _dl_mprotect((void*)object->got_start, object->got_size,
PROT_READ);
}
diff --git a/libexec/ld.so/powerpc/rtld_machine.c b/libexec/ld.so/powerpc/rtld_machine.c
index 8c5b1e89535..2a040336a6d 100644
--- a/libexec/ld.so/powerpc/rtld_machine.c
+++ b/libexec/ld.so/powerpc/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.23 2003/02/15 00:30:16 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.24 2003/02/15 22:39:13 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -448,9 +448,10 @@ _dl_printf(" found other symbol at %x size %d\n",
void
_dl_md_reloc_got(elf_object_t *object, int lazy)
{
- Elf32_Addr *pltresolve;
- Elf32_Addr *first_rela;
- Elf32_Rela *relas;
+ Elf_Addr *pltresolve;
+ Elf_Addr *first_rela;
+ Elf_RelA *relas;
+ Elf_Addr plt_addr;
int numrela;
int i;
int index;
@@ -461,6 +462,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
if (object->Dyn.info[DT_PLTREL] != DT_RELA)
return;
+ object->got_addr = NULL;
+ object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
@@ -475,20 +478,38 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
+ plt_addr = 0;
+ object->plt_size = 0;
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;
+ 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;
-
+ object->plt_size = ooff + this->st_value - plt_addr;
+
+ if (object->got_addr == NULL)
+ object->got_start = NULL;
+ else {
+ object->got_start = ELF_TRUNC(object->got_addr, _dl_pagesz);
+ object->got_size += object->got_addr - object->got_start;
+ object->got_size = ELF_ROUND(object->got_size, _dl_pagesz);
+ }
+ if (plt_addr == NULL)
+ object->plt_start = NULL;
+ else {
+ object->plt_start = ELF_TRUNC(plt_addr, _dl_pagesz);
+ object->plt_size += plt_addr - object->plt_start;
+ object->plt_size = ELF_ROUND(object->plt_size, _dl_pagesz);
+ }
+
+
if (!lazy) {
_dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
return;
@@ -518,13 +539,14 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
_dl_dcbf(&r_addr[0]);
_dl_dcbf(&r_addr[2]);
}
- if (object->got_addr != NULL && object->got_size != 0) {
- _dl_mprotect((void*)object->got_addr, object->got_size,
+ if (object->got_size != 0) {
+
+ _dl_mprotect((void*)object->got_start, object->got_size,
PROT_READ|PROT_EXEC); /* only PPC is PROT_EXE */
_dl_syncicache((void*)object->got_addr, 4);
}
- if (object->plt_addr != NULL && object->plt_size != 0)
- _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ if (object->plt_size != 0)
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_EXEC);
}
@@ -560,10 +582,10 @@ _dl_bind(elf_object_t *object, int reloff)
}
/* if PLT is protected, allow the write */
- if (object->plt_addr != NULL && object->plt_size != 0) {
+ if (object->plt_size != 0) {
sigfillset(&nmask);
_dl_sigprocmask(SIG_BLOCK, &nmask, &omask);
- _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_WRITE|PROT_EXEC);
}
@@ -611,8 +633,8 @@ _dl_bind(elf_object_t *object, int reloff)
}
/* if PLT is (to be protected, change back to RO/X */
- if (object->plt_addr != NULL && object->plt_size != 0) {
- _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ if (object->plt_size != 0) {
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_EXEC); /* only PPC is PROT_EXE */
_dl_sigprocmask(SIG_SETMASK, &omask, NULL);
}
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index 752e721363d..f67290f00e9 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.h,v 1.21 2003/02/02 16:57:58 deraadt Exp $ */
+/* $OpenBSD: resolve.h,v 1.22 2003/02/15 22:39:13 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -62,8 +62,9 @@ typedef struct elf_object {
u_int32_t load_size;
Elf_Addr got_addr;
+ Elf_Addr got_start;
size_t got_size;
- Elf_Addr plt_addr;
+ Elf_Addr plt_start;
size_t plt_size;
union {
@@ -198,4 +199,7 @@ extern char *_dl_debug;
#define DL_INVALID_HANDLE 7
#define DL_INVALID_CTL 8
+#define ELF_ROUND(x,malign) (((x) + (malign)-1) & ~((malign)-1))
+#define ELF_TRUNC(x,malign) ((x) & ~((malign)-1))
+
#endif /* _RESOLVE_H_ */
diff --git a/libexec/ld.so/sparc/rtld_machine.c b/libexec/ld.so/sparc/rtld_machine.c
index 96349dba377..cc567f6218b 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.13 2003/02/02 16:57:58 deraadt Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.14 2003/02/15 22:39:13 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -356,7 +356,7 @@ _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) {
+ if (object->plt_size != 0) {
sigfillset(&nmask);
_dl_sigprocmask(SIG_BLOCK, &nmask, &omask);
/* mprotect the actual modified region, not the whole plt */
@@ -367,7 +367,7 @@ _dl_bind(elf_object_t *object, Elf_Word reloff)
_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 (object->plt_size != 0) {
/* mprotect the actual modified region, not the whole plt */
_dl_mprotect((void*)addr,sizeof (Elf_Addr) * 3,
PROT_READ|PROT_EXEC);
@@ -384,6 +384,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
extern void _dl_bind_start(void); /* XXX */
Elf_Addr ooff;
const Elf_Sym *this;
+ Elf_Addr plt_addr;
pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT];
@@ -414,6 +415,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
__asm __volatile("nop;nop;nop;nop;nop");
}
+ object->got_addr = NULL;
+ object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
@@ -428,30 +431,47 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
+ plt_addr = 0;
+ object->plt_size = 0;
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;
+ 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;
+ object->plt_size = ooff + this->st_value - plt_addr;
+
+ if (object->got_addr == NULL)
+ object->got_start = NULL;
+ else {
+ object->got_start = ELF_TRUNC(object->got_addr, _dl_pagesz);
+ object->got_size += object->got_addr - object->got_start;
+ object->got_size = ELF_ROUND(object->got_size, _dl_pagesz);
+ }
+ if (plt_addr == NULL)
+ object->plt_start = NULL;
+ else {
+ object->plt_start = ELF_TRUNC(plt_addr, _dl_pagesz);
+ object->plt_size += plt_addr - object->plt_start;
+ object->plt_size = ELF_ROUND(object->plt_size, _dl_pagesz);
+ }
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)
+ if (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,
+ if (object->plt_size != 0)
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_EXEC);
}
diff --git a/libexec/ld.so/sparc64/rtld_machine.c b/libexec/ld.so/sparc64/rtld_machine.c
index cddca12dc09..95c9c339435 100644
--- a/libexec/ld.so/sparc64/rtld_machine.c
+++ b/libexec/ld.so/sparc64/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.24 2003/02/02 16:57:58 deraadt Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.25 2003/02/15 22:39:14 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -644,18 +644,18 @@ _dl_bind(elf_object_t *object, int index)
}
/* if PLT is protected, allow the write */
- if (object->plt_addr != NULL && object->plt_size != 0) {
+ if (object->plt_size != 0) {
sigfillset(&nmask);
_dl_sigprocmask(SIG_BLOCK, &nmask, &omask);
- _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_WRITE|PROT_EXEC);
}
_dl_reloc_plt(addr, ooff + this->st_value, rela);
/* if PLT is (to be protected), change back to RO/X */
- if (object->plt_addr != NULL && object->plt_size != 0) {
- _dl_mprotect((void*)object->plt_addr, object->plt_size,
+ if (object->plt_size != 0) {
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_EXEC);
_dl_sigprocmask(SIG_SETMASK, &omask, NULL);
}
@@ -700,11 +700,14 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
Elf_Addr *pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT];
Elf_Word *entry = (Elf_Word *)pltgot;
Elf_Addr ooff;
+ Elf_Addr plt_addr;
const Elf_Sym *this;
if (object->Dyn.info[DT_PLTREL] != DT_RELA)
return;
+ object->got_addr = NULL;
+ object->got_size = 0;
this = NULL;
ooff = _dl_find_symbol("__got_start", object, &this,
SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, SYM_NOTPLT,
@@ -719,19 +722,36 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
if (this != NULL)
object->got_size = ooff + this->st_value - object->got_addr;
+ plt_addr = 0;
+ object->plt_size = 0;
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;
+ 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;
+ object->plt_size = ooff + this->st_value - plt_addr;
+
+ if (object->got_addr == NULL)
+ object->got_start = NULL;
+ else {
+ object->got_start = ELF_TRUNC(object->got_addr, _dl_pagesz);
+ object->got_size += object->got_addr - object->got_start;
+ object->got_size = ELF_ROUND(object->got_size, _dl_pagesz);
+ }
+ if (plt_addr == NULL)
+ object->plt_start = NULL;
+ else {
+ object->plt_start = ELF_TRUNC(plt_addr, _dl_pagesz);
+ object->plt_size += plt_addr - object->plt_start;
+ object->plt_size = ELF_ROUND(object->plt_size, _dl_pagesz);
+ }
if (!lazy) {
_dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
@@ -743,10 +763,10 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
pltgot[8] = (Elf_Addr)object;
- if (object->got_addr != NULL && object->got_size != 0)
+ if (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,
+ if (object->plt_size != 0)
+ _dl_mprotect((void*)object->plt_start, object->plt_size,
PROT_READ|PROT_EXEC);
}