This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: systemtap ARM port status
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