2005-09-03 15:57:42 -07:00
/*
2007-10-16 01:27:00 -07:00
* Copyright ( C ) 2002 - 2007 Jeff Dike ( jdike @ { addtoit , linux . intel } . com )
2005-09-03 15:57:42 -07:00
* Licensed under the GPL
*/
2012-10-08 03:27:32 +01:00
# include <linux/kernel.h>
# include <linux/ptrace.h>
# include <kern_util.h>
# include <sysdep/ptrace.h>
# include <sysdep/syscalls.h>
2005-09-03 15:57:42 -07:00
2008-02-04 22:31:29 -08:00
extern int syscall_table_size ;
2010-04-19 23:53:07 +02:00
# define NR_SYSCALLS (syscall_table_size / sizeof(void *))
2008-02-04 22:31:29 -08:00
2007-10-16 01:26:58 -07:00
void handle_syscall ( struct uml_pt_regs * r )
2005-09-03 15:57:42 -07:00
{
struct pt_regs * regs = container_of ( r , struct pt_regs , regs ) ;
long result ;
int syscall ;
2012-05-23 00:18:33 -04:00
syscall_trace_enter ( regs ) ;
2005-09-03 15:57:42 -07:00
2007-10-16 01:27:00 -07:00
/*
* This should go in the declaration of syscall , but when I do that ,
2005-09-03 15:57:42 -07:00
* strace - f - c bash - c ' ls ; ls ' breaks , sometimes not tracing
* children at all , sometimes hanging when bash doesn ' t see the first
* ls exit .
* The assembly looks functionally the same to me . This is
* gcc version 4.0 .1 20050727 ( Red Hat 4.0 .1 - 5 )
* in case it ' s a compiler bug .
*/
syscall = UPT_SYSCALL_NR ( r ) ;
2010-04-19 23:53:07 +02:00
if ( ( syscall > = NR_SYSCALLS ) | | ( syscall < 0 ) )
2005-09-03 15:57:42 -07:00
result = - ENOSYS ;
else result = EXECUTE_SYSCALL ( syscall , regs ) ;
2012-05-22 21:16:35 -04:00
PT_REGS_SET_SYSCALL_RETURN ( regs , result ) ;
2005-09-03 15:57:42 -07:00
2012-05-23 00:18:33 -04:00
syscall_trace_leave ( regs ) ;
2005-09-03 15:57:42 -07:00
}