| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* ptrace.c: FRV specific parts of process tracing | 
 | 2 |  * | 
 | 3 |  * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved. | 
 | 4 |  * Written by David Howells (dhowells@redhat.com) | 
 | 5 |  * - Derived from arch/m68k/kernel/ptrace.c | 
 | 6 |  * | 
 | 7 |  * This program is free software; you can redistribute it and/or | 
 | 8 |  * modify it under the terms of the GNU General Public License | 
 | 9 |  * as published by the Free Software Foundation; either version | 
 | 10 |  * 2 of the License, or (at your option) any later version. | 
 | 11 |  */ | 
 | 12 |  | 
 | 13 | #include <linux/kernel.h> | 
 | 14 | #include <linux/sched.h> | 
 | 15 | #include <linux/mm.h> | 
 | 16 | #include <linux/smp.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 | #include <linux/errno.h> | 
 | 18 | #include <linux/ptrace.h> | 
 | 19 | #include <linux/user.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 | #include <linux/security.h> | 
| Jesper Juhl | 7ed20e1 | 2005-05-01 08:59:14 -0700 | [diff] [blame] | 21 | #include <linux/signal.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 22 |  | 
 | 23 | #include <asm/uaccess.h> | 
 | 24 | #include <asm/page.h> | 
 | 25 | #include <asm/pgtable.h> | 
 | 26 | #include <asm/system.h> | 
 | 27 | #include <asm/processor.h> | 
 | 28 | #include <asm/unistd.h> | 
 | 29 |  | 
 | 30 | /* | 
 | 31 |  * does not yet catch signals sent when the child dies. | 
 | 32 |  * in exit.c or in signal.c. | 
 | 33 |  */ | 
 | 34 |  | 
 | 35 | /* | 
 | 36 |  * Get contents of register REGNO in task TASK. | 
 | 37 |  */ | 
 | 38 | static inline long get_reg(struct task_struct *task, int regno) | 
 | 39 | { | 
 | 40 | 	struct user_context *user = task->thread.user; | 
 | 41 |  | 
 | 42 | 	if (regno < 0 || regno >= PT__END) | 
 | 43 | 		return 0; | 
 | 44 |  | 
 | 45 | 	return ((unsigned long *) user)[regno]; | 
 | 46 | } | 
 | 47 |  | 
 | 48 | /* | 
 | 49 |  * Write contents of register REGNO in task TASK. | 
 | 50 |  */ | 
 | 51 | static inline int put_reg(struct task_struct *task, int regno, | 
 | 52 | 			  unsigned long data) | 
 | 53 | { | 
 | 54 | 	struct user_context *user = task->thread.user; | 
 | 55 |  | 
 | 56 | 	if (regno < 0 || regno >= PT__END) | 
 | 57 | 		return -EIO; | 
 | 58 |  | 
 | 59 | 	switch (regno) { | 
 | 60 | 	case PT_GR(0): | 
 | 61 | 		return 0; | 
 | 62 | 	case PT_PSR: | 
 | 63 | 	case PT__STATUS: | 
 | 64 | 		return -EIO; | 
 | 65 | 	default: | 
 | 66 | 		((unsigned long *) user)[regno] = data; | 
 | 67 | 		return 0; | 
 | 68 | 	} | 
 | 69 | } | 
 | 70 |  | 
 | 71 | /* | 
 | 72 |  * check that an address falls within the bounds of the target process's memory mappings | 
 | 73 |  */ | 
 | 74 | static inline int is_user_addr_valid(struct task_struct *child, | 
 | 75 | 				     unsigned long start, unsigned long len) | 
 | 76 | { | 
 | 77 | #ifdef CONFIG_MMU | 
 | 78 | 	if (start >= PAGE_OFFSET || len > PAGE_OFFSET - start) | 
 | 79 | 		return -EIO; | 
 | 80 | 	return 0; | 
 | 81 | #else | 
 | 82 | 	struct vm_list_struct *vml; | 
 | 83 |  | 
 | 84 | 	for (vml = child->mm->context.vmlist; vml; vml = vml->next) | 
 | 85 | 		if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end) | 
 | 86 | 			return 0; | 
 | 87 |  | 
 | 88 | 	return -EIO; | 
 | 89 | #endif | 
 | 90 | } | 
 | 91 |  | 
 | 92 | /* | 
 | 93 |  * Called by kernel/ptrace.c when detaching.. | 
 | 94 |  * | 
 | 95 |  * Control h/w single stepping | 
 | 96 |  */ | 
 | 97 | void ptrace_disable(struct task_struct *child) | 
 | 98 | { | 
 | 99 | 	child->thread.frame0->__status &= ~REG__STATUS_STEP; | 
 | 100 | } | 
 | 101 |  | 
 | 102 | void ptrace_enable(struct task_struct *child) | 
 | 103 | { | 
 | 104 | 	child->thread.frame0->__status |= REG__STATUS_STEP; | 
 | 105 | } | 
 | 106 |  | 
