ptrace.c 17 KB

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