summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-04-20 18:40:43 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-04-20 18:40:43 +0000
commit02f8640c762c0778ef2a2dbb67607bb84ffda2e2 (patch)
tree0b8a212451de42d4aeaaa49409460c978541a4b7 /libexec
parenteb1485abe7e83624207b03c63428d3fa60a58d65 (diff)
Prefer the processor-specific _DYNAMIC[] tags value to find out the boundaries
of the .plt whenever possible, and fallback to the old behaviour of searching for special symbols pointing to its boundaries. No functional change.
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.