| Christoph Hellwig | 481bed4 | 2005-11-07 00:59:47 -0800 | [diff] [blame] | 107 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 108 | { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 109 | 	unsigned long tmp; | 
 | 110 | 	int ret; | 
 | 111 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 112 | 	switch (request) { | 
 | 113 | 		/* when I and D space are separate, these will need to be fixed. */ | 
 | 114 | 	case PTRACE_PEEKTEXT: /* read word at location addr. */ | 
| Alexey Dobriyan | 7664732 | 2007-07-17 04:03:43 -0700 | [diff] [blame] | 115 | 	case PTRACE_PEEKDATA: | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 116 | 		ret = -EIO; | 
 | 117 | 		if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) | 
 | 118 | 			break; | 
| Alexey Dobriyan | 7664732 | 2007-07-17 04:03:43 -0700 | [diff] [blame] | 119 | 		ret = generic_ptrace_peekdata(child, addr, data); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 120 | 		break; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 |  | 
 | 122 | 		/* read the word at location addr in the USER area. */ | 
 | 123 | 	case PTRACE_PEEKUSR: { | 
 | 124 | 		tmp = 0; | 
 | 125 | 		ret = -EIO; | 
 | 126 | 		if ((addr & 3) || addr < 0) | 
 | 127 | 			break; | 
 | 128 |  | 
 | 129 | 		ret = 0; | 
 | 130 | 		switch (addr >> 2) { | 
 | 131 | 		case 0 ... PT__END - 1: | 
 | 132 | 			tmp = get_reg(child, addr >> 2); | 
 | 133 | 			break; | 
 | 134 |  | 
 | 135 | 		case PT__END + 0: | 
 | 136 | 			tmp = child->mm->end_code - child->mm->start_code; | 
 | 137 | 			break; | 
 | 138 |  | 
 | 139 | 		case PT__END + 1: | 
 | 140 | 			tmp = child->mm->end_data - child->mm->start_data; | 
 | 141 | 			break; | 
 | 142 |  | 
 | 143 | 		case PT__END + 2: | 
 | 144 | 			tmp = child->mm->start_stack - child->mm->start_brk; | 
 | 145 | 			break; | 
 | 146 |  | 
 | 147 | 		case PT__END + 3: | 
 | 148 | 			tmp = child->mm->start_code; | 
 | 149 | 			break; | 
 | 150 |  | 
 | 151 | 		case PT__END + 4: | 
 | 152 | 			tmp = child->mm->start_stack; | 
 | 153 | 			break; | 
 | 154 |  | 
 | 155 | 		default: | 
 | 156 | 			ret = -EIO; | 
 | 157 | 			break; | 
 | 158 | 		} | 
 | 159 |  | 
 | 160 | 		if (ret == 0) | 
 | 161 | 			ret = put_user(tmp, (unsigned long *) data); | 
 | 162 | 		break; | 
 | 163 | 	} | 
 | 164 |  | 
 | 165 | 		/* when I and D space are separate, this will have to be fixed. */ | 
 | 166 | 	case PTRACE_POKETEXT: /* write the word at location addr. */ | 
 | 167 | 	case PTRACE_POKEDATA: | 
 | 168 | 		ret = -EIO; | 
 | 169 | 		if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) | 
 | 170 | 			break; | 
| Alexey Dobriyan | f284ce7 | 2007-07-17 04:03:44 -0700 | [diff] [blame] | 171 | 		ret = generic_ptrace_pokedata(child, addr, data); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 172 | 		break; | 
 | 173 |  | 
 | 174 | 	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 
 | 175 | 		ret = -EIO; | 
 | 176 | 		if ((addr & 3) || addr < 0) | 
 | 177 | 			break; | 
 | 178 |  | 
 | 179 | 		ret = 0; | 
 | 180 | 		switch (addr >> 2) { | 
 | 181 | 		case 0 ... PT__END-1: | 
 | 182 | 			ret = put_reg(child, addr >> 2, data); | 
 | 183 | 			break; | 
 | 184 |  | 
 | 185 | 		default: | 
 | 186 | 			ret = -EIO; | 
 | 187 | 			break; | 
 | 188 | 		} | 
 | 189 | 		break; | 
 | 190 |  | 
 | 191 | 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 
 | 192 | 	case PTRACE_CONT: /* restart after signal. */ | 
 | 193 | 		ret = -EIO; | 
