This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[RFC 03/13] mips: Read _stp_deref and _stp_store_deref support
- From: Crestez Dan Leonard <cdleonard at gmail dot com>
- To: systemtap at sourceware dot org
- Date: Thu, 31 Jul 2014 23:21:08 +0300
- Subject: [RFC 03/13] mips: Read _stp_deref and _stp_store_deref support
- Authentication-results: sourceware.org; auth=none
- References: <cover dot 1406837921 dot git dot cdleonard at gmail dot com>
- References: <cover dot 1406837921 dot git dot cdleonard at gmail dot com>
Based on an earlier patch by Victor Kamensky <kamensky@cisco.com>
Signed-off-by: Crestez Dan Leonard <cdleonard@gmail.com>
---
runtime/linux/loc2c-runtime.h | 51 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 49 insertions(+), 2 deletions(-)
diff --git a/runtime/linux/loc2c-runtime.h b/runtime/linux/loc2c-runtime.h
index dd1b002..254eef3 100644
--- a/runtime/linux/loc2c-runtime.h
+++ b/runtime/linux/loc2c-runtime.h
@@ -577,6 +577,39 @@ extern void __store_deref_bad(void);
#elif defined __mips__
+#define __stp_get_user_asm(val, insn, addr, err) \
+{ \
+ __asm__ __volatile__( \
+ "1: " insn " %1, %3 \n" \
+ "2: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "3: li %0, %4 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "__UA_ADDR "\t1b, 3b \n" \
+ " .previous \n" \
+ : "=r" (err), "=r" (val) \
+ : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \
+}
+
+#define __stp_put_user_asm(val, insn, addr, err) \
+{ \
+ __asm__ __volatile__( \
+ "1: " insn " %z2, %3 # __put_user_asm\n" \
+ "2: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "3: li %0, %4 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " " __UA_ADDR " 1b, 3b \n" \
+ " .previous \n" \
+ : "=r" (err) \
+ : "0" (0), "Jr" (val), "o" (__m(addr)), \
+ "i" (-EFAULT)); \
+}
+
#define _stp_deref(size, addr, seg) \
({ \
int _bad = 0; \
@@ -587,7 +620,14 @@ extern void __store_deref_bad(void);
if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
- _bad = 1; \
+ switch (size) \
+ { \
+ case 1: __stp_get_user_asm(_v, "lb", addr, _bad); break; \
+ case 2: __stp_get_user_asm(_v, "lh", addr, _bad); break; \
+ case 4: __stp_get_user_asm(_v, "ld", addr, _bad); break; \
+ case 8: __stp_get_user_asm(_v, "lw", addr, _bad); break; \
+ default: __get_user_unknown(); break; \
+ } \
pagefault_enable(); \
set_fs(_oldfs); \
if (_bad) \
@@ -604,7 +644,14 @@ extern void __store_deref_bad(void);
if (lookup_bad_addr((unsigned long)addr, size)) \
_bad = 1; \
else \
- _bad = 1; \
+ switch (size) \
+ { \
+ case 1: __stp_put_user_asm(value, "sb", addr, _bad); break; \
+ case 2: __stp_put_user_asm(value, "sh", addr, _bad); break; \
+ case 4: __stp_put_user_asm(value, "sw", addr, _bad); break; \
+ case 8: __stp_put_user_asm(value, "sd", addr, _bad); break; \
+ default: __put_user_unknown(); break; \
+ } \
pagefault_enable(); \
set_fs(_oldfs); \
if (_bad) \