From edef3e8e82546c0b2bdbb110da7e4a02480761d6 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Mon, 24 Aug 2009 19:38:51 -0400 Subject: PR4186 cont'd: move tapset/i686 -> tapset/i386 --- tapset/i386/nd_syscalls.stp | 205 ++++++++++++++++++++++++++++++++++++++ tapset/i386/registers.stp | 232 ++++++++++++++++++++++++++++++++++++++++++++ tapset/i386/syscalls.stp | 174 +++++++++++++++++++++++++++++++++ tapset/i686/nd_syscalls.stp | 205 -------------------------------------- tapset/i686/registers.stp | 232 -------------------------------------------- tapset/i686/syscalls.stp | 174 --------------------------------- 6 files changed, 611 insertions(+), 611 deletions(-) create mode 100644 tapset/i386/nd_syscalls.stp create mode 100644 tapset/i386/registers.stp create mode 100644 tapset/i386/syscalls.stp delete mode 100644 tapset/i686/nd_syscalls.stp delete mode 100644 tapset/i686/registers.stp delete mode 100644 tapset/i686/syscalls.stp diff --git a/tapset/i386/nd_syscalls.stp b/tapset/i386/nd_syscalls.stp new file mode 100644 index 00000000..f19e54a9 --- /dev/null +++ b/tapset/i386/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/i386/registers.stp b/tapset/i386/registers.stp new file mode 100644 index 00000000..997376dc --- /dev/null +++ b/tapset/i386/registers.stp @@ -0,0 +1,232 @@ +global _reg_offsets, _stp_regs_registered, _sp_offset, _ss_offset + +function test_x86_gs:long() %{ /* pure */ +#ifdef STAPCONF_X86_GS + THIS->__retvalue = 1; +#else + THIS->__retvalue = 0; +#endif +%} + +function _stp_register_regs() { + + /* Same order as pt_regs */ + _reg_offsets["ebx"] = 0 _reg_offsets["bx"] = 0 + _reg_offsets["ecx"] = 4 _reg_offsets["cx"] = 4 + _reg_offsets["edx"] = 8 _reg_offsets["dx"] = 8 + _reg_offsets["esi"] = 12 _reg_offsets["si"] = 12 + _reg_offsets["edi"] = 16 _reg_offsets["di"] = 16 + _reg_offsets["ebp"] = 20 _reg_offsets["bp"] = 20 + _reg_offsets["eax"] = 24 _reg_offsets["ax"] = 24 + _reg_offsets["xds"] = 28 _reg_offsets["ds"] = 28 + _reg_offsets["xes"] = 32 _reg_offsets["es"] = 32 + _reg_offsets["xfs"] = 36 _reg_offsets["fs"] = 36 + gs_incr = 0 +if (test_x86_gs()) { + gs_incr = 4 + _reg_offsets["xgs"] = 40 _reg_offsets["gs"] = 40 +} + _reg_offsets["orig_eax"] = 40 + gs_incr _reg_offsets["orig_ax"] = 40 + gs_incr + _reg_offsets["eip"] = 44 + gs_incr _reg_offsets["ip"] = 44 + gs_incr + _reg_offsets["xcs"] = 48 + gs_incr _reg_offsets["cs"] = 48 + gs_incr + _reg_offsets["eflags"] = 52 + gs_incr _reg_offsets["flags"] = 52 + gs_incr + _reg_offsets["esp"] = 56 + gs_incr _reg_offsets["sp"] = 56 + gs_incr + _reg_offsets["xss"] = 60 + gs_incr _reg_offsets["ss"] = 60 + gs_incr + _sp_offset = 56 + gs_incr + _ss_offset = 60 + gs_incr + + _stp_regs_registered = 1 +} + +function _stp_get_register_by_offset:long (offset:long) %{ /* pure */ + long value; + if (!CONTEXT->regs) { + CONTEXT->last_error = "No registers available in this context"; + return; + } + if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(long)) { + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "Bad register offset: %lld", THIS->offset); + CONTEXT->last_error = CONTEXT->error_buffer; + return; + } + memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); + THIS->__retvalue = value; +%} + +function _stp_probing_kernel:long () %{ /* pure */ + THIS->__retvalue = !user_mode(CONTEXT->regs); +%} + +/* + * esp and ss aren't saved on a breakpoint in kernel mode, so + * the pre-trap stack pointer is ®s->sp. + */ +function _stp_kernel_sp:long (sp_offset:long) %{ /* pure */ + THIS->__retvalue = ((long) CONTEXT->regs) + THIS->sp_offset; +%} + +/* Assume ss register hasn't changed since we took the trap. */ +function _stp_kernel_ss:long () %{ /* pure */ + unsigned short ss; + asm volatile("movw %%ss, %0" : : "m" (ss)); + THIS->__retvalue = ss; +%} + +/* Return the named register value as a signed value. */ +function register:long (name:string) { + if (!registers_valid()) { + error("cannot access CPU registers in this context") + return 0 + } + if (!_stp_regs_registered) + _stp_register_regs() + offset = _reg_offsets[name] + if (offset == 0 && !(name in _reg_offsets)) { + error("Unknown register: " . name) + return 0 + } + if (_stp_probing_kernel()) { + if (offset == _sp_offset) + return _stp_kernel_sp(_sp_offset) + else if (offset == _ss_offset) + return _stp_kernel_ss() + } + return _stp_get_register_by_offset(offset) +} + +/* + * Return the named register value as an unsigned value. Specifically, + * don't sign-extend the register value when promoting it to 64 bits. + */ +function u_register:long (name:string) { + return register(name) & 0xffffffff; +} + +/* Return the value of function arg #argnum (1=first arg) as a signed value. */ +function _stp_arg:long (argnum:long) %{ /* pure */ + long val; + int n, nr_regargs, result; + + THIS->__retvalue = 0; + if (!CONTEXT->regs) { + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "cannot access function args in this context"); + CONTEXT->last_error = CONTEXT->error_buffer; + return; + } + if (THIS->argnum < 1) + goto bad_argnum; + n = (int) THIS->argnum; + nr_regargs = _stp_get_regparm(CONTEXT->regparm, CONTEXT->regs); + result = _stp_get_arg32_by_number(n, nr_regargs, CONTEXT->regs, &val); + switch (result) { + case 0: + /* Arg is in register. */ + THIS->__retvalue = (int64_t) val; + break; + case 1: + /* Arg is on kernel stack. */ + THIS->__retvalue = kread((long *) val); + break; + case 2: + { + /* Arg is on user stack. */ + const char __user *vaddr = (const char __user*) val; + if (_stp_copy_from_user((char*)&val, vaddr, sizeof(val)) != 0) { + /* Stack page not resident. */ + _stp_warn("cannot access arg(%d) " + "at user stack address %p\n", n, vaddr); + THIS->__retvalue = 0; + } else + THIS->__retvalue = (int64_t) val; + break; + } + default: + goto bad_argnum; + } + return; + +bad_argnum: + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "cannot access arg(%lld)", THIS->argnum); + CONTEXT->last_error = CONTEXT->error_buffer; + return; + + if (0) { +deref_fault: /* branched to from deref() */ + snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "kernel fault at %#lx accessing arg(%lld)", val, + THIS->argnum); + CONTEXT->last_error = CONTEXT->error_buffer; + } +%} + +/* Return the value of function arg #argnum as a signed int. */ +function int_arg:long (argnum:long) { + return _stp_arg(argnum) +} + +/* Return the value of function arg #argnum as an unsigned int. */ +function uint_arg:long (argnum:long) { + return _stp_arg(argnum) & 0xffffffff; +} + +function long_arg:long (argnum:long) { + return int_arg(argnum) +} + +function ulong_arg:long (argnum:long) { + return uint_arg(argnum) +} + +function longlong_arg:long (argnum:long) { + /* + * TODO: If argnum == nr_regarg, gcc puts the whole 64-bit arg + * on the stack. + */ + lowbits = uint_arg(argnum) + highbits = uint_arg(argnum+1) + return ((highbits << 32) | lowbits) +} + +function ulonglong_arg:long (argnum:long) { + return longlong_arg(argnum) +} + +function pointer_arg:long (argnum:long) { + return ulong_arg(argnum) +} + +function s32_arg:long (argnum:long) { + return int_arg(argnum) +} + +function u32_arg:long (argnum:long) { + return uint_arg(argnum) +} + +function s64_arg:long (argnum:long) { + return longlong_arg(argnum) +} + +function u64_arg:long (argnum:long) { + return ulonglong_arg(argnum) +} + +function asmlinkage() %{ + CONTEXT->regparm = _STP_REGPARM | 0; +%} + +function fastcall() %{ + CONTEXT->regparm = _STP_REGPARM | 3; +%} + +function regparm(n:long) %{ + if (THIS->n < 0 || THIS->n > 3) { + snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), + "For i386, regparm value must be in the range 0-3."); + CONTEXT->last_error = CONTEXT->error_buffer; + } else + CONTEXT->regparm = _STP_REGPARM | (int) THIS->n; +%} diff --git a/tapset/i386/syscalls.stp b/tapset/i386/syscalls.stp new file mode 100644 index 00000000..dec0aa97 --- /dev/null +++ b/tapset/i386/syscalls.stp @@ -0,0 +1,174 @@ +# 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 syscall.get_thread_area = kernel.function("sys_get_thread_area") +{ + name = "get_thread_area" + u_info_uaddr = $u_info + argstr = sprintf("%p", u_info_uaddr) +} +probe syscall.get_thread_area.return = kernel.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 syscall.iopl = kernel.function("sys_iopl") +{ + name = "iopl" + argstr = "" +} +probe syscall.iopl.return = kernel.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 syscall.ipc = kernel.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) +} +probe syscall.ipc.return = kernel.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 syscall.mmap2 = kernel.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) +} +probe syscall.mmap2.return = kernel.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 syscall.set_thread_area = kernel.function("sys_set_thread_area") +{ + name = "set_thread_area" + u_info_uaddr = $u_info + argstr = sprintf("%p", u_info_uaddr) +} +probe syscall.set_thread_area.return = kernel.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 syscall.set_zone_reclaim = kernel.function("sys_set_zone_reclaim") ? +{ + name = "set_zone_reclaim" + node = $node + zone = $zone + state = $state + argstr = sprintf("%d, %d, %d", $node, $zone, $state) +} +probe syscall.set_zone_reclaim.return = kernel.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 syscall.sigaltstack = kernel.function("sys_sigaltstack") +{ + name = "sigaltstack" + ussp = %( kernel_vr < "2.6.25" %? $ebx %: %( kernel_vr < "2.6.29" %? $bx %: $regs->bx %) %) + argstr = sprintf("%p", ussp) +} +probe syscall.sigaltstack.return = kernel.function("sys_sigaltstack").return +{ + name = "sigaltstack" + retstr = returnstr(1) +} + +# vm86 _______________________________________________________ +# +# int sys_vm86(struct pt_regs regs) +# +probe syscall.vm86 = kernel.function("sys_vm86") ? +{ + name = "vm86" + /* + * unsupported type identifier '$regs' + * regs = $regs + */ + argstr = "" +} +probe syscall.vm86.return = kernel.function("sys_vm86").return ? +{ + name = "vm86" + retstr = returnstr(1) +} + +# vm86old ____________________________________________________ +# +# int sys_vm86old(struct pt_regs regs) +# +probe syscall.vm86old = kernel.function("sys_vm86old") ? +{ + name = "vm86old" + /* + * unsupported type identifier '$regs' + * regs = $regs + */ + argstr = "" +} +probe syscall.vm86old.return = kernel.function("sys_vm86old").return ? +{ + name = "vm86old" + retstr = returnstr(1) +} + diff --git a/tapset/i686/nd_syscalls.stp b/tapset/i686/nd_syscalls.stp deleted file mode 100644 index f19e54a9..00000000 --- a/tapset/i686/nd_syscalls.stp +++ /dev/null @@ -1,205 +0,0 @@ -# 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/i686/registers.stp b/tapset/i686/registers.stp deleted file mode 100644 index 997376dc..00000000 --- a/tapset/i686/registers.stp +++ /dev/null @@ -1,232 +0,0 @@ -global _reg_offsets, _stp_regs_registered, _sp_offset, _ss_offset - -function test_x86_gs:long() %{ /* pure */ -#ifdef STAPCONF_X86_GS - THIS->__retvalue = 1; -#else - THIS->__retvalue = 0; -#endif -%} - -function _stp_register_regs() { - - /* Same order as pt_regs */ - _reg_offsets["ebx"] = 0 _reg_offsets["bx"] = 0 - _reg_offsets["ecx"] = 4 _reg_offsets["cx"] = 4 - _reg_offsets["edx"] = 8 _reg_offsets["dx"] = 8 - _reg_offsets["esi"] = 12 _reg_offsets["si"] = 12 - _reg_offsets["edi"] = 16 _reg_offsets["di"] = 16 - _reg_offsets["ebp"] = 20 _reg_offsets["bp"] = 20 - _reg_offsets["eax"] = 24 _reg_offsets["ax"] = 24 - _reg_offsets["xds"] = 28 _reg_offsets["ds"] = 28 - _reg_offsets["xes"] = 32 _reg_offsets["es"] = 32 - _reg_offsets["xfs"] = 36 _reg_offsets["fs"] = 36 - gs_incr = 0 -if (test_x86_gs()) { - gs_incr = 4 - _reg_offsets["xgs"] = 40 _reg_offsets["gs"] = 40 -} - _reg_offsets["orig_eax"] = 40 + gs_incr _reg_offsets["orig_ax"] = 40 + gs_incr - _reg_offsets["eip"] = 44 + gs_incr _reg_offsets["ip"] = 44 + gs_incr - _reg_offsets["xcs"] = 48 + gs_incr _reg_offsets["cs"] = 48 + gs_incr - _reg_offsets["eflags"] = 52 + gs_incr _reg_offsets["flags"] = 52 + gs_incr - _reg_offsets["esp"] = 56 + gs_incr _reg_offsets["sp"] = 56 + gs_incr - _reg_offsets["xss"] = 60 + gs_incr _reg_offsets["ss"] = 60 + gs_incr - _sp_offset = 56 + gs_incr - _ss_offset = 60 + gs_incr - - _stp_regs_registered = 1 -} - -function _stp_get_register_by_offset:long (offset:long) %{ /* pure */ - long value; - if (!CONTEXT->regs) { - CONTEXT->last_error = "No registers available in this context"; - return; - } - if (THIS->offset < 0 || THIS->offset > sizeof(struct pt_regs) - sizeof(long)) { - snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), - "Bad register offset: %lld", THIS->offset); - CONTEXT->last_error = CONTEXT->error_buffer; - return; - } - memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); - THIS->__retvalue = value; -%} - -function _stp_probing_kernel:long () %{ /* pure */ - THIS->__retvalue = !user_mode(CONTEXT->regs); -%} - -/* - * esp and ss aren't saved on a breakpoint in kernel mode, so - * the pre-trap stack pointer is ®s->sp. - */ -function _stp_kernel_sp:long (sp_offset:long) %{ /* pure */ - THIS->__retvalue = ((long) CONTEXT->regs) + THIS->sp_offset; -%} - -/* Assume ss register hasn't changed since we took the trap. */ -function _stp_kernel_ss:long () %{ /* pure */ - unsigned short ss; - asm volatile("movw %%ss, %0" : : "m" (ss)); - THIS->__retvalue = ss; -%} - -/* Return the named register value as a signed value. */ -function register:long (name:string) { - if (!registers_valid()) { - error("cannot access CPU registers in this context") - return 0 - } - if (!_stp_regs_registered) - _stp_register_regs() - offset = _reg_offsets[name] - if (offset == 0 && !(name in _reg_offsets)) { - error("Unknown register: " . name) - return 0 - } - if (_stp_probing_kernel()) { - if (offset == _sp_offset) - return _stp_kernel_sp(_sp_offset) - else if (offset == _ss_offset) - return _stp_kernel_ss() - } - return _stp_get_register_by_offset(offset) -} - -/* - * Return the named register value as an unsigned value. Specifically, - * don't sign-extend the register value when promoting it to 64 bits. - */ -function u_register:long (name:string) { - return register(name) & 0xffffffff; -} - -/* Return the value of function arg #argnum (1=first arg) as a signed value. */ -function _stp_arg:long (argnum:long) %{ /* pure */ - long val; - int n, nr_regargs, result; - - THIS->__retvalue = 0; - if (!CONTEXT->regs) { - snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), - "cannot access function args in this context"); - CONTEXT->last_error = CONTEXT->error_buffer; - return; - } - if (THIS->argnum < 1) - goto bad_argnum; - n = (int) THIS->argnum; - nr_regargs = _stp_get_regparm(CONTEXT->regparm, CONTEXT->regs); - result = _stp_get_arg32_by_number(n, nr_regargs, CONTEXT->regs, &val); - switch (result) { - case 0: - /* Arg is in register. */ - THIS->__retvalue = (int64_t) val; - break; - case 1: - /* Arg is on kernel stack. */ - THIS->__retvalue = kread((long *) val); - break; - case 2: - { - /* Arg is on user stack. */ - const char __user *vaddr = (const char __user*) val; - if (_stp_copy_from_user((char*)&val, vaddr, sizeof(val)) != 0) { - /* Stack page not resident. */ - _stp_warn("cannot access arg(%d) " - "at user stack address %p\n", n, vaddr); - THIS->__retvalue = 0; - } else - THIS->__retvalue = (int64_t) val; - break; - } - default: - goto bad_argnum; - } - return; - -bad_argnum: - snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), - "cannot access arg(%lld)", THIS->argnum); - CONTEXT->last_error = CONTEXT->error_buffer; - return; - - if (0) { -deref_fault: /* branched to from deref() */ - snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), - "kernel fault at %#lx accessing arg(%lld)", val, - THIS->argnum); - CONTEXT->last_error = CONTEXT->error_buffer; - } -%} - -/* Return the value of function arg #argnum as a signed int. */ -function int_arg:long (argnum:long) { - return _stp_arg(argnum) -} - -/* Return the value of function arg #argnum as an unsigned int. */ -function uint_arg:long (argnum:long) { - return _stp_arg(argnum) & 0xffffffff; -} - -function long_arg:long (argnum:long) { - return int_arg(argnum) -} - -function ulong_arg:long (argnum:long) { - return uint_arg(argnum) -} - -function longlong_arg:long (argnum:long) { - /* - * TODO: If argnum == nr_regarg, gcc puts the whole 64-bit arg - * on the stack. - */ - lowbits = uint_arg(argnum) - highbits = uint_arg(argnum+1) - return ((highbits << 32) | lowbits) -} - -function ulonglong_arg:long (argnum:long) { - return longlong_arg(argnum) -} - -function pointer_arg:long (argnum:long) { - return ulong_arg(argnum) -} - -function s32_arg:long (argnum:long) { - return int_arg(argnum) -} - -function u32_arg:long (argnum:long) { - return uint_arg(argnum) -} - -function s64_arg:long (argnum:long) { - return longlong_arg(argnum) -} - -function u64_arg:long (argnum:long) { - return ulonglong_arg(argnum) -} - -function asmlinkage() %{ - CONTEXT->regparm = _STP_REGPARM | 0; -%} - -function fastcall() %{ - CONTEXT->regparm = _STP_REGPARM | 3; -%} - -function regparm(n:long) %{ - if (THIS->n < 0 || THIS->n > 3) { - snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer), - "For i386, regparm value must be in the range 0-3."); - CONTEXT->last_error = CONTEXT->error_buffer; - } else - CONTEXT->regparm = _STP_REGPARM | (int) THIS->n; -%} diff --git a/tapset/i686/syscalls.stp b/tapset/i686/syscalls.stp deleted file mode 100644 index dec0aa97..00000000 --- a/tapset/i686/syscalls.stp +++ /dev/null @@ -1,174 +0,0 @@ -# 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 syscall.get_thread_area = kernel.function("sys_get_thread_area") -{ - name = "get_thread_area" - u_info_uaddr = $u_info - argstr = sprintf("%p", u_info_uaddr) -} -probe syscall.get_thread_area.return = kernel.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 syscall.iopl = kernel.function("sys_iopl") -{ - name = "iopl" - argstr = "" -} -probe syscall.iopl.return = kernel.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 syscall.ipc = kernel.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) -} -probe syscall.ipc.return = kernel.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 syscall.mmap2 = kernel.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) -} -probe syscall.mmap2.return = kernel.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 syscall.set_thread_area = kernel.function("sys_set_thread_area") -{ - name = "set_thread_area" - u_info_uaddr = $u_info - argstr = sprintf("%p", u_info_uaddr) -} -probe syscall.set_thread_area.return = kernel.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 syscall.set_zone_reclaim = kernel.function("sys_set_zone_reclaim") ? -{ - name = "set_zone_reclaim" - node = $node - zone = $zone - state = $state - argstr = sprintf("%d, %d, %d", $node, $zone, $state) -} -probe syscall.set_zone_reclaim.return = kernel.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 syscall.sigaltstack = kernel.function("sys_sigaltstack") -{ - name = "sigaltstack" - ussp = %( kernel_vr < "2.6.25" %? $ebx %: %( kernel_vr < "2.6.29" %? $bx %: $regs->bx %) %) - argstr = sprintf("%p", ussp) -} -probe syscall.sigaltstack.return = kernel.function("sys_sigaltstack").return -{ - name = "sigaltstack" - retstr = returnstr(1) -} - -# vm86 _______________________________________________________ -# -# int sys_vm86(struct pt_regs regs) -# -probe syscall.vm86 = kernel.function("sys_vm86") ? -{ - name = "vm86" - /* - * unsupported type identifier '$regs' - * regs = $regs - */ - argstr = "" -} -probe syscall.vm86.return = kernel.function("sys_vm86").return ? -{ - name = "vm86" - retstr = returnstr(1) -} - -# vm86old ____________________________________________________ -# -# int sys_vm86old(struct pt_regs regs) -# -probe syscall.vm86old = kernel.function("sys_vm86old") ? -{ - name = "vm86old" - /* - * unsupported type identifier '$regs' - * regs = $regs - */ - argstr = "" -} -probe syscall.vm86old.return = kernel.function("sys_vm86old").return ? -{ - name = "vm86old" - retstr = returnstr(1) -} - -- cgit