| Jesper Juhl | 7ed20e1 | 2005-05-01 08:59:14 -0700 | [diff] [blame] | 194 | 		if (!valid_signal(data)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 195 | 			break; | 
 | 196 | 		if (request == PTRACE_SYSCALL) | 
 | 197 | 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 
 | 198 | 		else | 
 | 199 | 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 
 | 200 | 		child->exit_code = data; | 
 | 201 | 		ptrace_disable(child); | 
 | 202 | 		wake_up_process(child); | 
 | 203 | 		ret = 0; | 
 | 204 | 		break; | 
 | 205 |  | 
 | 206 | 		/* make the child exit.  Best I can do is send it a sigkill. | 
 | 207 | 		 * perhaps it should be put in the status that it wants to | 
 | 208 | 		 * exit. | 
 | 209 | 		 */ | 
 | 210 | 	case PTRACE_KILL: | 
 | 211 | 		ret = 0; | 
 | 212 | 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */ | 
 | 213 | 			break; | 
 | 214 | 		child->exit_code = SIGKILL; | 
 | 215 | 		clear_tsk_thread_flag(child, TIF_SINGLESTEP); | 
 | 216 | 		ptrace_disable(child); | 
 | 217 | 		wake_up_process(child); | 
 | 218 | 		break; | 
 | 219 |  | 
 | 220 | 	case PTRACE_SINGLESTEP:  /* set the trap flag. */ | 
 | 221 | 		ret = -EIO; | 
| Jesper Juhl | 7ed20e1 | 2005-05-01 08:59:14 -0700 | [diff] [blame] | 222 | 		if (!valid_signal(data)) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 223 | 			break; | 
 | 224 | 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 
 | 225 | 		ptrace_enable(child); | 
 | 226 | 		child->exit_code = data; | 
 | 227 | 		wake_up_process(child); | 
 | 228 | 		ret = 0; | 
 | 229 | 		break; | 
 | 230 |  | 
 | 231 | 	case PTRACE_DETACH:	/* detach a process that was attached. */ | 
 | 232 | 		ret = ptrace_detach(child, data); | 
 | 233 | 		break; | 
 | 234 |  | 
 | 235 | 	case PTRACE_GETREGS: { /* Get all integer regs from the child. */ | 
 | 236 | 		int i; | 
 | 237 | 		for (i = 0; i < PT__GPEND; i++) { | 
 | 238 | 			tmp = get_reg(child, i); | 
 | 239 | 			if (put_user(tmp, (unsigned long *) data)) { | 
 | 240 | 				ret = -EFAULT; | 
 | 241 | 				break; | 
 | 242 | 			} | 
 | 243 | 			data += sizeof(long); | 
 | 244 | 		} | 
 | 245 | 		ret = 0; | 
 | 246 | 		break; | 
 | 247 | 	} | 
 | 248 |  | 
 | 249 | 	case PTRACE_SETREGS: { /* Set all integer regs in the child. */ | 
 | 250 | 		int i; | 
 | 251 | 		for (i = 0; i < PT__GPEND; i++) { | 
 | 252 | 			if (get_user(tmp, (unsigned long *) data)) { | 
 | 253 | 				ret = -EFAULT; | 
 | 254 | 				break; | 
 | 255 | 			} | 
 | 256 | 			put_reg(child, i, tmp); | 
 | 257 | 			data += sizeof(long); | 
 | 258 | 		} | 
 | 259 | 		ret = 0; | 
 | 260 | 		break; | 
 | 261 | 	} | 
 | 262 |  | 
 | 263 | 	case PTRACE_GETFPREGS: { /* Get the child FP/Media state. */ | 
 | 264 | 		ret = 0; | 
 | 265 | 		if (copy_to_user((void *) data, | 
 | 266 | 				 &child->thread.user->f, | 
 | 267 | 				 sizeof(child->thread.user->f))) | 
 | 268 | 			ret = -EFAULT; | 
 | 269 | 		break; | 
 | 270 | 	} | 
 | 271 |  | 
 | 272 | 	case PTRACE_SETFPREGS: { /* Set the child FP/Media state. */ | 
 | 273 | 		ret = 0; | 
 | 274 | 		if (copy_from_user(&child->thread.user->f, | 
 | 275 | 				   (void *) data, | 
 | 276 | 				   sizeof(child->thread.user->f))) | 
 | 277 | 			ret = -EFAULT; | 
 | 278 | 		break; | 
 | 279 | 	} | 
 | 280 |  | 
 | 281 | 	case PTRACE_GETFDPIC: | 
 | 282 | 		tmp = 0; | 
 | 283 | 		switch (addr) { | 
 | 284 | 		case PTRACE_GETFDPIC_EXEC: | 
 | 285 | 			tmp = child->mm->context.exec_fdpic_loadmap; | 
 | 286 | 			break; | 
 | 287 | 		case PTRACE_GETFDPIC_INTERP: | 
 | 288 | 			tmp = child->mm->context.interp_fdpic_loadmap; | 
 | 289 | 			break; | 
 | 290 | 		default: | 
 | 291 | 			break; | 
 | 292 | 		} | 
 | 293 |  | 
 | 294 | 		ret = 0; | 
 | 295 | 		if (put_user(tmp, (unsigned long *) data)) { | 
 | 296 | 			ret = -EFAULT; | 
 | 297 | 			break; | 
 | 298 | 		} | 
 | 299 | 		break; | 
 | 300 |  | 
 | 301 | 	default: | 
 | 302 | 		ret = -EIO; | 
 | 303 | 		break; | 
 | 304 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 305 | 	return ret; | 
 | 306 | } | 
 | 307 |  | 
 | 308 | int __nongprelbss kstrace; | 
 | 309 |  | 
 | 310 | static const struct { | 
 | 311 | 	const char	*name; | 
 | 312 | 	unsigned	argmask; | 
 | 313 | } __syscall_name_table[NR_syscalls] = { | 
 | 314 | 	[0]	= { "restart_syscall"			}, | 
 | 315 | 	[1]	= { "exit",		0x000001	}, | 
 | 316 | 	[2]	= { "fork",		0xffffff	}, | 
 | 317 | 	[3]	= { "read",		0x000141	}, | 
 | 318 | 	[4]	= { "write",		0x000141	}, | 
 | 319 | 	[5]	= { "open",		0x000235	}, | 
 | 320 | 	[6]	= { "close",		0x000001	}, | 
 | 321 | 	[7]	= { "waitpid",		0x000141	}, | 
 | 322 | 	[8]	= { "creat",		0x000025	}, | 
 | 323 | 	[9]	= { "link",		0x000055	}, | 
 | 324 | 	[10]	= { "unlink",		0x000005	}, | 
 | 325 | 	[11]	= { "execve",		0x000445	}, | 
 | 326 | 	[12]	= { "chdir",		0x000005	}, | 
 | 327 | 	[13]	= { "time",		0x000004	}, | 
 | 328 | 	[14]	= { "mknod",		0x000325	}, | 
 | 329 | 	[15]	= { "chmod",		0x000025	}, | 
 | 330 | 	[16]	= { "lchown",		0x000025	}, | 
 | 331 | 	[17]	= { "break" }, | 
 | 332 | 	[18]	= { "oldstat",		0x000045	}, | 
 | 333 | 	[19]	= { "lseek",		0x000131	}, | 
 | 334 | 	[20]	= { "getpid",		0xffffff	}, | 
 | 335 | 	[21]	= { "mount",		0x043555	}, | 
 | 336 | 	[22]	= { "umount",		0x000005	}, | 
 | 337 | 	[23]	= { "setuid",		0x000001	}, | 
 | 338 | 	[24]	= { "getuid",		0xffffff	}, | 
 | 339 | 	[25]	= { "stime",		0x000004	}, | 
 | 340 | 	[26]	= { "ptrace",		0x004413	}, | 
 | 341 | 	[27]	= { "alarm",		0x000001	}, | 
 | 342 | 	[28]	= { "oldfstat",		0x000041	}, | 
 | 343 | 	[29]	= { "pause",		0xffffff	}, | 
 | 344 | 	[30]	= { "utime",		0x000045	}, | 
 | 345 | 	[31]	= { "stty" }, | 
 | 346 | 	[32]	= { "gtty" }, | 
 | 347 | 	[33]	= { "access",		0x000025	}, | 
 | 348 | 	[34]	= { "nice",		0x000001	}, | 
 | 349 | 	[35]	= { "ftime" }, | 
 | 350 | 	[36]	= { "sync",		0xffffff	}, | 
 | 351 | 	[37]	= { "kill",		0x000011	}, | 
 | 352 | 	[38]	= { "rename",		0x000055	}, | 
 | 353 | 	[39]	= { "mkdir",		0x000025	}, | 
 | 354 | 	[40]	= { "rmdir",		0x000005	}, | 
 | 355 | 	[41]	= { "dup",		0x000001	}, | 
 | 356 | 	[42]	= { "pipe",		0x000004	}, | 
 | 357 | 	[43]	= { "times",		0x000004	}, | 
 | 358 | 	[44]	= { "prof" }, | 
 | 359 | 	[45]	= { "brk",		0x000004	}, | 
 | 360 | 	[46]	= { "setgid",		0x000001	}, | 
 | 361 | 	[47]	= { "getgid",		0xffffff	}, | 
 | 362 | 	[48]	= { "signal",		0x000041	}, | 
 | 363 | 	[49]	= { "geteuid",		0xffffff	}, | 
 | 364 | 	[50]	= { "getegid",		0xffffff	}, | 
 | 365 | 	[51]	= { "acct",		0x000005	}, | 
 | 366 | 	[52]	= { "umount2",		0x000035	}, | 
 | 367 | 	[53]	= { "lock" }, | 
 | 368 | 	[54]	= { "ioctl",		0x000331	}, | 
 | 369 | 	[55]	= { "fcntl",		0x000331	}, | 
 | 370 | 	[56]	= { "mpx" }, | 
 | 371 | 	[57]	= { "setpgid",		0x000011	}, | 
 | 372 | 	[58]	= { "ulimit" }, | 
 | 373 | 	[60]	= { "umask",		0x000002	}, | 
 | 374 | 	[61]	= { "chroot",		0x000005	}, | 
 | 375 | 	[62]	= { "ustat",		0x000043	}, | 
 | 376 | 	[63]	= { "dup2",		0x000011	}, | 
 | 377 | 	[64]	= { "getppid",		0xffffff	}, | 
 | 378 | 	[65]	= { "getpgrp",		0xffffff	}, | 
 | 379 | 	[66]	= { "setsid",		0xffffff	}, | 
 | 380 | 	[67]	= { "sigaction" }, | 
 | 381 | 	[68]	= { "sgetmask" }, | 
 | 382 | 	[69]	= { "ssetmask" }, | 
 | 383 | 	[70]	= { "setreuid" }, | 
 | 384 | 	[71]	= { "setregid" }, | 
 | 385 | 	[72]	= { "sigsuspend" }, | 
 | 386 | 	[73]	= { "sigpending" }, | 
 | 387 | 	[74]	= { "sethostname" }, | 
 | 388 | 	[75]	= { "setrlimit" }, | 
 | 389 | 	[76]	= { "getrlimit" }, | 
 | 390 | 	[77]	= { "getrusage" }, | 
 | 391 | 	[78]	= { "gettimeofday" }, | 
 | 392 | 	[79]	= { "settimeofday" }, | 
 | 393 | 	[80]	= { "getgroups" }, | 
 | 394 | 	[81]	= { "setgroups" }, | 
 | 395 | 	[82]	= { "select" }, | 
 | 396 | 	[83]	= { "symlink" }, | 
 | 397 | 	[84]	= { "oldlstat" }, | 
 | 398 | 	[85]	= { "readlink" }, | 
 | 399 | 	[86]	= { "uselib" }, | 
 | 400 | 	[87]	= { "swapon" }, | 
 | 401 | 	[88]	= { "reboot" }, | 
 | 402 | 	[89]	= { "readdir" }, | 
 | 403 | 	[91]	= { "munmap",		0x000034	}, | 
 | 404 | 	[92]	= { "truncate" }, | 
 | 405 | 	[93]	= { "ftruncate" }, | 
 | 406 | 	[94]	= { "fchmod" }, | 
 | 407 | 	[95]	= { "fchown" }, | 
 | 408 | 	[96]	= { "getpriority" }, | 
 | 409 | 	[97]	= { "setpriority" }, | 
 | 410 | 	[99]	= { "statfs" }, | 
 | 411 | 	[100]	= { "fstatfs" }, | 
 | 412 | 	[102]	= { "socketcall" }, | 
 | 413 | 	[103]	= { "syslog" }, | 
 | 414 | 	[104]	= { "setitimer" }, | 
 | 415 | 	[105]	= { "getitimer" }, | 
 | 416 | 	[106]	= { "stat" }, | 
 | 417 | 	[107]	= { "lstat" }, | 
 | 418 | 	[108]	= { "fstat" }, | 
 | 419 | 	[111]	= { "vhangup" }, | 
 | 420 | 	[114]	= { "wait4" }, | 
 | 421 | 	[115]	= { "swapoff" }, | 
 | 422 | 	[116]	= { "sysinfo" }, | 
 | 423 | 	[117]	= { "ipc" }, | 
 | 424 | 	[118]	= { "fsync" }, | 
 | 425 | 	[119]	= { "sigreturn" }, | 
 | 426 | 	[120]	= { "clone" }, | 
 | 427 | 	[121]	= { "setdomainname" }, | 
 | 428 | 	[122]	= { "uname" }, | 
 | 429 | 	[123]	= { "modify_ldt" }, | 
 | 430 | 	[123]	= { "cacheflush" }, | 
 | 431 | 	[124]	= { "adjtimex" }, | 
 | 432 | 	[125]	= { "mprotect" }, | 
 | 433 | 	[126]	= { "sigprocmask" }, | 
 | 434 | 	[127]	= { "create_module" }, | 
 | 435 | 	[128]	= { "init_module" }, | 
 | 436 | 	[129]	= { "delete_module" }, | 
 | 437 | 	[130]	= { "get_kernel_syms" }, | 
 | 438 | 	[131]	= { "quotactl" }, | 
 | 439 | 	[132]	= { "getpgid" }, | 
 | 440 | 	[133]	= { "fchdir" }, | 
 | 441 | 	[134]	= { "bdflush" }, | 
 | 442 | 	[135]	= { "sysfs" }, | 
 | 443 | 	[136]	= { "personality" }, | 
 | 444 | 	[137]	= { "afs_syscall" }, | 
 | 445 | 	[138]	= { "setfsuid" }, | 
 | 446 | 	[139]	= { "setfsgid" }, | 
 | 447 | 	[140]	= { "_llseek",			0x014331	}, | 
 | 448 | 	[141]	= { "getdents" }, | 
 | 449 | 	[142]	= { "_newselect",		0x000141	}, | 
 | 450 | 	[143]	= { "flock" }, | 
 | 451 | 	[144]	= { "msync" }, | 
 | 452 | 	[145]	= { "readv" }, | 
 | 453 | 	[146]	= { "writev" }, | 
 | 454 | 	[147]	= { "getsid",			0x000001	}, | 
 | 455 | 	[148]	= { "fdatasync",		0x000001	}, | 
 | 456 | 	[149]	= { "_sysctl",			0x000004	}, | 
 | 457 | 	[150]	= { "mlock" }, | 
 | 458 | 	[151]	= { "munlock" }, | 
 | 459 | 	[152]	= { "mlockall" }, | 
 | 460 | 	[153]	= { "munlockall" }, | 
 | 461 | 	[154]	= { "sched_setparam" }, | 
 | 462 | 	[155]	= { "sched_getparam" }, | 
 | 463 | 	[156]	= { "sched_setscheduler" }, | 
 | 464 | 	[157]	= { "sched_getscheduler" }, | 
 | 465 | 	[158]	= { "sched_yield" }, | 
 | 466 | 	[159]	= { "sched_get_priority_max" }, | 
 | 467 | 	[160]	= { "sched_get_priority_min" }, | 
 | 468 | 	[161]	= { "sched_rr_get_interval" }, | 
 | 469 | 	[162]	= { "nanosleep",		0x000044	}, | 
 | 470 | 	[163]	= { "mremap" }, | 
 | 471 | 	[164]	= { "setresuid" }, | 
 | 472 | 	[165]	= { "getresuid" }, | 
 | 473 | 	[166]	= { "vm86" }, | 
 | 474 | 	[167]	= { "query_module" }, | 
 | 475 | 	[168]	= { "poll" }, | 
 | 476 | 	[169]	= { "nfsservctl" }, | 
 | 477 | 	[170]	= { "setresgid" }, | 
 | 478 | 	[171]	= { "getresgid" }, | 
 | 479 | 	[172]	= { "prctl",			0x333331	}, | 
 | 480 | 	[173]	= { "rt_sigreturn",		0xffffff	}, | 
 | 481 | 	[174]	= { "rt_sigaction",		0x001441	}, | 
 | 482 | 	[175]	= { "rt_sigprocmask",		0x001441	}, | 
 | 483 | 	[176]	= { "rt_sigpending",		0x000014	}, | 
 | 484 | 	[177]	= { "rt_sigtimedwait",		0x001444	}, | 
 | 485 | 	[178]	= { "rt_sigqueueinfo",		0x000411	}, | 
 | 486 | 	[179]	= { "rt_sigsuspend",		0x000014	}, | 
 | 487 | 	[180]	= { "pread",			0x003341	}, | 
 | 488 | 	[181]	= { "pwrite",			0x003341	}, | 
 | 489 | 	[182]	= { "chown",			0x000115	}, | 
 | 490 | 	[183]	= { "getcwd" }, | 
 | 491 | 	[184]	= { "capget" }, | 
 | 492 | 	[185]	= { "capset" }, | 
 | 493 | 	[186]	= { "sigaltstack" }, | 
 | 494 | 	[187]	= { "sendfile" }, | 
 | 495 | 	[188]	= { "getpmsg" }, | 
 | 496 | 	[189]	= { "putpmsg" }, | 
 | 497 | 	[190]	= { "vfork",			0xffffff	}, | 
 | 498 | 	[191]	= { "ugetrlimit" }, | 
 | 499 | 	[192]	= { "mmap2",			0x313314	}, | 
 | 500 | 	[193]	= { "truncate64" }, | 
 | 501 | 	[194]	= { "ftruncate64" }, | 
 | 502 | 	[195]	= { "stat64",			0x000045	}, | 
 | 503 | 	[196]	= { "lstat64",			0x000045	}, | 
 | 504 | 	[197]	= { "fstat64",			0x000041	}, | 
 | 505 | 	[198]	= { "lchown32" }, | 
 | 506 | 	[199]	= { "getuid32",			0xffffff	}, | 
 | 507 | 	[200]	= { "getgid32",			0xffffff	}, | 
 | 508 | 	[201]	= { "geteuid32",		0xffffff	}, | 
 | 509 | 	[202]	= { "getegid32",		0xffffff	}, | 
 | 510 | 	[203]	= { "setreuid32" }, | 
 | 511 | 	[204]	= { "setregid32" }, | 
 | 512 | 	[205]	= { "getgroups32" }, | 
 | 513 | 	[206]	= { "setgroups32" }, | 
 | 514 | 	[207]	= { "fchown32" }, | 
 | 515 | 	[208]	= { "setresuid32" }, | 
 | 516 | 	[209]	= { "getresuid32" }, | 
 | 517 | 	[210]	= { "setresgid32" }, | 
 | 518 | 	[211]	= { "getresgid32" }, | 
 | 519 | 	[212]	= { "chown32" }, | 
 | 520 | 	[213]	= { "setuid32" }, | 
 | 521 | 	[214]	= { "setgid32" }, | 
 | 522 | 	[215]	= { "setfsuid32" }, | 
 | 523 | 	[216]	= { "setfsgid32" }, | 
 | 524 | 	[217]	= { "pivot_root" }, | 
 | 525 | 	[218]	= { "mincore" }, | 
 | 526 | 	[219]	= { "madvise" }, | 
 | 527 | 	[220]	= { "getdents64" }, | 
 | 528 | 	[221]	= { "fcntl64" }, | 
 | 529 | 	[223]	= { "security" }, | 
 | 530 | 	[224]	= { "gettid" }, | 
 | 531 | 	[225]	= { "readahead" }, | 
 | 532 | 	[226]	= { "setxattr" }, | 
 | 533 | 	[227]	= { "lsetxattr" }, | 
 | 534 | 	[228]	= { "fsetxattr" }, | 
 | 535 | 	[229]	= { "getxattr" }, | 
 | 536 | 	[230]	= { "lgetxattr" }, | 
 | 537 | 	[231]	= { "fgetxattr" }, | 
 | 538 | 	[232]	= { "listxattr" }, | 
 | 539 | 	[233]	= { "llistxattr" }, | 
 | 540 | 	[234]	= { "flistxattr" }, | 
 | 541 | 	[235]	= { "removexattr" }, | 
 | 542 | 	[236]	= { "lremovexattr" }, | 
 | 543 | 	[237]	= { "fremovexattr" }, | 
 | 544 | 	[238]	= { "tkill" }, | 
 | 545 | 	[239]	= { "sendfile64" }, | 
 | 546 | 	[240]	= { "futex" }, | 
 | 547 | 	[241]	= { "sched_setaffinity" }, | 
 | 548 | 	[242]	= { "sched_getaffinity" }, | 
 | 549 | 	[243]	= { "set_thread_area" }, | 
 | 550 | 	[244]	= { "get_thread_area" }, | 
 | 551 | 	[245]	= { "io_setup" }, | 
 | 552 | 	[246]	= { "io_destroy" }, | 
 | 553 | 	[247]	= { "io_getevents" }, | 
 | 554 | 	[248]	= { "io_submit" }, | 
 | 555 | 	[249]	= { "io_cancel" }, | 
 | 556 | 	[250]	= { "fadvise64" }, | 
 | 557 | 	[252]	= { "exit_group",		0x000001	}, | 
 | 558 | 	[253]	= { "lookup_dcookie" }, | 
 | 559 | 	[254]	= { "epoll_create" }, | 
 | 560 | 	[255]	= { "epoll_ctl" }, | 
 | 561 | 	[256]	= { "epoll_wait" }, | 
 | 562 | 	[257]	= { "remap_file_pages" }, | 
 | 563 | 	[258]	= { "set_tid_address" }, | 
 | 564 | 	[259]	= { "timer_create" }, | 
 | 565 | 	[260]	= { "timer_settime" }, | 
 | 566 | 	[261]	= { "timer_gettime" }, | 
 | 567 | 	[262]	= { "timer_getoverrun" }, | 
 | 568 | 	[263]	= { "timer_delete" }, | 
 | 569 | 	[264]	= { "clock_settime" }, | 
 | 570 | 	[265]	= { "clock_gettime" }, | 
 | 571 | 	[266]	= { "clock_getres" }, | 
 | 572 | 	[267]	= { "clock_nanosleep" }, | 
 | 573 | 	[268]	= { "statfs64" }, | 
 | 574 | 	[269]	= { "fstatfs64" }, | 
 | 575 | 	[270]	= { "tgkill" }, | 
 | 576 | 	[271]	= { "utimes" }, | 
 | 577 | 	[272]	= { "fadvise64_64" }, | 
 | 578 | 	[273]	= { "vserver" }, | 
 | 579 | 	[274]	= { "mbind" }, | 
 | 580 | 	[275]	= { "get_mempolicy" }, | 
 | 581 | 	[276]	= { "set_mempolicy" }, | 
 | 582 | 	[277]	= { "mq_open" }, | 
 | 583 | 	[278]	= { "mq_unlink" }, | 
 | 584 | 	[279]	= { "mq_timedsend" }, | 
 | 585 | 	[280]	= { "mq_timedreceive" }, | 
 | 586 | 	[281]	= { "mq_notify" }, | 
 | 587 | 	[282]	= { "mq_getsetattr" }, | 
 | 588 | 	[283]	= { "sys_kexec_load" }, | 
 | 589 | }; | 
 | 590 |  | 
 | 591 | asmlinkage void do_syscall_trace(int leaving) | 
 | 592 | { | 
 | 593 | #if 0 | 
 | 594 | 	unsigned long *argp; | 
 | 595 | 	const char *name; | 
 | 596 | 	unsigned argmask; | 
 | 597 | 	char buffer[16]; | 
 | 598 |  | 
 | 599 | 	if (!kstrace) | 
 | 600 | 		return; | 
 | 601 |  | 
 | 602 | 	if (!current->mm) | 
 | 603 | 		return; | 
 | 604 |  | 
 | 605 | 	if (__frame->gr7 == __NR_close) | 
 | 606 | 		return; | 
 | 607 |  | 
 | 608 | #if 0 | 
 | 609 | 	if (__frame->gr7 != __NR_mmap2 && | 
 | 610 | 	    __frame->gr7 != __NR_vfork && | 
 | 611 | 	    __frame->gr7 != __NR_execve && | 
 | 612 | 	    __frame->gr7 != __NR_exit) | 
 | 613 | 		return; | 
 | 614 | #endif | 
 | 615 |  | 
 | 616 | 	argmask = 0; | 
 | 617 | 	name = NULL; | 
 | 618 | 	if (__frame->gr7 < NR_syscalls) { | 
 | 619 | 		name = __syscall_name_table[__frame->gr7].name; | 
 | 620 | 		argmask = __syscall_name_table[__frame->gr7].argmask; | 
 | 621 | 	} | 
 | 622 | 	if (!name) { | 
 | 623 | 		sprintf(buffer, "sys_%lx", __frame->gr7); | 
 | 624 | 		name = buffer; | 
 | 625 | 	} | 
 | 626 |  | 
 | 627 | 	if (!leaving) { | 
 | 628 | 		if (!argmask) { | 
 | 629 | 			printk(KERN_CRIT "[%d] %s(%lx,%lx,%lx,%lx,%lx,%lx)\n", | 
 | 630 | 			       current->pid, | 
 | 631 | 			       name, | 
 | 632 | 			       __frame->gr8, | 
 | 633 | 			       __frame->gr9, | 
 | 634 | 			       __frame->gr10, | 
 | 635 | 			       __frame->gr11, | 
 | 636 | 			       __frame->gr12, | 
 | 637 | 			       __frame->gr13); | 
 | 638 | 		} | 
 | 639 | 		else if (argmask == 0xffffff) { | 
 | 640 | 			printk(KERN_CRIT "[%d] %s()\n", | 
 | 641 | 			       current->pid, | 
 | 642 | 			       name); | 
 | 643 | 		} | 
 | 644 | 		else { | 
 | 645 | 			printk(KERN_CRIT "[%d] %s(", | 
 | 646 | 			       current->pid, | 
 | 647 | 			       name); | 
 | 648 |  | 
 | 649 | 			argp = &__frame->gr8; | 
 | 650 |  | 
 | 651 | 			do { | 
 | 652 | 				switch (argmask & 0xf) { | 
 | 653 | 				case 1: | 
 | 654 | 					printk("%ld", (long) *argp); | 
 | 655 | 					break; | 
 | 656 | 				case 2: | 
 | 657 | 					printk("%lo", *argp); | 
 | 658 | 					break; | 
 | 659 | 				case 3: | 
 | 660 | 					printk("%lx", *argp); | 
 | 661 | 					break; | 
 | 662 | 				case 4: | 
 | 663 | 					printk("%p", (void *) *argp); | 
 | 664 | 					break; | 
 | 665 | 				case 5: | 
 | 666 | 					printk("\"%s\"", (char *) *argp); | 
 | 667 | 					break; | 
 | 668 | 				} | 
 | 669 |  | 
 | 670 | 				argp++; | 
 | 671 | 				argmask >>= 4; | 
 | 672 | 				if (argmask) | 
 | 673 | 					printk(","); | 
 | 674 |  | 
 | 675 | 			} while (argmask); | 
 | 676 |  | 
 | 677 | 			printk(")\n"); | 
 | 678 | 		} | 
 | 679 | 	} | 
 | 680 | 	else { | 
 | 681 | 		if ((int)__frame->gr8 > -4096 && (int)__frame->gr8 < 4096) | 
 | 682 | 			printk(KERN_CRIT "[%d] %s() = %ld\n", current->pid, name, __frame->gr8); | 
 | 683 | 		else | 
 | 684 | 			printk(KERN_CRIT "[%d] %s() = %lx\n", current->pid, name, __frame->gr8); | 
 | 685 | 	} | 
 | 686 | 	return; | 
 | 687 | #endif | 
 | 688 |  | 
 | 689 | 	if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 
 | 690 | 		return; | 
 | 691 |  | 
 | 692 | 	if (!(current->ptrace & PT_PTRACED)) | 
 | 693 | 		return; | 
 | 694 |  | 
 | 695 | 	/* we need to indicate entry or exit to strace */ | 
 | 696 | 	if (leaving) | 
 | 697 | 		__frame->__status |= REG__STATUS_SYSC_EXIT; | 
 | 698 | 	else | 
 | 699 | 		__frame->__status |= REG__STATUS_SYSC_ENTRY; | 
 | 700 |  | 
 | 701 | 	ptrace_notify(SIGTRAP); | 
 | 702 |  | 
 | 703 | 	/* | 
 | 704 | 	 * this isn't the same as continuing with a signal, but it will do | 
 | 705 | 	 * for normal use.  strace only continues with a signal if the | 
 | 706 | 	 * stopping signal is not SIGTRAP.  -brl | 
 | 707 | 	 */ | 
 | 708 | 	if (current->exit_code) { | 
 | 709 | 		send_sig(current->exit_code, current, 1); | 
 | 710 | 		current->exit_code = 0; | 
 | 711 | 	} | 
 | 712 | } |