summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tapset/ChangeLog7
-rw-r--r--tapset/syscalls.stp33
2 files changed, 39 insertions, 1 deletions
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index a7f8fdf8..f617b331 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,10 @@
+2008-01-23 Masami Hiramatsu <mhiramat@redhat.com>
+
+ PR5554
+ * syscalls.stp (__is_user_regs): Add new function to check whether
+ pt_regs is user mode registers.
+ (syscall.fork): Use __is_user_regs() to decide syscall name.
+
2008-01-16 Eugene Teo <eteo@redhat.com>
* signal.stp (get_sa_flags, get_sa_handler): New functions to
diff --git a/tapset/syscalls.stp b/tapset/syscalls.stp
index 500aff1a..3a239245 100644
--- a/tapset/syscalls.stp
+++ b/tapset/syscalls.stp
@@ -848,6 +848,37 @@ probe syscall.flock.return = kernel.function("sys_flock").return {
retstr = returnstr(1)
}
+function __is_user_regs:long (regs:long) %{ /* pure */
+ struct pt_regs * regs = (void *)((unsigned long)THIS->regs);
+/* copied from asm/ptrace.h */
+#if defined(__i386__)
+#ifdef STAPCONF_X86_UNIREGS
+ int cs = kread(&regs->cs);
+#else
+ int cs = kread(&regs->xcs);
+#endif
+ THIS->__retvalue = ((cs & SEGMENT_RPL_MASK) == USER_RPL);
+#elif defined(__x86_64__)
+ unsigned long cs = kread(&regs->cs);
+ THIS->__retvalue = (!!((cs & 3)));
+#elif defined(__ia64__)
+ unsigned long psr = kread(&regs->cr_ipsr);
+ THIS->__retvalue = (((struct ia64_psr *) &psr)->cpl != 0);
+#elif defined(__powerpc64__)
+ unsigned long msr = kread(&regs->msr);
+ THIS->__retvalue = ((msr >> MSR_PR_LG) & 0x1);
+#elif defined(__arm__)
+ long cpsr = kread(&regs->ARM_cpsr);
+ THIS->__retvalue = ((cpsr & 0xf) == 0);
+#elif defined(__s390__) || defined(__s390x__)
+ unsigned long mask = kread(&regs->psw.mask);
+ THIS->__retvalue = ((mask & PSW_MASK_PSTATE) != 0);
+#else
+#error "Unimplemented architecture"
+#endif
+CATCH_DEREF_FAULT();
+%}
+
# fork _______________________________________________________
# long do_fork(unsigned long clone_flags,
# unsigned long stack_start,
@@ -863,7 +894,7 @@ probe syscall.fork = kernel.function("do_fork") {
parent_tid_uaddr = $parent_tidptr
child_tid_uaddr = $child_tidptr
- if (stack_start == 0) {
+ if (!__is_user_regs(regs)) {
name = "fork_kernel_thread"
argstr = __fork_flags(clone_flags)
} else if (clone_flags == 17)