summaryrefslogtreecommitdiffstats
path: root/runtime/syscall.h
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2009-04-22 13:21:17 -0400
committerMasami Hiramatsu <mhiramat@redhat.com>2009-04-22 13:21:17 -0400
commitb453b91268d5bd3d08614d37c3833dfc44b8ee64 (patch)
tree295797546f418530808142206aaae2999b563a1f /runtime/syscall.h
parent055b3e70a42e14453ad051de1a51de84b728b984 (diff)
downloadsystemtap-steved-b453b91268d5bd3d08614d37c3833dfc44b8ee64.tar.gz
systemtap-steved-b453b91268d5bd3d08614d37c3833dfc44b8ee64.tar.xz
systemtap-steved-b453b91268d5bd3d08614d37c3833dfc44b8ee64.zip
utrace/ia64: Fix syscall_get_set_args_cb() to handle syscalls via syscall()
* runtime/syscall.h (syscall_get_set_args_cb): Fix to decode user stack collectly in case of syscall(), and check the maximum number of syscall arguments.
Diffstat (limited to 'runtime/syscall.h')
-rw-r--r--runtime/syscall.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/runtime/syscall.h b/runtime/syscall.h
index ffc21efc..38b523e1 100644
--- a/runtime/syscall.h
+++ b/runtime/syscall.h
@@ -345,6 +345,10 @@ struct syscall_get_set_args {
int rw;
};
+#define CFM_SOF(cfm) ((cfm) & 0x7f) /* Size of frame */
+#define CFM_SOL(cfm) (((cfm) >> 7) & 0x7f) /* Size of locals */
+#define CFM_OUT(cfm) (CFM_SOF(cfm) - CFM_SOL(cfm)) /* Size of outputs */
+
static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data)
{
struct syscall_get_set_args *args = data;
@@ -361,15 +365,18 @@ static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data)
count = 0;
if (in_syscall(pt))
- count = min_t(int, args->n, cfm & 0x7f);
+ /* args->i + args->n must be less equal than nr outputs */
+ count = min_t(int, args->n, CFM_OUT(cfm) - args->i);
for (i = 0; i < count; i++) {
+ /* Skips dirties and locals */
if (args->rw)
- *ia64_rse_skip_regs(krbs, ndirty + i + args->i) =
+ *ia64_rse_skip_regs(krbs,
+ ndirty + CFM_SOL(cfm) + args->i + i) =
args->args[i];
else
args->args[i] = *ia64_rse_skip_regs(krbs,
- ndirty + i + args->i);
+ ndirty + CFM_SOL(cfm) + args->i + i);
}
if (!args->rw) {