| 
									
										
										
										
											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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 01:27:00 -07:00
										 |  |  | #include "linux/kernel.h"
 | 
					
						
							| 
									
										
										
										
											2005-09-03 15:57:42 -07:00
										 |  |  | #include "linux/ptrace.h"
 | 
					
						
							|  |  |  | #include "kern_util.h"
 | 
					
						
							| 
									
										
										
										
											2007-10-16 01:27:00 -07:00
										 |  |  | #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; | 
					
						
							|  |  |  | #define NR_syscalls (syscall_table_size / sizeof(void *))
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	syscall_trace(r, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							| 
									
										
										
										
											2007-10-16 01:27:00 -07:00
										 |  |  | 	if ((syscall >= NR_syscalls) || (syscall < 0)) | 
					
						
							| 
									
										
										
										
											2005-09-03 15:57:42 -07:00
										 |  |  | 		result = -ENOSYS; | 
					
						
							|  |  |  | 	else result = EXECUTE_SYSCALL(syscall, regs); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 01:27:07 -07:00
										 |  |  | 	REGS_SET_SYSCALL_RETURN(r->gp, result); | 
					
						
							| 
									
										
										
										
											2005-09-03 15:57:42 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	syscall_trace(r, 1); | 
					
						
							|  |  |  | } |