ptrace.c 17 KB

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