ptrace.c 17 KB

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