From 55c0f2bfefb04915622dd3688bba59da1addaec8 Mon Sep 17 00:00:00 2001 From: David Smith Date: Wed, 8 Apr 2009 12:41:55 -0500 Subject: Only includes task_finder.c when needed. 2009-04-08 David Smith * tapsets.cxx (itrace_derived_probe_group::emit_module_decls): Added inclusion of task_finder.c back. Unconditionally including it when not needed causes all systemtap scripts to fail on kernels with no utrace support. (utrace_derived_probe_group::emit_module_decls): Ditto. (uprobe_derived_probe_group::emit_module_decls): Ditto. * runtime/runtime.h: Removed unconditional inclusion of task_finder.c. --- runtime/runtime.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'runtime') diff --git a/runtime/runtime.h b/runtime/runtime.h index 0a656b78..70fe4dce 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -89,8 +89,6 @@ static struct #include "regs.c" #include "regs-ia64.c" -#include "task_finder.c" - #include "sym.c" #ifdef STP_PERFMON #include "perf.c" -- cgit From 117bcbe45ff448c0913007d31cfa2be78caeb4ba Mon Sep 17 00:00:00 2001 From: David Smith Date: Wed, 8 Apr 2009 13:14:24 -0500 Subject: Added '#ifdef STP_NEED_VMA_TRACKER' around code that needs it. 2009-04-08 David Smith * runtime/sym.c: Added '#ifdef STP_NEED_VMA_TRACKER' around code that needs it. --- runtime/sym.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/sym.c b/runtime/sym.c index 835e1b46..7b918428 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -30,6 +30,7 @@ static void _stp_sym_init(void) } } +#ifdef STP_NEED_VMA_TRACKER /* Callback that needs to be registered (in tapsets.cxx for emit_module_init) for every user task path or pid for which we might need symbols or unwind info. */ @@ -76,6 +77,7 @@ static int _stp_tf_munmap_cb(struct stap_task_finder_target *tgt, stap_remove_vma_map_info(tsk->group_leader, addr, addr + length, 0); return 0; } +#endif /* XXX: this needs to be address-space-specific. */ static unsigned long _stp_module_relocate(const char *module, const char *section, unsigned long offset) @@ -128,7 +130,6 @@ static unsigned long _stp_module_relocate(const char *module, const char *sectio return 0; } - /* Return module owner and, if sec != NULL, fills in closest section of the address if found, return NULL otherwise. XXX: needs to be address-space-specific. */ -- cgit From 9b11ea1ccc742f6a594be6a9777e618bdcbfebed Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 8 Apr 2009 19:27:42 +0200 Subject: Fix DEBUG_TASK_FINDER_VMA compilation. * runtime/sym.c (_stp_tf_mmap_cb): We get passed vm_flags, not flags. --- runtime/sym.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/sym.c b/runtime/sym.c index 7b918428..8de01bc8 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -48,7 +48,7 @@ static int _stp_tf_mmap_cb(struct stap_task_finder_target *tgt, #ifdef DEBUG_TASK_FINDER_VMA _stp_dbug(__FUNCTION__, __LINE__, "mmap_cb: tsk %d:%d path %s, addr 0x%08lx, length 0x%08lx, offset 0x%lx, flags 0x%lx\n", - tsk->pid, tsk->tgid, path, addr, length, offset, flags); + tsk->pid, tsk->tgid, path, addr, length, offset, vm_flags); #endif if (path != NULL) { for (i = 0; i < _stp_num_modules; i++) { -- cgit From 8c39e6ee099a479b3f8e25bad1272085369970a9 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 8 Apr 2009 23:35:21 +0200 Subject: Make sure code using the vma tracker compiles again. * runtime/runtime.h: Include task_finder.c. * runtime/sym.c: Always define task_finder callbacks for usage in tapsets. * runtime/task_finder.c: Define dummy stap_task_finder_target when ! defined(CONFIG_UTRACE). * tapsets.cxx: Never include task_finder.c directly. --- runtime/runtime.h | 2 ++ runtime/sym.c | 2 -- runtime/task_finder.c | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'runtime') diff --git a/runtime/runtime.h b/runtime/runtime.h index 70fe4dce..0a656b78 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -89,6 +89,8 @@ static struct #include "regs.c" #include "regs-ia64.c" +#include "task_finder.c" + #include "sym.c" #ifdef STP_PERFMON #include "perf.c" diff --git a/runtime/sym.c b/runtime/sym.c index 8de01bc8..a2cdd0ff 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -30,7 +30,6 @@ static void _stp_sym_init(void) } } -#ifdef STP_NEED_VMA_TRACKER /* Callback that needs to be registered (in tapsets.cxx for emit_module_init) for every user task path or pid for which we might need symbols or unwind info. */ @@ -77,7 +76,6 @@ static int _stp_tf_munmap_cb(struct stap_task_finder_target *tgt, stap_remove_vma_map_info(tsk->group_leader, addr, addr + length, 0); return 0; } -#endif /* XXX: this needs to be address-space-specific. */ static unsigned long _stp_module_relocate(const char *module, const char *section, unsigned long offset) diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 69b6246b..55a896ee 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -2,8 +2,9 @@ #define TASK_FINDER_C #if ! defined(CONFIG_UTRACE) -#error "Need CONFIG_UTRACE!" -#endif +/* Dummy definitions for use in sym.c */ +struct stap_task_finder_target { }; +#else #include @@ -1324,5 +1325,5 @@ stap_stop_task_finder(void) debug_task_finder_report(); } - +#endif /* defined(CONFIG_UTRACE) */ #endif /* TASK_FINDER_C */ -- cgit From 86872ea4cdc4ce7b4546975125fc7be7c7a6e0ec Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 9 Apr 2009 14:22:03 +0200 Subject: Make new stap_task_finder_targets chain on correct list. * runtime/task_finder.c (stap_register_task_finder_target): Also check both pathlen are zero. --- runtime/task_finder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 55a896ee..433a042a 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -179,7 +179,7 @@ stap_register_task_finder_target(struct stap_task_finder_target *new_tgt) && strcmp(tgt->pathname, new_tgt->pathname) == 0) /* pid-based target (a specific pid or all * pids) */ - || (new_tgt->pathlen == 0 + || (new_tgt->pathlen == 0 && tgt->pathlen == 0 && tgt->pid == new_tgt->pid))) { found_node = 1; break; -- cgit From 52356a26e1825acbd9146337ffdbed9b0e173f2b Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 9 Apr 2009 18:20:32 +0200 Subject: Make simple probes work even without KPROBES in the kernel. Without KPROBES very little works atm. But stack.c file is unconditionally imported, while these two functions are only used through context-unwind.stp. This at least lets us do simple sanity checks on "plain" kernels. * runtime/stack.c (_stp_stack_print, _stp_stack_snprint): Wrap in #if defined (CONFIG_KPROBES). --- runtime/stack.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'runtime') diff --git a/runtime/stack.c b/runtime/stack.c index f6b1cd08..68fb9b1f 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -97,6 +97,12 @@ static void _stp_stack_print_fallback(unsigned long stack, int verbose, int leve &print_data); } #endif + +// Without KPROBES very little works atm. +// But this file is unconditionally imported, while these two functions are only +// used through context-unwind.stp. +#if defined (CONFIG_KPROBES) + /** Prints the stack backtrace * @param regs A pointer to the struct pt_regs. */ @@ -141,6 +147,8 @@ static void _stp_stack_snprint(char *str, int size, struct pt_regs *regs, int ve pb->len = 0; } +#endif /* CONFIG_KPROBES */ + /** Prints the user stack backtrace * @param str string * @returns Same string as was input with trace info appended, -- cgit From d5cd287f7860df8752f93de93fcd1cc68884d56b Mon Sep 17 00:00:00 2001 From: David Smith Date: Thu, 9 Apr 2009 12:06:05 -0500 Subject: Uses when available. 2009-04-09 David Smith * buildrun.cxx (compile_pass): Compile autoconf test for . * runtime/autoconf-asm-syscall.c: New "autoconf" test the presence of . * runtime/syscall.h: If exists, use it. Otherwise, use our private copy of the functions for each architecture. (syscall_get_nr): Renamed from __stp_user_syscall_nr(). (syscall_get_return_value): Renamed from __stp_user_syscall_return_value(). (syscall_get_arguments): Renamed from __stp_user_syscall_arg(). * runtime/task_finder.c (__stp_utrace_task_finder_target_syscall_exit): Uses new syscall.h functions. * tapset/utrace.stp: Ditto. --- runtime/autoconf-asm-syscall.c | 2 + runtime/syscall.h | 298 ++++++++++++++++++++++++++--------------- runtime/task_finder.c | 56 ++------ 3 files changed, 207 insertions(+), 149 deletions(-) create mode 100644 runtime/autoconf-asm-syscall.c (limited to 'runtime') diff --git a/runtime/autoconf-asm-syscall.c b/runtime/autoconf-asm-syscall.c new file mode 100644 index 00000000..bf7a273f --- /dev/null +++ b/runtime/autoconf-asm-syscall.c @@ -0,0 +1,2 @@ +#include + diff --git a/runtime/syscall.h b/runtime/syscall.h index ae451070..6d22ba83 100644 --- a/runtime/syscall.h +++ b/runtime/syscall.h @@ -1,5 +1,6 @@ -/* syscall defines and inlines - * Copyright (C) 2008 Red Hat Inc. +/* + * syscall defines and inlines + * Copyright (C) 2008-2009 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 @@ -89,9 +90,17 @@ #error "Unimplemented architecture" #endif +#ifdef STAPCONF_ASM_SYSCALL_H + +/* If the system has asm/syscall.h, use defines from it. */ +#include + +#else /* !STAPCONF_ASM_SYSCALL_H */ + +/* If the system doesn't have asm/syscall.h, use our defines. */ #if defined(__i386__) || defined(__x86_64__) -static inline unsigned long -__stp_user_syscall_nr(struct pt_regs *regs) +static inline long +syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { #if defined(STAPCONF_X86_UNIREGS) return regs->orig_ax; @@ -104,37 +113,37 @@ __stp_user_syscall_nr(struct pt_regs *regs) #endif #if defined(__powerpc__) -static inline unsigned long -__stp_user_syscall_nr(struct pt_regs *regs) +static inline long +syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { return regs->gpr[0]; } #endif #if defined(__ia64__) -static inline unsigned long -__stp_user_syscall_nr(struct pt_regs *regs) +static inline long +syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { return regs->r15; } #endif #if defined(__s390__) || defined(__s390x__) -static inline unsigned long -__stp_user_syscall_nr(struct pt_regs *regs) +static inline long +syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - // might need to be 'orig_gpr2' + // might need to be 'orig_gpr2' return regs->gprs[2]; } #endif #if defined(__i386__) || defined(__x86_64__) -static inline long * -__stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs) +static inline long +syscall_get_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 +// syscall_get_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 @@ -145,158 +154,233 @@ __stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs) # endif #endif #if defined(STAPCONF_X86_UNIREGS) - return ®s->ax; + return regs->ax; #elif defined(__x86_64__) - return ®s->rax; + return regs->rax; #elif defined (__i386__) - return ®s->eax; + return regs->eax; #endif } #endif #if defined(__powerpc__) -static inline long * -__stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs) +static inline long +syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) { - return ®s->gpr[3]; + return regs->gpr[3]; } #endif #if defined(__ia64__) -static inline long * -__stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs) +static inline long +syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) { - return ®s->r8; + return regs->r8; } #endif #if defined(__s390__) || defined(__s390x__) -static inline long * -__stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs) +static inline long +syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) { - return ®s->gprs[2]; + return regs->gprs[2]; } #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) +static inline void +syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, unsigned long *args) { -#if defined(__i386__) - if (n > 5) { - _stp_error("syscall arg > 5"); - return NULL; + if (i + n > 6) { + _stp_error("invalid syscall arg request"); + return; } +#if defined(__i386__) #if defined(STAPCONF_X86_UNIREGS) - return ®s->bx + n; + memcpy(args, ®s->bx + i, n * sizeof(args[0])); #else - return ®s->ebx + n; + memcpy(args, ®s->ebx + i, n * sizeof(args[0])); #endif #elif defined(__x86_64__) #ifdef CONFIG_IA32_EMULATION - if (test_tsk_thread_flag(task, TIF_IA32)) - switch (n) { + if (test_tsk_thread_flag(task, TIF_IA32)) { + switch (i) { #if defined(STAPCONF_X86_UNIREGS) - 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; + case 0: + if (!n--) break; + *args++ = regs->bx; + case 1: + if (!n--) break; + *args++ = regs->cx; + case 2: + if (!n--) break; + *args++ = regs->dx; + case 3: + if (!n--) break; + *args++ = regs->si; + case 4: + if (!n--) break; + *args++ = regs->di; + case 5: + if (!n--) break; + *args++ = regs->bp; #else - case 0: return ®s->rbx; - case 1: return ®s->rcx; - case 2: return ®s->rdx; - case 3: return ®s->rsi; - case 4: return ®s->rdi; - case 5: return ®s->rbp; + case 0: + if (!n--) break; + *args++ = regs->rbx; + case 1: + if (!n--) break; + *args++ = regs->rcx; + case 2: + if (!n--) break; + *args++ = regs->rdx; + case 3: + if (!n--) break; + *args++ = regs->rsi; + case 4: + if (!n--) break; + *args++ = regs->rdi; + case 5: + if (!n--) break; + *args++ = regs->rbp; #endif - default: - _stp_error("syscall arg > 5"); - return NULL; } + return; + } #endif /* CONFIG_IA32_EMULATION */ - switch (n) { + switch (i) { #if defined(STAPCONF_X86_UNIREGS) - 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; + case 0: + if (!n--) break; + *args++ = regs->di; + case 1: + if (!n--) break; + *args++ = regs->si; + case 2: + if (!n--) break; + *args++ = regs->dx; + case 3: + if (!n--) break; + *args++ = regs->r10; + case 4: + if (!n--) break; + *args++ = regs->r8; + case 5: + if (!n--) break; + *args++ = regs->r9; #else - case 0: return ®s->rdi; - case 1: return ®s->rsi; - case 2: return ®s->rdx; - case 3: return ®s->r10; - case 4: return ®s->r8; - case 5: return ®s->r9; + case 0: + if (!n--) break; + *args++ = regs->rdi; + case 1: + if (!n--) break; + *args++ = regs->rsi; + case 2: + if (!n--) break; + *args++ = regs->rdx; + case 3: + if (!n--) break; + *args++ = regs->r10; + case 4: + if (!n--) break; + *args++ = regs->r8; + case 5: + if (!n--) break; + *args++ = regs->r9; #endif - default: - _stp_error("syscall arg > 5"); - return NULL; } #endif /* CONFIG_X86_32 */ + return; } #endif #if defined(__powerpc__) -static inline long * -__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs, - unsigned int n) +static inline void +syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, unsigned long *args) { - switch (n) { - case 0: return ®s->gpr[3]; - case 1: return ®s->gpr[4]; - case 2: return ®s->gpr[5]; - case 3: return ®s->gpr[6]; - case 4: return ®s->gpr[7]; - case 5: return ®s->gpr[8]; - default: - _stp_error("syscall arg > 5"); - return NULL; + if (i + n > 6) { + _stp_error("invalid syscall arg request"); + return; } + memcpy(args, ®s->gpr[3 + i], n * sizeof(args[0])); } #endif #if defined(__ia64__) -#define __stp_user_syscall_arg(task, regs, n) \ - ____stp_user_syscall_arg(task, regs, n, &c->unwaddr) +#define syscall_get_arguments(task, regs, i, n, args) \ + __ia64_syscall_get_arguments(task, regs, i, n, args, &c->unwaddr) -static inline long * -____stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs, - unsigned int n, unsigned long **cache) +static inline void +__ia64_syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args, unsigned long **cache) { - if (n > 5) { - _stp_error("syscall arg > 5"); - return NULL; + if (i + n > 6) { + _stp_error("invalid syscall arg request"); + return; + } + switch (i) { + case 0: + if (!n--) break; + *args++ = *__ia64_fetch_register(i + 32, regs, cache); + case 1: + if (!n--) break; + *args++ = *__ia64_fetch_register(i + 33, regs, cache); + case 2: + if (!n--) break; + *args++ = *__ia64_fetch_register(i + 34, regs, cache); + case 3: + if (!n--) break; + *args++ = *__ia64_fetch_register(i + 35, regs, cache); + case 4: + if (!n--) break; + *args++ = *__ia64_fetch_register(i + 36, regs, cache); + case 5: + if (!n--) break; + *args++ = *__ia64_fetch_register(i + 37, regs, cache); } - return __ia64_fetch_register(n + 32, regs, cache); } #endif #if defined(__s390__) || defined(__s390x__) -static inline long * -__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs, - unsigned int n) +static inline void +syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, unsigned long *args) { - /* If we were returning a value, we could check for TIF_31BIT - * here and cast the value with '(u32)' to make sure it got - * down to 32bits. But, since we're returning an address, - * there isn't much we can do. */ - switch (n) { - case 0: return ®s->orig_gpr2; - case 1: return ®s->gprs[3]; - case 2: return ®s->gprs[4]; - case 3: return ®s->gprs[5]; - case 4: return ®s->gprs[6]; - case 5: return ®s->args[0]; - default: - _stp_error("syscall arg > 5"); - return NULL; + unsigned long mask = -1UL; + + if (i + n > 6) { + _stp_error("invalid syscall arg request"); + return; + } +#ifdef CONFIG_COMPAT + if (test_tsk_thread_flag(task, TIF_31BIT)) + mask = 0xffffffff; +#endif + switch (i) { + case 0: + if (!n--) break; + *args++ = regs->orig_gpr2 & mask; + case 1: + if (!n--) break; + *args++ = regs->gprs[3] & mask; + case 2: + if (!n--) break; + *args++ = regs->gprs[4] & mask; + case 3: + if (!n--) break; + *args++ = regs->gprs[5] & mask; + case 4: + if (!n--) break; + *args++ = regs->gprs[6] & mask; + case 5: + if (!n--) break; + *args++ = regs->args[0] & mask; } } #endif +#endif /* !STAPCONF_ASM_SYSCALL_H */ #endif /* _SYSCALL_H_ */ diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 433a042a..fa6c296e 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -1065,11 +1065,9 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, #endif { struct stap_task_finder_target *tgt = engine->data; - unsigned long syscall_no; - unsigned long *rv_addr, rv; - unsigned long *arg_addr, arg0; - unsigned long arg1 = 0; - unsigned long arg2 = 0; + long syscall_no; + unsigned long rv; + unsigned long args[3]; int rc; struct mm_struct *mm; struct vm_area_struct *vma; @@ -1088,7 +1086,7 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, // See if syscall is one we're interested in. // // FIXME: do we need to handle mremap()? - syscall_no = __stp_user_syscall_nr(regs); + syscall_no = syscall_get_nr(tsk, regs); if (syscall_no != MMAP_SYSCALL_NO(tsk) && syscall_no != MMAP2_SYSCALL_NO(tsk) && syscall_no != MPROTECT_SYSCALL_NO(tsk) @@ -1106,21 +1104,11 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, return UTRACE_RESUME; // Get return value - rv_addr = __stp_user_syscall_return_value(tsk, regs); - if ((rc = __stp_get_user(rv, rv_addr)) != 0) { - _stp_error("couldn't read syscall return value for pid %d: %d", - tsk->pid, rc); - return UTRACE_RESUME; - } + rv = syscall_get_return_value(tsk, regs); // We need the first syscall argument to see what address we // were operating on. - arg_addr = __stp_user_syscall_arg(tsk, regs, 0); - if ((rc = __stp_get_user(arg0, arg_addr)) != 0) { - _stp_error("couldn't read syscall arg 0 for pid %d: %d", - tsk->pid, rc); - return UTRACE_RESUME; - } + syscall_get_arguments(tsk, regs, 0, 1, args); #ifdef DEBUG_TASK_FINDER_VMA _stp_dbug(__FUNCTION__, __LINE__, @@ -1131,20 +1119,15 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, : ((syscall_no == MPROTECT_SYSCALL_NO(tsk)) ? "mprotect" : ((syscall_no == MUNMAP_SYSCALL_NO(tsk)) ? "munmap" : "UNKNOWN")))), - arg0, rv); + args[0], rv); #endif __stp_tf_handler_start(); if (syscall_no == MUNMAP_SYSCALL_NO(tsk)) { // We need the 2nd syscall argument for the length. - arg_addr = __stp_user_syscall_arg(tsk, regs, 1); - if ((rc = __stp_get_user(arg1, arg_addr)) != 0) { - _stp_error("couldn't read syscall arg 1 for pid %d: %d", - tsk->pid, rc); - goto syscall_exit_done; - } + syscall_get_arguments(tsk, regs, 1, 1, &args[1]); // Call the callbacks - __stp_call_munmap_callbacks(tgt, tsk, arg0, arg1); + __stp_call_munmap_callbacks(tgt, tsk, args[0], args[1]); } else if (syscall_no == MMAP_SYSCALL_NO(tsk) || syscall_no == MMAP2_SYSCALL_NO(tsk)) { @@ -1165,24 +1148,13 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, } } else { - // We need the 2nd syscall argument for the length. - arg_addr = __stp_user_syscall_arg(tsk, regs, 1); - if ((rc = __stp_get_user(arg1, arg_addr)) != 0) { - _stp_error("couldn't read syscall arg 1 for pid %d: %d", - tsk->pid, rc); - goto syscall_exit_done; - } - - // We need the 3nd syscall argument for the protection. - arg_addr = __stp_user_syscall_arg(tsk, regs, 2); - if ((rc = __stp_get_user(arg2, arg_addr)) != 0) { - _stp_error("couldn't read syscall arg 2 for pid %d: %d", - tsk->pid, rc); - goto syscall_exit_done; - } + // We need the 2nd syscall argument for the length and + // the 3rd argument for the protection. + syscall_get_arguments(tsk, regs, 1, 2, &args[1]); // Call the callbacks - __stp_call_mprotect_callbacks(tgt, tsk, arg0, arg1, arg2); + __stp_call_mprotect_callbacks(tgt, tsk, args[0], args[1], + args[2]); } syscall_exit_done: -- cgit From b9c2e81cc7a62336ec1daf374cb3411add772ab4 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 13 Apr 2009 19:50:23 -0700 Subject: PR10067: fix bitfield access * tapsets.cxx (dwflpp::translate_components): Eliminate the extra die-dereference at the end of the loop (a regression from @casts). * runtime/loc2c-runtime.h (store_bitfield): Use the target as the representative type, since the base is always int64_t. Also be a bit more aggressive with masking and parentheses. * testsuite/systemtap.base/bitfield.*: New test for R/W bitfields. --- runtime/loc2c-runtime.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'runtime') diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h index eaf47cad..620e1615 100644 --- a/runtime/loc2c-runtime.h +++ b/runtime/loc2c-runtime.h @@ -29,11 +29,12 @@ & (((__typeof (base)) 1 << (nbits)) - 1)) #define store_bitfield(target, base, higherbits, nbits) \ - target = (target \ - &~ ((((__typeof (base)) 1 << (nbits)) - 1) \ - << (sizeof (base) * 8 - (higherbits) - (nbits))) \ - | ((__typeof (base)) (base) \ - << (sizeof (base) * 8 - (higherbits) - (nbits)))) + target = ((target \ + &~ ((((__typeof (target)) 1 << (nbits)) - 1) \ + << (sizeof (target) * 8 - (higherbits) - (nbits)))) \ + | ((((__typeof (target)) (base)) \ + & (((__typeof (target)) 1 << (nbits)) - 1)) \ + << (sizeof (target) * 8 - (higherbits) - (nbits)))) /* Given a DWARF register number, fetch its intptr_t (long) value from the -- cgit