summaryrefslogtreecommitdiff
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
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.
-rw-r--r--libexec/ld.so/m88k/rtld_machine.c54
-rw-r--r--sys/arch/m88k/include/exec.h10
2 files changed, 44 insertions, 20 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.
diff --git a/sys/arch/m88k/include/exec.h b/sys/arch/m88k/include/exec.h
index f67b9b7372d..a7c6155d68c 100644
--- a/sys/arch/m88k/include/exec.h
+++ b/sys/arch/m88k/include/exec.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec.h,v 1.3 2013/02/09 19:21:29 miod Exp $ */
+/* $OpenBSD: exec.h,v 1.4 2013/04/20 18:40:42 miod Exp $ */
#ifndef _M88K_EXEC_H_
#define _M88K_EXEC_H_
@@ -16,4 +16,12 @@
#define _KERN_DO_AOUT
#define _KERN_DO_ELF
+/* Processor specific dynamic tag values. */
+#define DT_88K_ADDRBASE 0x70000001
+#define DT_88K_PLTSTART 0x70000002
+#define DT_88K_PLTEND 0x70000003
+#define DT_88K_TDESC 0x70000004
+
+#define DT_PROCNUM (DT_88K_TDESC + 1 - DT_LOPROC)
+
#endif /* _M88K_EXEC_H_ */