ptrace.c 17 KB

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