diff options
author | David Smith <dsmith@redhat.com> | 2008-06-23 12:41:45 -0500 |
---|---|---|
committer | David Smith <dsmith@redhat.com> | 2008-06-23 12:43:23 -0500 |
commit | a21d81ec8b00571cb5987fe04ce74a3fe873351c (patch) | |
tree | d38eae80a5cfaf3cb5bdf0a8da6cbe0b8b98cd88 /runtime/syscall.h | |
parent | b857a3649c0f8e4e2d8a7209424f23c5d55adac7 (diff) | |
download | systemtap-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.h | 132 |
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 ®s->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 ®s->bx + n; +#elif defined(CONFIG_X86_64) +#ifdef CONFIG_IA32_EMULATION + if (test_tsk_thread_flag(task, TIF_IA32)) + switch (n) { + case 0: return ®s->bx; + case 1: return ®s->cx; + case 2: return ®s->dx; + case 3: return ®s->si; + case 4: return ®s->di; + case 5: return ®s->bp; + default: + _stp_error("syscall arg > 5"); + return NULL; + } +#endif /* CONFIG_IA32_EMULATION */ + switch (n) { + case 0: return ®s->di; + case 1: return ®s->si; + case 2: return ®s->dx; + case 3: return ®s->r10; + case 4: return ®s->r8; + case 5: return ®s->r9; + default: + _stp_error("syscall arg > 5"); + return NULL; + } +#endif /* CONFIG_X86_32 */ +} +#endif + +#endif /* _SYSCALL_H_ */ |