systemtap ARM port status

Quentin Barnes qbarnes@urbana.css.mot.com
Sat Jun 2 14:11:00 GMT 2007


On Fri, Jun 01, 2007 at 10:29:37PM -0500, Quentin Barnes wrote:
[...]
>So I think all I have to do to properly port the deref() macro
>for ARM is to copy the ARM's __{get|put}_user_asm_{byte|half|word}()
>macros to loc2c-runtime.h, rename them to the _stp_* variety, and
>have them use the "ldrb", "strb", "ldr", and "str" instructions.

Overnight testing revealed that works.  Attached is the ARM version
that seems to do the right thing:


Index: loc2c-runtime.h
===================================================================
--- loc2c-runtime.h	(.../vendor/usr/src/systemtap-20070526/runtime/loc2c-runtime.h)	(revision 206)
+++ loc2c-runtime.h	(.../branches/kprobes/usr/src/systemtap-20070526/runtime/loc2c-runtime.h)	(revision 206)
@@ -112,6 +112,13 @@
 #define fetch_register(regno) ((intptr_t) c->regs->gpr[regno])
 #define store_register(regno) (c->regs->gpr[regno] = (value))
 
+#elif defined (__arm__)
+
+#undef fetch_register
+#undef store_register
+#define fetch_register(regno) ((long) c->regs->uregs[regno])
+#define store_register(regno) (c->regs->uregs[regno] = (value))
+
 #elif defined (__s390__) || defined (__s390x__)
 #undef fetch_register
 #undef store_register
@@ -294,6 +301,141 @@
       goto deref_fault;							      \
   })
 
+#elif defined (__arm__)
+
+#define __stp_get_user_asm_byte(x,addr,err)			\
+	__asm__ __volatile__(					\
+	"1:	ldrb	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	mov	%1, #0\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "+r" (err), "=&r" (x)					\
+	: "r" (addr), "i" (-EFAULT)				\
+	: "cc")
+
+#ifndef __ARMEB__
+#define __stp_get_user_asm_half(x,__gu_addr,err)		\
+({								\
+	unsigned long __b1, __b2;				\
+	__stp_get_user_asm_byte(__b1, __gu_addr, err);		\
+	__stp_get_user_asm_byte(__b2, __gu_addr + 1, err);	\
+	(x) = __b1 | (__b2 << 8);				\
+})
+#else
+#define __stp_get_user_asm_half(x,__gu_addr,err)		\
+({								\
+	unsigned long __b1, __b2;				\
+	__stp_get_user_asm_byte(__b1, __gu_addr, err);		\
+	__stp_get_user_asm_byte(__b2, __gu_addr + 1, err);	\
+	(x) = (__b1 << 8) | __b2;				\
+})
+#endif
+
+#define __stp_get_user_asm_word(x,addr,err)			\
+	__asm__ __volatile__(					\
+	"1:	ldr	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	mov	%1, #0\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "+r" (err), "=&r" (x)					\
+	: "r" (addr), "i" (-EFAULT)				\
+	: "cc")
+
+#define __stp_put_user_asm_byte(x,__pu_addr,err)		\
+	__asm__ __volatile__(					\
+	"1:	strb	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "+r" (err)						\
+	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
+	: "cc")
+
+#ifndef __ARMEB__
+#define __stp_put_user_asm_half(x,__pu_addr,err)			\
+({									\
+	unsigned long __temp = (unsigned long)(x);			\
+	__stp_put_user_asm_byte(__temp, __pu_addr, err);		\
+	__stp_put_user_asm_byte(__temp >> 8, __pu_addr + 1, err);	\
+})
+#else
+#define __stp_put_user_asm_half(x,__pu_addr,err)			\
+({									\
+	unsigned long __temp = (unsigned long)(x);			\
+	__stp_put_user_asm_byte(__temp >> 8, __pu_addr, err);		\
+	__stp_put_user_asm_byte(__temp, __pu_addr + 1, err);		\
+})
+#endif
+
+#define __stp_put_user_asm_word(x,__pu_addr,err)		\
+	__asm__ __volatile__(					\
+	"1:	str	%1,[%2],#0\n"				\
+	"2:\n"							\
+	"	.section .fixup,\"ax\"\n"			\
+	"	.align	2\n"					\
+	"3:	mov	%0, %3\n"				\
+	"	b	2b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.align	3\n"					\
+	"	.long	1b, 3b\n"				\
+	"	.previous"					\
+	: "+r" (err)						\
+	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
+	: "cc")
+
+#define deref(size, addr)						\
+  ({									\
+     int _bad = 0;							\
+     intptr_t _v=0;							\
+	switch (size){							\
+	case 1: __stp_get_user_asm_byte(_v, addr, _bad); break; 	\
+	case 2: __stp_get_user_asm_half(_v, addr, _bad); break; 	\
+	case 4: __stp_get_user_asm_word(_v, addr, _bad); break; 	\
+	default: __get_user_bad(); break;				\
+	}								\
+    if (_bad)  								\
+	goto deref_fault;						\
+     _v;								\
+   })
+
+#define store_deref(size, addr, value)					\
+  ({									\
+    int _bad=0;								\
+	switch (size){							\
+	case 1: __stp_put_user_asm_byte(value, addr, _bad); break;	\
+	case 2: __stp_put_user_asm_half(value, addr, _bad); break;	\
+	case 4: __stp_put_user_asm_word(value, addr, _bad); break;	\
+	case 8: __stp_put_user_asm_dword(value, addr, _bad); break;	\
+	default: __put_user_bad(); break;				\
+	}								\
+    if (_bad)								\
+	   goto deref_fault;						\
+   })
+
 #elif defined (__s390__) || defined (__s390x__)
 
 #ifndef EX_TABLE



More information about the Systemtap mailing list