diff options
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/m88k/rtld_machine.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/libexec/ld.so/m88k/rtld_machine.c b/libexec/ld.so/m88k/rtld_machine.c index a867c3f10d1..f8e70e790f8 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.4 2013/01/26 20:41:39 miod Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.5 2013/04/20 18:40:42 miod Exp $ */ /* * Copyright (c) 2013 Miodrag Vallat. @@ -235,7 +235,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) int fails = 0; Elf_Addr *pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT]; Elf_Addr ooff; - Elf_Addr plt_addr; + Elf_Addr plt_start, plt_end; const Elf_Sym *this; if (pltgot == NULL) @@ -269,26 +269,42 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_size = ELF_ROUND(object->got_size, _dl_pagesz); } - plt_addr = 0; - object->plt_size = 0; - this = NULL; - ooff = _dl_find_symbol("__plt_start", &this, - SYM_SEARCH_OBJ | SYM_NOWARNNOTFOUND | SYM_PLT, NULL, object, NULL); - if (this != NULL) - plt_addr = ooff + this->st_value; + /* + * Post-5.3 binaries use dynamic tags to provide the .plt boundaries. + * If the tags are missing, fall back to the special symbol search. + */ + plt_start = object->Dyn.info[DT_88K_PLTSTART - DT_LOPROC + DT_NUM]; + plt_end = object->Dyn.info[DT_88K_PLTEND - DT_LOPROC + DT_NUM]; + if (plt_start == 0 || plt_end == 0) { + this = NULL; + ooff = _dl_find_symbol("__plt_start", &this, + SYM_SEARCH_OBJ | SYM_NOWARNNOTFOUND | SYM_PLT, NULL, + object, NULL); + if (this != NULL) + plt_start = ooff + this->st_value; + else + plt_start = 0; - this = NULL; - ooff = _dl_find_symbol("__plt_end", &this, - SYM_SEARCH_OBJ | SYM_NOWARNNOTFOUND | SYM_PLT, NULL, object, NULL); - if (this != NULL) - object->plt_size = ooff + this->st_value - plt_addr; + this = NULL; + ooff = _dl_find_symbol("__plt_end", &this, + SYM_SEARCH_OBJ | SYM_NOWARNNOTFOUND | SYM_PLT, NULL, + object, NULL); + if (this != NULL) + plt_end = ooff + this->st_value; + else + plt_end = 0; + } else { + plt_start += object->obj_base; + plt_end += object->obj_base; + } - if (plt_addr == 0) + if (plt_start == 0) { object->plt_start = 0; - 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); + 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; /* * GOT relocation will require PLT to be writeable. |