From 987a37e77751d1a8aac0a0591c3b53fddf0de7cd Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 2 Jun 2009 18:59:53 -0700 Subject: [PATCH] Add $arch/nd_syscalls.stp These are all the dwarfless analogs to $arch/syscalls.stp. (Only i686 and x86_64 have been tested...) --- tapset/i686/nd_syscalls.stp | 205 ++++++++++ tapset/ia64/nd_syscalls.stp | 102 +++++ tapset/ppc64/nd_syscalls.stp | 738 ++++++++++++++++++++++++++++++++++ tapset/s390x/nd_syscalls.stp | 187 +++++++++ tapset/x86_64/nd_syscalls.stp | 187 +++++++++ 5 files changed, 1419 insertions(+) create mode 100644 tapset/i686/nd_syscalls.stp create mode 100644 tapset/ia64/nd_syscalls.stp create mode 100644 tapset/ppc64/nd_syscalls.stp create mode 100644 tapset/s390x/nd_syscalls.stp create mode 100644 tapset/x86_64/nd_syscalls.stp diff --git a/tapset/i686/nd_syscalls.stp b/tapset/i686/nd_syscalls.stp new file mode 100644 index 000000000..f19e54a98 --- /dev/null +++ b/tapset/i686/nd_syscalls.stp @@ -0,0 +1,205 @@ +# 32-bit x86-specific system calls +# These are typically defined in arch/i386 +# + +# get_thread_area ____________________________________________ +/* + * asmlinkage int + * sys_get_thread_area(struct user_desc __user *u_info) + */ +probe nd_syscall.get_thread_area = kprobe.function("sys_get_thread_area") +{ + name = "get_thread_area" + // u_info_uaddr = $u_info + asmlinkage() + u_info_uaddr = pointer_arg(1) + argstr = sprintf("%p", u_info_uaddr) +} +probe nd_syscall.get_thread_area.return = kprobe.function("sys_get_thread_area").return +{ + name = "get_thread_area" + retstr = returnstr(1) +} + +# iopl _______________________________________________________ +# long sys_iopl(unsigned long unused) +# NOTE. This function is only in i386 and x86_64 and its args vary +# between those two archs. +# +probe nd_syscall.iopl = kprobe.function("sys_iopl") +{ + name = "iopl" + argstr = "" +} +probe nd_syscall.iopl.return = kprobe.function("sys_iopl").return +{ + name = "iopl" + retstr = returnstr(1) +} + +# ipc ________________________________________________________ +# int sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth) +# +probe nd_syscall.ipc = kprobe.function("sys_ipc") ? +{ + name = "ipc" + // call = $call + // first = $first + // second = $second + // third = $third + // ptr_uaddr = $ptr + // fifth = $fifth + // argstr = sprintf("%d, %d, %d, %d, %p, %d", $call, $first, + // $second, $third, $ptr, $fifth) + asmlinkage() + call = uint_arg(1) + first = int_arg(2) + second = int_arg(3) + third = int_arg(4) + ptr_uaddr = pointer_arg(5) + fifth = long_arg(6) + argstr = sprintf("%d, %d, %d, %d, %p, %d", call, first, + second, third, ptr_uaddr, fifth) +} +probe nd_syscall.ipc.return = kprobe.function("sys_ipc").return ? +{ + name = "ipc" + retstr = returnstr(1) +} + +# mmap2 ____________________________________________ +# sys_mmap2(unsigned long addr, unsigned long len, +# unsigned long prot, unsigned long flags, +# unsigned long fd, unsigned long pgoff) +# +probe nd_syscall.mmap2 = kprobe.function("sys_mmap2") ? +{ + name = "mmap2" + // start = $addr + // length = $len + // prot = $prot + // flags = $flags + // fd = $fd + // pgoffset = $pgoff + // argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr, + // $len, _mprotect_prot_str($prot), _mmap_flags($flags), + // $fd, $pgoff) + asmlinkage() + start = ulong_arg(1) + length = ulong_arg(2) + prot = ulong_arg(3) + flags = ulong_arg(4) + fd = ulong_arg(5) + pgoffset = ulong_arg(6) + argstr = sprintf("%p, %d, %s, %s, %d, %d", start, + length, _mprotect_prot_str(prot), _mmap_flags(flags), + fd, pgoffset) +} +probe nd_syscall.mmap2.return = kprobe.function("sys_mmap2").return ? +{ + name = "mmap2" + retstr = returnstr(2) +} + +# set_thread_area ____________________________________________ +/* + * asmlinkage int + * sys_set_thread_area(struct user_desc __user *u_info) + */ +probe nd_syscall.set_thread_area = kprobe.function("sys_set_thread_area") +{ + name = "set_thread_area" + // u_info_uaddr = $u_info + asmlinkage() + u_info_uaddr = pointer_arg(1) + argstr = sprintf("%p", u_info_uaddr) +} +probe nd_syscall.set_thread_area.return = kprobe.function("sys_set_thread_area").return +{ + name = "set_thread_area" + retstr = returnstr(1) +} + +# set_zone_reclaim ___________________________________________ +/* + * asmlinkage long + * sys_set_zone_reclaim(unsigned int node, + * unsigned int zone, + * unsigned int state) + */ +probe nd_syscall.set_zone_reclaim = kprobe.function("sys_set_zone_reclaim") ? +{ + name = "set_zone_reclaim" + // node = $node + // zone = $zone + // state = $state + // argstr = sprintf("%d, %d, %d", $node, $zone, $state) + asmlinkage() + node = uint_arg(1) + zone = uint_arg(2) + state = uint_arg(3) + argstr = sprintf("%d, %d, %d", node, zone, state) +} +probe nd_syscall.set_zone_reclaim.return = kprobe.function("sys_set_zone_reclaim").return ? +{ + name = "set_zone_reclaim" + retstr = returnstr(1) +} + +# sigaltstack ________________________________________________ +# int sys_sigaltstack(unsigned long ebx) +# +# NOTE: args vary between archs. +# +probe nd_syscall.sigaltstack = kprobe.function("sys_sigaltstack") +{ + name = "sigaltstack" + // ussp = %( kernel_vr < "2.6.25" %? $ebx %: %( kernel_vr < "2.6.29" %? $bx %: $regs->bx %) %) + // NB: no asmlinkage() + ussp = %( kernel_vr < "2.6.29" %? ulong_arg(1) %: @cast(ulong_arg(1), "pt_regs")->bx %) + argstr = sprintf("%p", ussp) +} +probe nd_syscall.sigaltstack.return = kprobe.function("sys_sigaltstack").return +{ + name = "sigaltstack" + retstr = returnstr(1) +} + +# vm86 _______________________________________________________ +# +# int sys_vm86(struct pt_regs regs) +# +probe nd_syscall.vm86 = kprobe.function("sys_vm86") ? +{ + name = "vm86" + /* + * unsupported type identifier '$regs' + * regs = $regs + */ + argstr = "" +} +probe nd_syscall.vm86.return = kprobe.function("sys_vm86").return ? +{ + name = "vm86" + retstr = returnstr(1) +} + +# vm86old ____________________________________________________ +# +# int sys_vm86old(struct pt_regs regs) +# +probe nd_syscall.vm86old = kprobe.function("sys_vm86old") ? +{ + name = "vm86old" + /* + * unsupported type identifier '$regs' + * regs = $regs + */ + argstr = "" +} +probe nd_syscall.vm86old.return = kprobe.function("sys_vm86old").return ? +{ + name = "vm86old" + retstr = returnstr(1) +} + diff --git a/tapset/ia64/nd_syscalls.stp b/tapset/ia64/nd_syscalls.stp new file mode 100644 index 000000000..d25423d15 --- /dev/null +++ b/tapset/ia64/nd_syscalls.stp @@ -0,0 +1,102 @@ +# IA64 system calls + +# mmap +# sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off) +# +probe nd_syscall.mmap = kprobe.function("sys_mmap") ? +{ + name = "mmap" + // start = $addr + // len = $len + // prot = $prot + // flags = $flags + // fd = $fd + // offset = $off + // argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr, $len, + // _mprotect_prot_str($prot), _mmap_flags($flags), $fd, $off) + asmlinkage() + start = ulong_arg(1) + len = ulong_arg(2) + prot = int_arg(3) + flags = int_arg(4) + fd = int_arg(5) + offset = long_arg(6) + argstr = sprintf("%p, %d, %s, %s, %d, %d", start, len, + _mprotect_prot_str(prot), _mmap_flags(flags), fd, offset) +} + +probe nd_syscall.mmap.return = kprobe.function("sys_mmap").return ? +{ + name = "mmap" + retstr = returnstr(2) +} + +# mmap2 +# sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff) +probe nd_syscall.mmap2 = kprobe.function("sys_mmap2") ? +{ + name = "mmap2" + // start = $addr + // length = $len + // prot = $prot + // flags = $flags + // fd = $fd + // pgoffset = $pgoff + // argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr, + // $len, _mprotect_prot_str($prot), _mmap_flags($flags), + // $fd, $pgoff) + asmlinkage() + start = ulong_arg(1) + length = ulong_arg(2) + prot = int_arg(3) + flags = int_arg(4) + fd = int_arg(5) + pgoffset = long_arg(6) + argstr = sprintf("%p, %d, %s, %s, %d, %d", start, length, + _mprotect_prot_str(prot), _mmap_flags(flags), fd, pgoffset) +} +probe nd_syscall.mmap2.return = kprobe.function("sys_mmap2").return ? +{ + name = "mmap2" + retstr = returnstr(2) +} + +# sigaltstack _______________________________________________ +# asmlinkage long +# sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2, +# long arg3, long arg4, long arg5, long arg6, long arg7, +# struct pt_regs regs) +# +probe nd_syscall.sigaltstack = kprobe.function("sys_sigaltstack") +{ + name = "sigaltstack"; + // ss_uaddr = $uss + // oss_uaddr = $uoss + // argstr = sprintf("%p, %p", $uss, $uoss) + asmlinkage() + ss_uaddr = pointer_arg(1) + oss_uaddr = pointer_arg(2) + argstr = sprintf("%p, %p", ss_uaddr, oss_uaddr) +} +probe nd_syscall.sigaltstack.return = kprobe.function("sys_sigaltstack").return +{ + name = "sigaltstack"; + retstr = returnstr(1) +} + +# sysctl _____________________________________________________ +# +# long sys32_sysctl (struct sysctl32 __user *args) +# +probe nd_syscall.sysctl32 = kprobe.function("sys32_sysctl") ? +{ + name = "sysctl" + // argstr = sprintf("%p", $args) + asmlinkage() + argstr = sprintf("%p", pointer_arg(1)) +} +probe nd_syscall.sysctl32.return = kprobe.function("sys32_sysctl").return ? +{ + name = "sysctl" + retstr = returnstr(1) +} diff --git a/tapset/ppc64/nd_syscalls.stp b/tapset/ppc64/nd_syscalls.stp new file mode 100644 index 000000000..46267507e --- /dev/null +++ b/tapset/ppc64/nd_syscalls.stp @@ -0,0 +1,738 @@ +# PPC64-specific system calls + +# sys64_time ________________________________________ +# +# time_t sys64_time(time_t __user * tloc) +# +probe nd_syscall.sys64_time = kprobe.function("sys64_time") ? +{ + name = "sys64_time" + // argstr = sprintf("%p", $tloc) + asmlinkage() + argstr = sprintf("%p", pointer_arg(1)) +} +probe nd_syscall.sys64_time.return = kprobe.function("sys64_time").return ? +{ + name = "sys64_time" + retstr = returnstr(1) +} + +# ppc64_personality ________________________________________ +# +# long ppc64_personality(unsigned long personality) +# +probe nd_syscall.ppc64_personality = kprobe.function("ppc64_personality") +{ + name = "ppc64_personality" + // persona = $personality + // argstr = sprint($personality) + asmlinkage() + persona = ulong_arg(1) + argstr = sprint(persona) +} +probe nd_syscall.ppc64_personality.return = kprobe.function("ppc64_personality").return +{ + name = "ppc64_personality" + retstr = returnstr(1) +} + +# ppc_rtas ________________________________________ +# +# int ppc_rtas(struct rtas_args __user *uargs) +# +probe nd_syscall.ppc_rtas = kprobe.function("ppc_rtas") ? +{ + name = "ppc_rtas" + // uargs_uaddr = $uargs + // argstr = sprintf("%p", $uargs) + asmlinkage() + uargs_uaddr = pointer_arg(1) + argstr = sprintf("%p", uargs_uaddr) +} +probe nd_syscall.ppc_rtas.return = kprobe.function("ppc_rtas").return ? +{ + name = "ppc_rtas" + retstr = returnstr(1) +} + +# ppc64_sys32_stime ________________________________________ +# +# long ppc64_sys32_stime(int __user * tptr) +# +probe nd_syscall.ppc64_sys32_stime = kprobe.function("ppc64_sys32_stime") ? +{ + name = "ppc64_sys32_stime" + // t_uaddr = $tptr + // argstr = sprintf("%p", $tptr) + asmlinkage() + t_uaddr = pointer_arg(1) + argstr = sprintf("%p", t_uaddr) +} +probe nd_syscall.ppc64_sys32_stime.return = kprobe.function("ppc64_sys32_stime").return ? +{ + name = "ppc64_sys32_stime" + retstr = returnstr(1) +} + +# sys32_ptrace ________________________________________ +# (obsolete) +# int sys32_ptrace(long request, long pid, unsigned long addr, +# unsigned long data) +# +probe nd_syscall.sys32_ptrace = kprobe.function("sys32_ptrace") ? +{ + name = "sys32_ptrace" + // request = $request + // pid = $pid + // addr = $addr + // data = $data + // argstr = sprintf("%p, %p, %p, %p", $request, $pid, $addr, $data) + asmlinkage() + request = long_arg(1) + pid = long_arg(2) + addr = ulong_arg(3) + data = ulong_arg(4) + argstr = sprintf("%p, %p, %p, %p", request, pid, addr, data) +} +probe nd_syscall.sys32_ptrace.return = kprobe.function("sys32_ptrace").return ? +{ + name = "sys32_ptrace" + retstr = returnstr(1) +} + +# sys32_sysinfo ________________________________________ +# +# (obsolete) long sys32_sysinfo(struct sysinfo32 __user *info) +# +probe nd_syscall.sys32_sysinfo = kprobe.function("sys32_sysinfo") ? +{ + name = "sys32_sysinfo" + // info_uaddr = $info + asmlinkage() + info_uaddr = pointer_arg(1) + argstr = sprintf("%p", info_uaddr) +} +probe nd_syscall.sys32_sysinfo.return = kprobe.function("sys32_sysinfo").return ? +{ + name = "sys32_sysinfo" + retstr = returnstr(1) +} + +# ipc ________________________________________ +# +# long sys32_ipc(u32 call, u32 first, u32 second, u32 third, +# compat_uptr_t ptr, u32 fifth) +# +probe nd_syscall.ipc = kprobe.function("sys32_ipc") ? +{ + name = "ipc" + // argstr = sprintf("%d, %d, %d, %d, %p, %d", $call, $first, $second, + // $third, $ptr, $fifth) + asmlinkage() + argstr = sprintf("%d, %d, %d, %d, %p, %d", uint_arg(1), uint_arg(2), uint_arg(3), + uint_arg(4), uint_arg(5), uint_arg(6)) +} +probe nd_syscall.ipc.return = kprobe.function("sys32_ipc").return ? +{ + name = "sys_ipc" + retstr = returnstr(1) +} + +# sys32_sigreturn ________________________________________ +# +# long sys32_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, +# struct pt_regs *regs) +# +probe nd_syscall.sys32_sigreturn = kprobe.function("sys32_sigreturn") ? +{ + name = "sys32_sigreturn" + // r3 = $r3 + // r4 = $r4 + // // r5 = $r5 + // r6 = $r6 + // r7 = $r7 + // r8 = $r8 + // argstr = sprintf("%p, %p, %p, %p, %p, %p", + // $r3, $r4, $r5, $r6, $r7, $r8) + asmlinkage() + r3 = int_arg(1) + r4 = int_arg(2) + r5 = int_arg(3) + r6 = int_arg(4) + r7 = int_arg(5) + r8 = int_arg(6) + argstr = sprintf("%p, %p, %p, %p, %p, %p", + r3, r4, r5, r6, r7, r8) +} +probe nd_syscall.sys32_sigreturn.return = kprobe.function("sys32_sigreturn").return ? +{ + name = "sys32_sigreturn" + retstr = returnstr(1) +} + +# sys32_adjtimex ________________________________________ +# +# long sys32_adjtimex(struct timex32 __user *utp) +# +probe nd_syscall.sys32_adjtimex = kprobe.function("sys32_adjtimex") ? +{ + name = "sys32_adjtimex" + // argstr = sprintf("%p", $utp) + asmlinkage() + argstr = sprintf("%p", pointer_arg(1)) +} +probe nd_syscall.sys32_adjtimex.return = kprobe.function("sys32_adjtimex").return ? +{ + name = "sys32_adjtimex" + retstr = returnstr(1) +} + +# sys32_getdents ________________________________________ +# +# asmlinkage long sys32_getdents(unsigned int fd, +# struct linux_dirent32 __user *dirent, +# unsigned int count) +# +probe nd_syscall.sys32_getdents = kprobe.function("sys32_getdents") ? +{ + name = "sys32_getdents" + // fd = $fd + // dirp_uaddr = $dirent + // count = $count + asmlinkage() + fd = uint_arg(1) + dirp_uaddr = pointer_arg(2) + count = uint_arg(3) + argstr = sprintf("%d, %p, %d", fd, dirp_uaddr, count) +} +probe nd_syscall.sys32_getdents.return = kprobe.function("sys32_getdents").return ? +{ + name = "sys32_getdents" + retstr = returnstr(1) +} + +# compat_sys_sysctl ________________________________________ +# +# long compat_sys_sysctl(struct __sysctl_args32 __user *args) +# +probe nd_syscall.compat_sysctl = kprobe.function("compat_sys_sysctl") ? +{ + name = "sysctl" + // argstr = sprintf("%p", $args) + asmlinkage() + argstr = sprintf("%p", pointer_arg(1)) +} +probe nd_syscall.compat_sysctl.return = kprobe.function("compat_sys_sysctl").return ? +{ + name = "sysctl" + retstr = returnstr(1) +} + +# sys32_sched_setparam ________________________________________ +# +# asmlinkage long sys32_sched_setparam(u32 pid, +# struct sched_param __user *param) +# +probe nd_syscall.sys32_sched_setparam = kprobe.function("sys32_sched_setparam") ? +{ + name = "sys32_sched_setparam" + // pid = $pid + // param_uaddr = $param + asmlinkage() + pid = uint_arg(1) + param_uaddr = pointer_arg(2) + argstr = sprintf("%d, %p", pid, param_uaddr) +} +probe nd_syscall.sys32_sched_setparam.return = kprobe.function("sys32_sched_setparam").return ? +{ + name = "sys32_sched_setparam" + retstr = returnstr(1) +} + +# sys32_sched_rr_get_interval ________________________________________ +# +# asmlinkage long sys32_sched_rr_get_interval(u32 pid, +# struct compat_timespec __user *interval) +# +probe nd_syscall.sys32_sched_rr_get_interval = kprobe.function("sys32_sched_rr_get_interval") ? +{ + name = "sys32_sched_rr_get_interval" + // pid = $pid + // interval_uaddr = $interval + asmlinkage() + pid = uint_arg(1) + interval_uaddr = pointer_arg(2) + argstr = sprintf("%d, %p", pid, interval_uaddr) +} +probe nd_syscall.sys32_sched_rr_get_interval.return = kprobe.function("sys32_sched_rr_get_interval").return ? +{ + name = "sys32_sched_rr_get_interval" + retstr = returnstr(1) +} + +# sys32_rt_sigpending ________________________________________ +# +# long sys32_rt_sigpending(compat_sigset_t __user *set, +# compat_size_t sigsetsize) +# +probe nd_syscall.sys32_rt_sigpending = kprobe.function("sys32_rt_sigpending") ? +{ + name = "sys32_rt_sigpending" + // set_uaddr = $set + // sigsetsize = $sigsetsize + // argstr = sprintf("%p, %d", set_uaddr, $sigsetsize) + asmlinkage() + set_uaddr = pointer_arg(1) + sigsetsize = uint_arg(2) + argstr = sprintf("%p, %d", set_uaddr, sigsetsize) +} +probe nd_syscall.sys32_rt_sigpending.return = kprobe.function("sys32_rt_sigpending").return ? +{ + name = "sys32_rt_sigpending" + retstr = returnstr(1) +} + +# sys32_rt_sigtimedwait ________________________________________ +# +# long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, +# compat_siginfo_t __user *uinfo, +# struct compat_timespec __user *uts, +# compat_size_t sigsetsize) +# +probe nd_syscall.sys32_rt_sigtimedwait = kprobe.function("sys32_rt_sigtimedwait") ? +{ + name = "sys32_rt_sigtimedwait" + // uthese_uaddr = $uthese + // uinfo_uaddr = $uinfo + // uts_uaddr = $uts + // sigsetsize = $sigsetsize + asmlinkage() + uthese_uaddr = pointer_arg(1) + uinfo_uaddr = pointer_arg(2) + uts_uaddr = pointer_arg(3) + sigsetsize = uint_arg(4) + argstr = sprintf("%p, %p, %p, %p", uthese_uaddr, + uinfo_uaddr, uts_uaddr, sigsetsize) +} +probe nd_syscall.sys32_rt_sigtimedwait.return = kprobe.function("sys32_rt_sigtimedwait").return ? +{ + name = "sys32_rt_sigtimedwait" + retstr = returnstr(1) +} + +# sys32_rt_sigqueueinfo ________________________________________ +# +# long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) +# +probe nd_syscall.sys32_rt_sigqueueinfo = kprobe.function("sys32_rt_sigqueueinfo") ? +{ + name = "sys32_rt_sigqueueinfo" + // pid = $pid + // sig = $sig + // uinfo_uaddr = $uinfo + // argstr = sprintf("%p, %s, %p", pid, _signal_name($sig), + // uinfo_uaddr) + asmlinkage() + pid = uint_arg(1) + sig = uint_arg(2) + uinfo_uaddr = pointer_arg(3) + argstr = sprintf("%p, %s, %p", pid, _signal_name(sig), + uinfo_uaddr) +} +probe nd_syscall.sys32_rt_sigqueueinfo.return = kprobe.function("sys32_rt_sigqueueinfo").return ? +{ + name = "sys32_rt_sigqueueinfo" + retstr = returnstr(1) +} + +# sys32_sigaltstack ________________________________________ +# +# int sys32_sigaltstack(u32 __new, u32 __old, int r5, +# int r6, int r7, int r8, struct pt_regs *regs) +# +probe nd_syscall.sys32_sigaltstack = kprobe.function("sys32_sigaltstack") ? +{ + name = "sys32_sigaltstack" + argstr = "FIXME" +} +probe nd_syscall.sys32_sigaltstack.return = kprobe.function("sys32_sigaltstack").return ? +{ + name = "sys32_sigaltstack" + retstr = returnstr(1) +} + +# sys32_sendfile64 ________________________________________ +# +# asmlinkage int sys32_sendfile64(int out_fd, int in_fd, +# compat_loff_t __user *offset, s32 count) +# +probe nd_syscall.sys32_sendfile64 = kprobe.function("sys32_sendfile64") ? +{ + name = "sys32_sendfile64" + // out_fd = $out_fd + // in_fd = $in_fd + // offset_uaddr = $offset + // count = $count + // argstr = sprintf("%d, %d, %p, %d", $out_fd, $in_fd, offset_uaddr, + // $count) + asmlinkage() + out_fd = int_arg(1) + in_fd = int_arg(2) + offset_uaddr = long_arg(3) + count = int_arg(4) + argstr = sprintf("%d, %d, %p, %d", out_fd, in_fd, offset_uaddr, + count) +} +probe nd_syscall.sys32_sendfile64.return = kprobe.function("sys32_sendfile64").return ? +{ + name = "sys32_sendfile64" + retstr = returnstr(1) +} + +# ppc32_timer_create ________________________________________ +# +# long ppc32_timer_create(clockid_t clock, +# struct compat_sigevent __user *ev32, +# timer_t __user *timer_id) +# +probe nd_syscall.ppc32_timer_create = kprobe.function("ppc32_timer_create") ? +{ + name = "ppc32_timer_create" + // which_clock = $clock + // timer_event_spec = $ev32 + // created_timer_id = $timer_id + asmlinkage() + which_clock = int_arg(1) + timer_event_spec = pointer_arg(2) + created_timer_id = pointer_arg(3) + argstr = sprintf("%d, %p, %p", which_clock, timer_event_spec, + created_timer_id) +} +probe nd_syscall.ppc32_timer_create.return = kprobe.function("ppc32_timer_create").return ? +{ + name = "ppc32_timer_create" + retstr = returnstr(1) +} + +# compat_timer_settime ________________________________________ +# +# long compat_timer_settime(timer_t timer_id, int flags, +# struct compat_itimerspec __user *new, +# struct compat_itimerspec __user *old) +# +probe nd_syscall.compat_timer_settime = kprobe.function("compat_timer_settime") ? +{ + name = "compat_timer_settime" + // timer_id = $timer_id + // flags = $flags + // new_setting_uaddr = $new + // old_setting_uaddr = $old + asmlinkage() + timer_id = int_arg(1) + flags = int_arg(2) + new_setting_uaddr = pointer_arg(3) + old_setting_uaddr = pointer_arg(4) + argstr = sprintf("%d, %d, %p, %p", timer_id, flags, + new_setting_uaddr, old_setting_uaddr) +} +probe nd_syscall.compat_timer_settime.return = kprobe.function("compat_timer_settime").return ? +{ + name = "compat_timer_settime" + retstr = returnstr(1) +} + +# compat_timer_gettime ________________________________________ +# +# long compat_timer_gettime(timer_t timer_id, +# struct compat_itimerspec __user *setting) +# +probe nd_syscall.compat_timer_gettime = kprobe.function("compat_timer_gettime") ? +{ + name = "compat_timer_gettime" + // timer_id = $timer_id + // setting_uaddr = $setting + asmlinkage() + timer_id = int_arg(1) + setting_uaddr = pointer_arg(2) + argstr = sprintf("%d, %p", timer_id, setting_uaddr) +} +probe nd_syscall.compat_timer_gettime.return = kprobe.function("compat_timer_gettime").return ? +{ + name = "compat_timer_gettime" + retstr = returnstr(1) +} + +# compat_clock_settime ________________________________________ +# +# long compat_clock_settime(clockid_t which_clock, +# struct compat_timespec __user *tp) +# +probe nd_syscall.compat_clock_settime = kprobe.function("compat_clock_settime") ? +{ + name = "compat_clock_settime" + // which_clock = $which_clock + // tp_uaddr = $tp + asmlinkage() + which_clock = int_arg(1) + tp_uaddr = pointer_arg(2) + argstr = sprintf("%d, %p", which_clock, tp_uaddr) +} +probe nd_syscall.compat_clock_settime.return = kprobe.function("compat_clock_settime").return ? +{ + name = "compat_clock_settime" + retstr = returnstr(1) +} + +# sys32_swapcontext ________________________________________ +# +# long sys32_swapcontext(struct ucontext32 __user *old_ctx, +# struct ucontext32 __user *new_ctx, +# int ctx_size, int r6, int r7, int r8, +# struct pt_regs *regs) +# +probe nd_syscall.sys32_swapcontext = kprobe.function("sys32_swapcontext") ? +{ + name = "sys32_swapcontext" + // old_ctx_uaddr = $old_ctx + // new_ctx_uaddr = $new_ctx + // r5 = $ctx_size + // r6 = $r6 + // r7 = $r7 + // r8 = $r8 + // regs = $regs + asmlinkage() + old_ctx_uaddr = pointer_arg(1) + new_ctx_uaddr = pointer_arg(2) + r5 = int_arg(3) + r6 = int_arg(4) + r7 = int_arg(5) + r8 = int_arg(6) + regs = pointer_arg(7) + argstr = sprintf("%p, %p, %d, %d, %d, %d, %p", + old_ctx_uaddr, new_ctx_uaddr, r5, r6, r7, r8, regs) +} +probe nd_syscall.sys32_swapcontext.return = kprobe.function("sys32_swapcontext").return ? +{ + name = "sys32_swapcontext" + retstr = returnstr(1) +} + +# sys32_utimes ________________________________________ +# +# asmlinkage long sys32_utimes(char __user *filename, +# struct compat_timeval __user *tvs) +# +probe nd_syscall.sys32_utimes = kprobe.function("sys32_utimes") ? +{ + name = "sys32_utimes" + // filename_uaddr = $filename + // path = user_string($filename) + // tvp_uaddr = $tvs + // argstr = sprintf("%s, %p", user_string_quoted($filename), tvp_uaddr) + asmlinkage() + filename_uaddr = pointer_arg(1) + path = user_string(filename_uaddr) + tvp_uaddr = pointer_arg(2) + argstr = sprintf("%s, %p", user_string_quoted(filename_uaddr), tvp_uaddr) +} +probe nd_syscall.sys32_utimes.return = kprobe.function("sys32_utimes").return ? +{ + name = "sys32_utimes" + retstr = returnstr(1) +} + +# compat_mbind ________________________________________ +# +# asmlinkage long compat_mbind(compat_ulong_t start, compat_ulong_t len, +# compat_ulong_t mode, compat_ulong_t __user *nmask, +# compat_ulong_t maxnode, compat_ulong_t flags) +# +probe nd_syscall.compat_mbind = kprobe.function("compat_mbind") ? +{ + name = "compat_mbind" + // start_uaddr = $start + // len = $len + // policy = $mode + // nodemask_uaddr = $nmask + // maxnode = $maxnode + // flags = $flags + asmlinkage() + start_uaddr = uint_arg(1) + len = uint_arg(2) + policy = uint_arg(3) + nodemask_uaddr = uint_arg(4) + maxnode = uint_arg(5) + flags = uint_arg(6) + argstr = sprintf("%p, %d, %d, %p, %d, %d", start_uaddr, len, + policy, nodemask_uaddr, maxnode, flags) +} +probe nd_syscall.compat_mbind.return = kprobe.function("compat_mbind").return ? +{ + name = "compat_mbind" + retstr = returnstr(1) +} + +# compat_get_mempolicy ________________________________________ +# +# asmlinkage long compat_get_mempolicy(int __user *policy, +# compat_ulong_t __user *nmask, +# compat_ulong_t maxnode, +# compat_ulong_t addr, compat_ulong_t flags) +# +probe nd_syscall.compat_get_mempolicy = kprobe.function("compat_get_mempolicy") ? +{ + name = "compat_get_mempolicy" + // policy_uaddr = $policy + // nmask_uaddr = $nmask + // maxnode = $maxnode + // addr = $addr + // flags = $flags + asmlinkage() + policy_uaddr = int_arg(1) + nmask_uaddr = uint_arg(2) + maxnode = uint_arg(3) + addr = uint_arg(4) + flags = uint_arg(5) + argstr = sprintf("%p, %p, %d, %d", policy_uaddr, nmask_uaddr, + maxnode, addr) +} +probe nd_syscall.compat_get_mempolicy.return = kprobe.function("compat_get_mempolicy").return ? +{ + name = "compat_get_mempolicy" + retstr = returnstr(1) +} + +# compat_set_mempolicy ________________________________________ +# +# asmlinkage long compat_set_mempolicy(int mode, compat_ulong_t __user *nmask, +# compat_ulong_t maxnode) +# +probe nd_syscall.compat_set_mempolicy = kprobe.function("compat_set_mempolicy") ? +{ + name = "compat_set_mempolicy" + // policy = $mode + // nodemask_uaddr = $nmask + // maxnode = $maxnode + asmlinkage() + policy = int_arg(1) + nodemask_uaddr = uint_arg(2) + maxnode = uint_arg(3) + argstr = sprintf("%d, %p, %d", policy, nodemask_uaddr, maxnode) +} +probe nd_syscall.compat_set_mempolicy.return = kprobe.function("compat_set_mempolicy").return ? +{ + name = "compat_set_mempolicy" + retstr = returnstr(1) +} + +# mmap +# long sys_mmap(unsigned long addr, size_t len, +# unsigned long prot, unsigned long flags, +# unsigned long fd, off_t offset) +# +probe nd_syscall.mmap = kprobe.function("sys_mmap") ? +{ + name = "mmap" + // start = $addr + // len = $len + // prot = $prot + // flags = $flags + // fd = $fd + // offset = $offset + // argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr, $len, + // _mprotect_prot_str($prot), _mmap_flags($flags), $fd, $offset) + asmlinkage() + start = ulong_arg(1) + len = ulong_arg(2) + prot = ulong_arg(3) + flags = ulong_arg(4) + fd = ulong_arg(5) + offset = ulong_arg(6) + argstr = sprintf("%p, %d, %s, %s, %d, %d", start, len, + _mprotect_prot_str(prot), _mmap_flags(flags), fd, offset) +} +probe nd_syscall.mmap.return = kprobe.function("sys_mmap").return ? +{ + name = "mmap" + retstr = returnstr(2) +} + +# mmap2 +# long sys_mmap2(unsigned long addr, size_t len, +# unsigned long prot, unsigned long flags, +# unsigned long fd, unsigned long pgoff) +# long compat_sys_mmap2(unsigned long addr, size_t len, +# unsigned long prot, unsigned long flags, +# unsigned long fd, unsigned long pgoff) +# +probe nd_syscall.mmap2 = kprobe.function("sys_mmap2") ?, + kprobe.function("compat_sys_mmap2") ? +{ + name = "mmap2" + // start = $addr + // length = $len + // prot = $prot + // flags = $flags + // fd = $fd + // pgoffset = $pgoff + // argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr, + // $len, _mprotect_prot_str($prot), _mmap_flags($flags), + // $fd, $pgoff) + asmlinkage() + start = ulong_arg(1) + length = ulong_arg(2) + prot = ulong_arg(3) + flags = ulong_arg(4) + fd = ulong_arg(5) + pgoffset = ulong_arg(6) + argstr = sprintf("%p, %d, %s, %s, %d, %d", start, + length, _mprotect_prot_str(prot), _mmap_flags(flags), + fd, pgoffset) +} +probe nd_syscall.mmap2.return = kprobe.function("sys_mmap2").return ?, + kprobe.function("compat_sys_mmap2").return ? +{ + name = "mmap2" + retstr = returnstr(2) +} + +# ppc64_sys_stime ________________________________________ +# +# long ppc64_sys_stime(long __user * tptr) +# +probe nd_syscall.ppc64_sys_stime = kprobe.function("ppc64_sys_stime") ? +{ + name = "ppc64_sys_stime" + /* FIXME */ + // t_uaddr = $tptr + asmlinkage() + t_uaddr = pointer_arg(1) + argstr = sprintf("%p", t_uaddr) +} +probe nd_syscall.ppc64_sys_stime.return = kprobe.function("ppc64_sys_stime").return ? +{ + name = "ppc64_sys_stime" + retstr = returnstr(1) +} + +# ppc64_newuname ________________________________________ +# +# asmlinkage int ppc64_newuname(struct new_utsname __user * name) +# +probe nd_syscall.ppc64_newuname = kprobe.function("ppc64_newuname") ? +{ + name = "ppc64_newuname" + // name_uaddr = $name + asmlinkage() + name_uaddr = pointer_arg(1) + argstr = sprintf("%p", name_uaddr) +} +probe nd_syscall.ppc64_newuname.return = kprobe.function("ppc64_newuname").return ? +{ + name = "ppc64_newuname" + retstr = returnstr(1) +} + +# +# + diff --git a/tapset/s390x/nd_syscalls.stp b/tapset/s390x/nd_syscalls.stp new file mode 100644 index 000000000..63435265f --- /dev/null +++ b/tapset/s390x/nd_syscalls.stp @@ -0,0 +1,187 @@ +# S390-specific system calls + +%(arch == "s390x" %? + +# getresgid __________________________________________________ +# long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid) +# +probe nd_syscall.getresgid16 = kprobe.function("sys32_getresgid16") ? +{ + name = "getresgid" + // argstr = sprintf("%p, %p, %p", $rgid, $egid, $sgid) + asmlinkage() + argstr = sprintf("%p, %p, %p", pointer_arg(1), pointer_arg(2), pointer_arg(3)) +} +probe nd_syscall.getresgid16.return = kprobe.function("sys32_getresgid16").return ? +{ + name = "getresgid" + retstr = returnstr(1) +} + +# getresuid __________________________________________________ +# long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid) +# +probe nd_syscall.getresuid16 = kprobe.function("sys32_getresuid16") ? +{ + name = "getresuid" + // argstr = sprintf("%p, %p, %p", $ruid, $euid, $suid) + asmlinkage() + argstr = sprintf("%p, %p, %p", pointer_arg(1), pointer_arg(2), pointer_arg(3)) +} +probe nd_syscall.getresuid16.return = kprobe.function("sys32_getresuid16").return ? +{ + name = "getresuid" + retstr = returnstr(1) +} + +# ipc _________________________________________________ +# long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) +# +probe nd_syscall.ipc = kprobe.function("sys32_ipc") ? +{ + name = "ipc" + // argstr = sprintf("%d, %d, %d, %d, %p", $call, $first, $second, $third, $ptr) + asmlinkage() + argstr = sprintf("%d, %d, %d, %d, %p", uint_arg(1), int_arg(2), int_arg(3), int_arg(4), uint_arg(5)) +} +probe nd_syscall.ipc.return = kprobe.function("sys_ipc").return ? +{ + name = "ipc" + retstr = returnstr(1) +} + +# mmap _________________________________________________ +# long old_mmap(struct mmap_arg_struct __user *arg) +# long old32_mmap(struct mmap_arg_struct_emu31 __user *arg) +# +probe nd_syscall.mmap = kprobe.function("old_mmap") ?, + kprobe.function("old32_mmap") ?, + kprobe.function("SyS_s390_old_mmap") ? +{ + name = "mmap" + + // if ((probefunc() == "old_mmap") || (probefunc() == "SyS_s390_old_mmap")) + // argstr = get_mmap_args($arg) + // else + // argstr = get_32mmap_args($arg) + + asmlinkage() + if ((probefunc() == "old_mmap") || (probefunc() == "SyS_s390_old_mmap")) + argstr = get_mmap_args(pointer_arg(1)) + else + argstr = get_32mmap_args(pointer_arg(1)) +} +probe nd_syscall.mmap.return = kprobe.function("old_mmap").return ?, + kprobe.function("old32_mmap").return ?, + kprobe.function("SyS_s390_old_mmap").return ? +{ + name = "mmap" + retstr = returnstr(2) +} + +# mmap2 _________________________________________________ +# +# long sys_mmap2(struct mmap_arg_struct __user *arg) +# long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) +# +probe nd_syscall.mmap2 = kprobe.function("sys_mmap2") ?, + kprobe.function("sys32_mmap2") ?, + kprobe.function("SyS_mmap2") ? +{ + name = "mmap2" + + // if ((probefunc() == "sys_mmap2") || (probefunc() == "SyS_mmap2")) + // argstr = get_mmap_args($arg) + // else + // argstr = get_32mmap_args($arg) + + asmlinkage() + if ((probefunc() == "sys_mmap2") || (probefunc() == "SyS_mmap2")) + argstr = get_mmap_args(pointer_arg(1)) + else + argstr = get_32mmap_args(pointer_arg(1)) +} + +probe nd_syscall.mmap2.return = kprobe.function("sys_mmap2").return ?, + kprobe.function("sys32_mmap2").return ?, + kprobe.function("SyS_mmap2").return ? +{ + name = "mmap2" + retstr = returnstr(2) +} + +# sysctl _____________________________________________________ +# +# long sys32_sysctl(struct __sysctl_args32 __user *args) +# +probe nd_syscall.sysctl32 = kprobe.function("sys32_sysctl") ? +{ + name = "sysctl" + // argstr = sprintf("%p", $args) + asmlinkage() + argstr = sprintf("%p", pointer_arg(1)) +} +probe nd_syscall.sysctl32.return = kprobe.function("sys32_sysctl").return ? +{ + name = "sysctl" + retstr = returnstr(1) +} + +/* compat */ +function get_32mmap_args:string (args:long) +%{ /* pure */ + struct mmap_arg_struct_emu31 { + u32 addr; + u32 len; + u32 prot; + u32 flags; + u32 fd; + u32 offset; + }a; + + + char proto[60]; + char flags[256]; + + if(_stp_copy_from_user((char *)&a, + (char *)THIS->args, sizeof(a))== 0){ + + /* _mprotect_prot_str */ + proto[0] = '\0'; + if(a.prot){ + if(a.prot & 1) strcat (proto, "PROT_READ|"); + if(a.prot & 2) strcat (proto, "PROT_WRITE|"); + if(a.prot & 4) strcat (proto, "PROT_EXEC|"); + } else { + strcat (proto, "PROT_NONE"); + } + if (proto[0] != '\0') proto[strlen(proto)-1] = '\0'; + + /* _mmap_flags */ + flags[0]='\0'; + if (a.flags & 1) strcat (flags, "MAP_SHARED|"); + if (a.flags & 2) strcat (flags, "MAP_PRIVATE|"); + if (a.flags & 0x10) strcat (flags, "MAP_FIXED|"); + if (a.flags & 0x20) strcat (flags, "MAP_ANONYMOUS|"); + if (a.flags & 0x100) strcat (flags, "MAP_GROWSDOWN|"); + if (a.flags & 0x800) strcat (flags, "MAP_DENYWRITE|"); + if (a.flags & 0x1000) strcat (flags, "MAP_EXECUTABLE|"); + if (a.flags & 0x2000) strcat (flags, "MAP_LOCKED|"); + if (a.flags & 0x4000) strcat (flags, "MAP_NORESERVE|"); + if (a.flags & 0x8000) strcat (flags, "MAP_POPULATE|"); + if (a.flags & 0x10000) strcat (flags, "MAP_NONBLOCK|"); + if (flags[0] != '\0') flags[strlen(flags)-1] = '\0'; + + sprintf(THIS->__retvalue,"0x%x, %d, %s, %s, %d, %d", + a.addr, + a.len, + proto, + flags, + a.fd, + a.offset); + }else{ + strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN); + } +%} + +%) diff --git a/tapset/x86_64/nd_syscalls.stp b/tapset/x86_64/nd_syscalls.stp new file mode 100644 index 000000000..6a3a984be --- /dev/null +++ b/tapset/x86_64/nd_syscalls.stp @@ -0,0 +1,187 @@ +# x86_64-specific system calls + +# arch_prctl _________________________________________________ +# long sys_arch_prctl(int code, unsigned long addr) +# +# NOTE: x86_64 only. +# +probe nd_syscall.arch_prctl = kprobe.function("sys_arch_prctl") +{ + name = "arch_prctl" + // code = $code + // addr = $addr + // argstr = sprintf("%d, %p", $code, $addr) + // NB: no asmlinkage() + code = int_arg(1) + addr = ulong_arg(2) + argstr = sprintf("%d, %p", code, addr) +} +probe nd_syscall.arch_prctl.return = kprobe.function("sys_arch_prctl").return +{ + name = "arch_prctl" + retstr = returnstr(1) +} + +# iopl _______________________________________________________ +# long sys_iopl(unsigned int level, struct pt_regs *regs); +# NOTE. This function is only in i386 and x86_64 and its args vary +# between those two archs. +# +probe nd_syscall.iopl = kprobe.function("sys_iopl") +{ + name = "iopl" +// %( kernel_vr == "*xen" %? +// level = $new_iopl +// %: +// level = $level +// %) + asmlinkage() + level = int_arg(1) + argstr = sprint(level) +} +probe nd_syscall.iopl.return = kprobe.function("sys_iopl").return +{ + name = "iopl" + retstr = returnstr(1) +} + +# sigaltstack ________________________________________________ +# long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, +# struct pt_regs *regs) +# +# NOTE: args vary between archs. +# +probe nd_syscall.sigaltstack = kprobe.function("sys_sigaltstack") +{ + name = "sigaltstack" + // uss_uaddr = $uss + // uoss_uaddr = $uoss + // regs_uaddr = $regs + // argstr = sprintf("%p, %p", $uss, $uoss) + asmlinkage() + uss_uaddr = pointer_arg(1) + uoss_uaddr = pointer_arg(2) + regs_uaddr = pointer_arg(3) + argstr = sprintf("%p, %p", uss_uaddr, uoss_uaddr) +} +probe nd_syscall.sigaltstack.return = kprobe.function("sys_sigaltstack").return +{ + name = "sigaltstack" + retstr = returnstr(1) +} + +# sysctl _____________________________________________________ +# +# long sys32_sysctl(struct sysctl_ia32 __user *args32) +# +probe nd_syscall.sysctl32 = kprobe.function("sys32_sysctl") ? +{ + name = "sysctl" + // argstr = sprintf("%p", $args32) + asmlinkage() + argstr = sprintf("%p", pointer_arg(1)) +} +probe nd_syscall.sysctl32.return = kprobe.function("sys32_sysctl").return ? +{ + name = "sysctl" + retstr = returnstr(1) +} + +# mmap +# long sys_mmap(unsigned long addr, unsigned long len, +# unsigned long prot, unsigned long flags, +# unsigned long fd, unsigned long off) +probe nd_syscall.mmap = kprobe.function("sys_mmap") ? +{ + name = "mmap" + // start = $addr + // len = $len + // prot = $prot + // flags = $flags + // fd = $fd + // offset = $off + // argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr, $len, + // _mprotect_prot_str($prot), _mmap_flags($flags), $fd, $off) + asmlinkage() + start = ulong_arg(1) + len = ulong_arg(2) + prot = ulong_arg(3) + flags = ulong_arg(4) + fd = ulong_arg(5) + offset = ulong_arg(6) + argstr = sprintf("%p, %d, %s, %s, %d, %d", start, len, + _mprotect_prot_str(prot), _mmap_flags(flags), fd, offset) +} +probe nd_syscall.mmap.return = kprobe.function("sys_mmap").return ? +{ + name = "mmap" + retstr = returnstr(2) +} + +# +# sys32_mmap(struct mmap_arg_struct __user *arg) +# +probe nd_syscall.mmap32 = kprobe.function("sys32_mmap") +{ + name = "mmap" + // argstr = get_mmap_args($arg) + asmlinkage() + argstr = get_mmap_args(pointer_arg(1)) +} +probe nd_syscall.mmap32.return = kprobe.function("sys32_mmap").return +{ + name = "mmap" + retstr = returnstr(2) +} + +# sys32_mmap2(unsigned long addr, unsigned long len, +# unsigned long prot, unsigned long flags, +# unsigned long fd, unsigned long pgoff) +# +probe nd_syscall.mmap2 = kprobe.function("sys32_mmap2") +{ + name = "mmap2" + // argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr, $len, + // _mprotect_prot_str($prot), _mmap_flags($flags), $fd, $pgoff) + asmlinkage() + argstr = sprintf("%p, %d, %s, %s, %d, %d", ulong_arg(1), ulong_arg(2), + _mprotect_prot_str(ulong_arg(3)), _mmap_flags(ulong_arg(4)), + ulong_arg(5), ulong_arg(6)) +} +probe nd_syscall.mmap2.return = kprobe.function("sys32_mmap2").return +{ + name = "mmap2" + retstr = returnstr(2) +} + +# vm86_warning _____________________________________________________ +# +# long sys32_vm86_warning(void) +# +probe nd_syscall.vm86_warning = kprobe.function("sys32_vm86_warning") +{ + name = "vm86_warning" + argstr = "" +} +probe nd_syscall.vm86_warning.return = kprobe.function("sys32_vm86_warning").return +{ + name = "wm86_warning" + retstr = returnstr(1) +} + +# pipe _______________________________________________________ +# +# long sys32_pipe(int __user *fd) +# +probe nd_syscall.pipe32 = kprobe.function("sys32_pipe") +{ + name = "pipe" + // argstr = sprintf("%p", $fd) + asmlinkage() + argstr = sprintf("%p", pointer_arg(1)) +} +probe nd_syscall.pipe32.return = kprobe.function("sys32_pipe").return +{ + name = "pipe" + retstr = returnstr(1) +} -- 2.43.5