diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-11-02 07:02:54 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-11-02 07:02:54 +0000 |
commit | 8fd2b4f8529a6ba7b9744585e37a0e7faf3679db (patch) | |
tree | 87045e41eb653c0670dd936535cb59387146d705 /libexec/ld.so/m88k | |
parent | 0c7db7d7d9f79eb542b0a6711364c7e112401184 (diff) |
Factor out the logic for mprotecting the memory between two symbols into
a new MI routine _dl_protect_segment(), and use that for protecting the
GOT and--on some archs--the PLT.
Amazing testing turnaround by miod@, who apparently violated relativity
to get back results on some archs as fast as he did
Diffstat (limited to 'libexec/ld.so/m88k')
-rw-r--r-- | libexec/ld.so/m88k/rtld_machine.c | 54 |
1 files changed, 15 insertions, 39 deletions
diff --git a/libexec/ld.so/m88k/rtld_machine.c b/libexec/ld.so/m88k/rtld_machine.c index 3d87aab0421..6e21fe1e810 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.12 2015/09/01 05:10:43 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.13 2015/11/02 07:02:53 guenther Exp $ */ /* * Copyright (c) 2013 Miodrag Vallat. @@ -276,6 +276,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) Elf_Addr *pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT]; Elf_Addr ooff; Elf_Addr plt_start, plt_end; + size_t plt_size; const Elf_Sym *this; if (pltgot == NULL) @@ -290,28 +291,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) if (object->traced) lazy = 1; - object->got_addr = 0; - object->got_size = 0; - this = NULL; - ooff = _dl_find_symbol("__got_start", &this, - SYM_SEARCH_OBJ | SYM_NOWARNNOTFOUND | SYM_PLT, NULL, object, NULL); - if (this != NULL) - object->got_addr = ooff + this->st_value; - - this = NULL; - ooff = _dl_find_symbol("__got_end", &this, - SYM_SEARCH_OBJ | SYM_NOWARNNOTFOUND | SYM_PLT, NULL, object, NULL); - if (this != NULL) - object->got_size = ooff + this->st_value - object->got_addr; - - if (object->got_addr == 0) - object->got_start = 0; - 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); - } - /* * Post-5.3 binaries use dynamic tags to provide the .plt boundaries. * If the tags are missing, fall back to the special symbol search. @@ -335,25 +314,23 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) if (this != NULL) plt_end = ooff + this->st_value; else - plt_end = 0; + plt_start = 0; /* not enough to go on */ } else { plt_start += object->obj_base; plt_end += object->obj_base; } - if (plt_start == 0) { - object->plt_start = 0; - object->plt_size = 0; - } else { - object->plt_start = ELF_TRUNC(plt_start, _dl_pagesz); - object->plt_size = - ELF_ROUND(plt_end, _dl_pagesz) - object->plt_start; + if (plt_start == 0) + plt_size = 0; + else { + plt_start = ELF_TRUNC(plt_start, _dl_pagesz); + plt_size = ELF_ROUND(plt_end, _dl_pagesz) - plt_start; /* * GOT relocation will require PLT to be writeable. */ if (!lazy || object->obj_base != 0) - _dl_mprotect((void*)object->plt_start, object->plt_size, + _dl_mprotect((void *)plt_start, plt_size, PROT_READ | PROT_WRITE); } @@ -378,18 +355,17 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) } } - if (object->got_size != 0) { - _dl_mprotect((void*)object->got_start, object->got_size, - PROT_READ); - } - if (object->plt_size != 0) { + /* mprotect the GOT */ + _dl_protect_segment(object, 0, "__got_start", "__got_end", PROT_READ); + + if (plt_size != 0) { if (!lazy || object->obj_base != 0) { /* * Force a cache sync on the whole plt here, * otherwise I$ might have stale information. */ - _dl_cacheflush(object->plt_start, object->plt_size); - _dl_mprotect((void*)object->plt_start, object->plt_size, + _dl_cacheflush(plt_start, plt_size); + _dl_mprotect((void *)plt_start, plt_size, PROT_READ | PROT_EXEC); } } |