summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.so/m88k/rtld_machine.c54
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.