Back to home page

LXR

 
 

    


0001 #include <linux/ptrace.h>
0002 #include <linux/sched.h>
0003 #include <linux/export.h>
0004 #include <asm/syscall.h>
0005 
0006 static int collect_syscall(struct task_struct *target, long *callno,
0007                unsigned long args[6], unsigned int maxargs,
0008                unsigned long *sp, unsigned long *pc)
0009 {
0010     struct pt_regs *regs;
0011 
0012     if (!try_get_task_stack(target)) {
0013         /* Task has no stack, so the task isn't in a syscall. */
0014         *callno = -1;
0015         return 0;
0016     }
0017 
0018     regs = task_pt_regs(target);
0019     if (unlikely(!regs)) {
0020         put_task_stack(target);
0021         return -EAGAIN;
0022     }
0023 
0024     *sp = user_stack_pointer(regs);
0025     *pc = instruction_pointer(regs);
0026 
0027     *callno = syscall_get_nr(target, regs);
0028     if (*callno != -1L && maxargs > 0)
0029         syscall_get_arguments(target, regs, 0, maxargs, args);
0030 
0031     put_task_stack(target);
0032     return 0;
0033 }
0034 
0035 /**
0036  * task_current_syscall - Discover what a blocked task is doing.
0037  * @target:     thread to examine
0038  * @callno:     filled with system call number or -1
0039  * @args:       filled with @maxargs system call arguments
0040  * @maxargs:        number of elements in @args to fill
0041  * @sp:         filled with user stack pointer
0042  * @pc:         filled with user PC
0043  *
0044  * If @target is blocked in a system call, returns zero with *@callno
0045  * set to the the call's number and @args filled in with its arguments.
0046  * Registers not used for system call arguments may not be available and
0047  * it is not kosher to use &struct user_regset calls while the system
0048  * call is still in progress.  Note we may get this result if @target
0049  * has finished its system call but not yet returned to user mode, such
0050  * as when it's stopped for signal handling or syscall exit tracing.
0051  *
0052  * If @target is blocked in the kernel during a fault or exception,
0053  * returns zero with *@callno set to -1 and does not fill in @args.
0054  * If so, it's now safe to examine @target using &struct user_regset
0055  * get() calls as long as we're sure @target won't return to user mode.
0056  *
0057  * Returns -%EAGAIN if @target does not remain blocked.
0058  *
0059  * Returns -%EINVAL if @maxargs is too large (maximum is six).
0060  */
0061 int task_current_syscall(struct task_struct *target, long *callno,
0062              unsigned long args[6], unsigned int maxargs,
0063              unsigned long *sp, unsigned long *pc)
0064 {
0065     long state;
0066     unsigned long ncsw;
0067 
0068     if (unlikely(maxargs > 6))
0069         return -EINVAL;
0070 
0071     if (target == current)
0072         return collect_syscall(target, callno, args, maxargs, sp, pc);
0073 
0074     state = target->state;
0075     if (unlikely(!state))
0076         return -EAGAIN;
0077 
0078     ncsw = wait_task_inactive(target, state);
0079     if (unlikely(!ncsw) ||
0080         unlikely(collect_syscall(target, callno, args, maxargs, sp, pc)) ||
0081         unlikely(wait_task_inactive(target, state) != ncsw))
0082         return -EAGAIN;
0083 
0084     return 0;
0085 }