summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2010-05-27 08:26:50 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2010-05-27 08:26:50 +0000
commit9a0d4427b66de9308d6ba4a41bdddcabc00c9379 (patch)
tree37e92b2fa05474f9e86772cbc7ffa99581f4034e
parent55fa386c8c91d3f9aa43d31f1eebcb8cb25cf2ae (diff)
Synchronize caches after modifying the data words in the PLT stub to prevent
instructions in the same cache line from being corrupted. ok deraadt@, miod@
-rw-r--r--libexec/ld.so/hppa/rtld_machine.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/libexec/ld.so/hppa/rtld_machine.c b/libexec/ld.so/hppa/rtld_machine.c
index c54b0d28d61..d7a493bca65 100644
--- a/libexec/ld.so/hppa/rtld_machine.c
+++ b/libexec/ld.so/hppa/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.19 2010/05/02 12:03:24 kettenis Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.20 2010/05/27 08:26:49 kettenis Exp $ */
/*
* Copyright (c) 2004 Michael Shalayeff
@@ -380,6 +380,18 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
got[1] = (Elf_Addr)object;
got[-2] = (Elf_Addr)&_dl_bind_start;
got[-1] = ltp;
+ /*
+ * Even though we didn't modify any instructions it
+ * seems we still need to syncronize the caches.
+ * There may be instructions in the same cache line
+ * and they end up being corrupted otherwise.
+ */
+ __asm __volatile("fdc 0(%0)" :: "r" (&got[-2]));
+ __asm __volatile("fdc 0(%0)" :: "r" (&got[-1]));
+ __asm __volatile("sync");
+ __asm __volatile("fic 0(%0)" :: "r" (&got[-2]));
+ __asm __volatile("fic 0(%0)" :: "r" (&got[-1]));
+ __asm __volatile("sync");
for (i = 0; i < numrela; i++, rela++) {
Elf_Addr *r_addr = (Elf_Addr *)(ooff + rela->r_offset);