summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorskrll <skrll@NetBSD.org>2012-01-06 10:38:56 +0000
committerskrll <skrll@NetBSD.org>2012-01-06 10:38:56 +0000
commit3ea1875ebab2929fc4eb0608516c28e731d13424 (patch)
treeab5d64fe71b75b6acbe1ab2d0acca3012c7e52f3 /libexec
parentb49e3a12aa9b796da13531aecc5b2e465a7717e6 (diff)
Implement lazy binding on hppa. rump_server needs it!?!?!
Mostly from OpenBSD.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.elf_so/arch/hppa/hppa_reloc.c57
-rw-r--r--libexec/ld.elf_so/arch/hppa/rtld_start.S4
-rw-r--r--libexec/ld.elf_so/reloc.c7
3 files changed, 59 insertions, 9 deletions
diff --git a/libexec/ld.elf_so/arch/hppa/hppa_reloc.c b/libexec/ld.elf_so/arch/hppa/hppa_reloc.c
index ed11cb0c3a0..3c29280abbc 100644
--- a/libexec/ld.elf_so/arch/hppa/hppa_reloc.c
+++ b/libexec/ld.elf_so/arch/hppa/hppa_reloc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hppa_reloc.c,v 1.41 2011/12/04 16:53:08 skrll Exp $ */
+/* $NetBSD: hppa_reloc.c,v 1.42 2012/01/06 10:38:57 skrll Exp $ */
/*-
* Copyright (c) 2002, 2004 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: hppa_reloc.c,v 1.41 2011/12/04 16:53:08 skrll Exp $");
+__RCSID("$NetBSD: hppa_reloc.c,v 1.42 2012/01/06 10:38:57 skrll Exp $");
#endif /* not lint */
#include <stdlib.h>
@@ -82,6 +82,30 @@ store_ptr(void *where, Elf_Addr val)
(void)memcpy(where, &val, sizeof(val));
}
+static __inline void
+fdc(void *addr)
+{
+ __asm volatile("fdc %%r0(%%sr0, %0)" : : "r" (addr));
+}
+
+static __inline void
+fic(void *addr)
+{
+ __asm volatile("fic %%r0(%%sr0,%0)" : : "r" (addr));
+}
+
+static __inline void
+sync(void)
+{
+ __asm volatile("sync" : : : "memory");
+}
+
+#define PLT_STUB_MAGIC1 0x00c0ffee
+#define PLT_STUB_MAGIC2 0xdeadbeef
+
+#define PLT_STUB_INSN1 0x0e801081 /* ldw 0(%r20), %r1 */
+#define PLT_STUB_INSN2 0xe820c000 /* bv %r0(%r1) */
+
/*
* In the runtime architecture (ABI), PLABEL function pointers are
* distinguished from normal function pointers by having the next-least-
@@ -355,7 +379,34 @@ _rtld_function_descriptor_function(const void *addr)
void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
- __rtld_setup_hppa_pltgot(obj, obj->pltgot);
+ Elf_Word *got = obj->pltgot;
+
+ assert(got[-2] == PLT_STUB_MAGIC1);
+ assert(got[-1] == PLT_STUB_MAGIC2);
+
+ __rtld_setup_hppa_pltgot(obj, got);
+
+ fdc(&got[-2]);
+ fdc(&got[-1]);
+ fdc(&got[1]);
+ sync();
+ fic(&got[-2]);
+ fic(&got[-1]);
+ fic(&got[1]);
+ sync();
+
+ /*
+ * libc makes use of %t1 (%r22) to pass errno values to __cerror. Fixup
+ * the PLT stub to not use %r22.
+ */
+ got[-7] = PLT_STUB_INSN1;
+ got[-6] = PLT_STUB_INSN2;
+ fdc(&got[-7]);
+ fdc(&got[-6]);
+ sync();
+ fic(&got[-7]);
+ fic(&got[-6]);
+ sync();
}
int
diff --git a/libexec/ld.elf_so/arch/hppa/rtld_start.S b/libexec/ld.elf_so/arch/hppa/rtld_start.S
index ea61ed93a08..230fc427183 100644
--- a/libexec/ld.elf_so/arch/hppa/rtld_start.S
+++ b/libexec/ld.elf_so/arch/hppa/rtld_start.S
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld_start.S,v 1.11 2011/09/30 03:05:43 mrg Exp $ */
+/* $NetBSD: rtld_start.S,v 1.12 2012/01/06 10:38:57 skrll Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -181,6 +181,7 @@ ENTRY(_rtld_bind_start,HPPA_FRAME_SIZE)
/* 0(%r3) is filled with the saved %r3 above */
stw %ret0, 4(%r3)
stw %ret1, 8(%r3)
+ stw %t1, 12(%r3) /* %r22 */
/*
* The linker PLT stub loads %r20 with (GOT - 8) for the object that
@@ -220,6 +221,7 @@ ENTRY(_rtld_bind_start,HPPA_FRAME_SIZE)
ldw HPPA_FRAME_ARG(3)(%r3), %arg3
ldw 4(%r3), %ret0
ldw 8(%r3), %ret1
+ ldw 12(%r3), %t1 /* %r22 */
/* End stack calling convention. */
ldo HPPA_FRAME_SIZE(%r3), %sp
diff --git a/libexec/ld.elf_so/reloc.c b/libexec/ld.elf_so/reloc.c
index d25c13ef30a..a9ea178aedb 100644
--- a/libexec/ld.elf_so/reloc.c
+++ b/libexec/ld.elf_so/reloc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: reloc.c,v 1.105 2011/12/02 09:06:49 skrll Exp $ */
+/* $NetBSD: reloc.c,v 1.106 2012/01/06 10:38:56 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.105 2011/12/02 09:06:49 skrll Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.106 2012/01/06 10:38:56 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -195,9 +195,6 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now)
dbg(("doing lazy PLT binding"));
if (_rtld_relocate_plt_lazy(obj) < 0)
ok = 0;
-#if defined(__hppa__)
- bind_now = 1;
-#endif
if (obj->z_now || bind_now) {
dbg(("doing immediate PLT binding"));
if (_rtld_relocate_plt_objects(obj) < 0)