summaryrefslogtreecommitdiffstats
path: root/runtime/syscall.h
diff options
context:
space:
mode:
authorDavid Smith <dsmith@redhat.com>2008-06-23 12:41:45 -0500
committerDavid Smith <dsmith@redhat.com>2008-06-23 12:43:23 -0500
commita21d81ec8b00571cb5987fe04ce74a3fe873351c (patch)
treed38eae80a5cfaf3cb5bdf0a8da6cbe0b8b98cd88 /runtime/syscall.h
parentb857a3649c0f8e4e2d8a7209424f23c5d55adac7 (diff)
downloadsystemtap-steved-a21d81ec8b00571cb5987fe04ce74a3fe873351c.tar.gz
systemtap-steved-a21d81ec8b00571cb5987fe04ce74a3fe873351c.tar.xz
systemtap-steved-a21d81ec8b00571cb5987fe04ce74a3fe873351c.zip
Major update to memory map change notification code.
2008-06-23 David Smith <dsmith@redhat.com> * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl): Handles UDPF_NONE value. (utrace_derived_probe_group::emit_vm_callback_probe_decl): New function. (utrace_derived_probe_group::emit_module_decls): Calls emit_vm_callback_probe_decl() to set up vm_callbacks. 2008-06-23 David Smith <dsmith@redhat.com> * task_finder.c (__stp_tf_vm_cb): New function. (stap_register_task_finder_target): Sets up syscall entry and syscall exit handlers. (__stp_find_file_based_vma): New function. (__stp_utrace_task_finder_target_syscall_entry): New function. Saves vma information off at syscall entry. (__stp_target_call_vm_callback): New function. (__stp_utrace_task_finder_target_syscall_exit): New function. Handles changes to memory maps based on information saved at syscall entry. * syscall.h: New file containing syscall function. * task_finder_vma.c: New file containing saved vma information handling functions.
Diffstat (limited to 'runtime/syscall.h')
-rw-r--r--runtime/syscall.h132
1 files changed, 132 insertions, 0 deletions
diff --git a/runtime/syscall.h b/runtime/syscall.h
new file mode 100644
index 00000000..3e37b550
--- /dev/null
+++ b/runtime/syscall.h
@@ -0,0 +1,132 @@
+/* syscall defines and inlines
+ * Copyright (C) 2008 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#ifndef _SYSCALL_H_ /* -*- linux-c -*- */
+#define _SYSCALL_H_
+
+#if defined(__i386__) || defined(CONFIG_IA32_EMULATION)
+#define __MMAP_SYSCALL_NO_IA32 192 /* mmap2 */
+#define __MPROTECT_SYSCALL_NO_IA32 125
+#define __MUNMAP_SYSCALL_NO_IA32 91
+#define __MREMAP_SYSCALL_NO_IA32 163
+# if !defined(CONFIG_IA32_EMULATION)
+#define MMAP_SYSCALL_NO(tsk) __MMAP_SYSCALL_NO_IA32
+#define MPROTECT_SYSCALL_NO(tsk) __MPROTECT_SYSCALL_NO_IA32
+#define MUNMAP_SYSCALL_NO(tsk) __MUNMAP_SYSCALL_NO_IA32
+#define MREMAP_SYSCALL_NO(tsk) __MREMAP_SYSCALL_NO_IA32
+# endif
+#endif
+
+#if defined(__x86_64__)
+#define __MMAP_SYSCALL_NO_X86_64 9
+#define __MPROTECT_SYSCALL_NO_X86_64 10
+#define __MUNMAP_SYSCALL_NO_X86_64 11
+#define __MREMAP_SYSCALL_NO_X86_64 25
+# if defined(CONFIG_IA32_EMULATION)
+#define MMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MMAP_SYSCALL_NO_IA32 \
+ : __MMAP_SYSCALL_NO_X86_64)
+#define MPROTECT_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MPROTECT_SYSCALL_NO_IA32 \
+ : __MPROTECT_SYSCALL_NO_X86_64)
+#define MUNMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MUNMAP_SYSCALL_NO_IA32 \
+ : __MUNMAP_SYSCALL_NO_X86_64)
+#define MREMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MREMAP_SYSCALL_NO_IA32 \
+ : __MREMAP_SYSCALL_NO_X86_64)
+# else
+#define MMAP_SYSCALL_NO(tsk) __MMAP_SYSCALL_NO_X86_64
+#define MPROTECT_SYSCALL_NO(tsk) __MPROTECT_SYSCALL_NO_X86_64
+#define MUNMAP_SYSCALL_NO(tsk) __MUNMAP_SYSCALL_NO_X86_64
+#define MREMAP_SYSCALL_NO(tsk) __MREMAP_SYSCALL_NO_X86_64
+# endif
+#endif
+
+#if !defined(MMAP_SYSCALL_NO) || !defined(MPROTECT_SYSCALL_NO) \
+ || !defined(MUNMAP_SYSCALL_NO) || !defined(MREMAP_SYSCALL_NO)
+#error "Unimplemented architecture"
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static inline unsigned long
+__stp_user_syscall_nr(struct pt_regs *regs)
+{
+#if defined(STAPCONF_X86_UNIREGS)
+ return regs->orig_ax;
+#elif defined(__x86_64__)
+ return regs->orig_rax;
+#elif defined (__i386__)
+ return regs->orig_eax;
+#endif
+}
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static inline long *
+__stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+#ifdef CONFIG_IA32_EMULATION
+// This code works, but isn't what we need. Since
+// __stp_user_syscall_arg() doesn't sign-extend, a value passed in as
+// an argument and then returned won't compare correctly anymore. So,
+// for now, disable this code.
+# if 0
+ if (test_tsk_thread_flag(task, TIF_IA32))
+ // Sign-extend the value so (int)-EFOO becomes (long)-EFOO
+ // and will match correctly in comparisons.
+ regs->ax = (long) (int) regs->ax;
+# endif
+#endif
+ return &regs->ax;
+}
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static inline long *
+__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
+ unsigned int n)
+{
+#if defined(CONFIG_X86_32)
+ if (n > 5) {
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+ return &regs->bx + n;
+#elif defined(CONFIG_X86_64)
+#ifdef CONFIG_IA32_EMULATION
+ if (test_tsk_thread_flag(task, TIF_IA32))
+ switch (n) {
+ case 0: return &regs->bx;
+ case 1: return &regs->cx;
+ case 2: return &regs->dx;
+ case 3: return &regs->si;
+ case 4: return &regs->di;
+ case 5: return &regs->bp;
+ default:
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+#endif /* CONFIG_IA32_EMULATION */
+ switch (n) {
+ case 0: return &regs->di;
+ case 1: return &regs->si;
+ case 2: return &regs->dx;
+ case 3: return &regs->r10;
+ case 4: return &regs->r8;
+ case 5: return &regs->r9;
+ default:
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+#endif /* CONFIG_X86_32 */
+}
+#endif
+
+#endif /* _SYSCALL_H_ */