# 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 = return_str(1, $return)
}
# 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 = return_str(1, $return)
}

# 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 = return_str(1, $return)
}


# In kernels < 2.6.33, mmap()/mmap2() was handled by arch-specific
# code.  In kernels >= 2.6.33, the arch-specific code just calls
# generic sys_mmap_pgoff().
%( kernel_v < "2.6.33" %?
# mmap2 ____________________________________________
# sys_mmap2(unsigned long addr, unsigned long len,
#	  unsigned long prot, unsigned long flags,
#	  unsigned long fd, unsigned long pgoff)
#
probe syscall.mmap2 = __syscall.mmap2 ?, __syscall.mmap_pgoff ?
{
        name = "mmap2"
        start = $addr
        length = $len
        prot = $prot
        flags = $flags
	# Although the kernel gets an unsigned long fd, on the
	# user-side it is a signed int.  Fix this.
        fd = __int32($fd)
        argstr = sprintf("%p, %d, %s, %s, %d, %d", $addr,
                $len, _mprotect_prot_str($prot), _mmap_flags($flags),
                __int32($fd), pgoffset)
}
probe __syscall.mmap2 = kernel.function("sys_mmap2")
{
        pgoffset = $pgoff
}
probe __syscall.mmap_pgoff = kernel.function("sys_mmap_pgoff")
{
        pgoffset = $pgoff * %{ PAGE_SIZE %}
}
probe syscall.mmap2.return = kernel.function("sys_mmap2").return ?,
	kernel.function("sys_mmap_pgoff").return ?
{
        name = "mmap2"
        retstr = return_str(2, $return)
}
%)

# 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 = return_str(1, $return)
}
# 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 = return_str(1, $return)
}

%( CONFIG_GENERIC_SIGALTSTACK == "n" || kernel_v < "3.8" %?
# sigaltstack ________________________________________________
# int sys_sigaltstack(unsigned long ebx)
#
# NOTE: args vary between archs.
#
probe syscall.sigaltstack = kernel.function("sys_sigaltstack")
{
	name = "sigaltstack"
# 'ussp' should have been 'uss_uaddr.  Deprecate the old name.
%(systemtap_v <= "1.4" %?
	ussp = %( kernel_vr < "2.6.25" %? $ebx %: %( kernel_vr < "2.6.30" %? $bx %: $regs->bx %) %)
%)
	if (@defined($regs)) {
		uss_uaddr = @choose_defined($uss, $regs->bx)
		uoss_uaddr = @choose_defined($uoss, $regs->cx)
%(systemtap_v < "2.3" %?
		regs = $regs
%)
	}
	else if (@defined($bx)) {	# kernels < "2.6.30"
		uss_uaddr = $bx
		# Make sure the register value didn't get sign extended.
		uoss_uaddr = __ulong(@cast(&$bx, "pt_regs", "kernel<asm/ptrace.h>")->cx)
%(systemtap_v < "2.3" %?
		regs = &$bx
%)
	}
	else {				# kernels < "2.6.25"
		uss_uaddr = $ebx
		# Make sure the register value didn't get sign extended.
		uoss_uaddr = __ulong(@cast(&$ebx, "pt_regs", "kernel<asm/ptrace.h>")->ecx)
%(systemtap_v < "2.3" %?
		regs = &$ebx
%)
	}
	argstr = sprintf("%p, %p", uss_uaddr, uoss_uaddr)
}
probe syscall.sigaltstack.return = kernel.function("sys_sigaltstack").return
{
	name = "sigaltstack"
	retstr = return_str(1, $return)
}
%)

# 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 = return_str(1, $return)
}

# 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 = return_str(1, $return)
}

