syscallfmt.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "/sys/src/libc/9syscall/sys.h"
  15. /*
  16. * Print functions for system call tracing.
  17. */
  18. static void
  19. fmtrwdata(Fmt* f, char* a, int n, char* suffix)
  20. {
  21. int i;
  22. char *t;
  23. if(a == nil){
  24. fmtprint(f, "0x0%s", suffix);
  25. return;
  26. }
  27. a = validaddr(a, n, 0);
  28. t = smalloc(n+1);
  29. for(i = 0; i < n; i++){
  30. if(a[i] > 0x20 && a[i] < 0x7f)
  31. t[i] = a[i];
  32. else
  33. t[i] = '.';
  34. }
  35. fmtprint(f, " %#p/\"%s\"%s", a, t, suffix);
  36. free(t);
  37. }
  38. static void
  39. fmtuserstring(Fmt* f, char* a, char* suffix)
  40. {
  41. int n;
  42. char *t;
  43. if(a == nil){
  44. fmtprint(f, "0/\"\"%s", suffix);
  45. return;
  46. }
  47. a = validaddr(a, 1, 0);
  48. n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;
  49. t = smalloc(n);
  50. memmove(t, a, n);
  51. t[n] = 0;
  52. fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
  53. free(t);
  54. }
  55. /*
  56. */
  57. void
  58. syscallfmt(int syscallno, va_list list)
  59. {
  60. int32_t l;
  61. uint32_t ul;
  62. Fmt fmt;
  63. void *v;
  64. int64_t vl;
  65. uintptr p;
  66. int i[2], len, **ip;
  67. char *a, **argv;
  68. fmtstrinit(&fmt);
  69. fmtprint(&fmt, "%d %s ", up->pid, up->text);
  70. if(syscallno > nsyscall)
  71. fmtprint(&fmt, " %d ", syscallno);
  72. else
  73. fmtprint(&fmt, "%s ", systab[syscallno].n);
  74. if(up->syscalltrace != nil)
  75. free(up->syscalltrace);
  76. switch(syscallno){
  77. case SYSR1:
  78. p = va_arg(list, uintptr);
  79. fmtprint(&fmt, "%#p", p);
  80. break;
  81. case _ERRSTR: /* deprecated */
  82. case CHDIR:
  83. case EXITS:
  84. case REMOVE:
  85. a = va_arg(list, char*);
  86. fmtuserstring(&fmt, a, "");
  87. break;
  88. case BIND:
  89. a = va_arg(list, char*);
  90. fmtuserstring(&fmt, a, " ");
  91. a = va_arg(list, char*);
  92. fmtuserstring(&fmt, a, " ");
  93. i[0] = va_arg(list, int);
  94. fmtprint(&fmt, "%#ux", i[0]);
  95. break;
  96. case CLOSE:
  97. case NOTED:
  98. i[0] = va_arg(list, int);
  99. fmtprint(&fmt, "%d", i[0]);
  100. break;
  101. case DUP:
  102. i[0] = va_arg(list, int);
  103. i[1] = va_arg(list, int);
  104. fmtprint(&fmt, "%d %d", i[0], i[1]);
  105. break;
  106. case ALARM:
  107. l = va_arg(list, unsigned long);
  108. fmtprint(&fmt, "%#lud ", l);
  109. break;
  110. case EXECAC:
  111. i[0] = va_arg(list, int);
  112. fmtprint(&fmt, "%d", i[0]);
  113. a = va_arg(list, char*);
  114. fmtuserstring(&fmt, a, " ");
  115. argv = va_arg(list, char**);
  116. evenaddr(PTR2UINT(argv));
  117. for(;;){
  118. a = *(char**)validaddr(argv, sizeof(char**), 0);
  119. if(a == nil)
  120. break;
  121. fmtprint(&fmt, " ");
  122. fmtuserstring(&fmt, a, "");
  123. argv++;
  124. }
  125. break;
  126. case EXEC:
  127. a = va_arg(list, char*);
  128. fmtuserstring(&fmt, a, "");
  129. argv = va_arg(list, char**);
  130. evenaddr(PTR2UINT(argv));
  131. for(;;){
  132. a = *(char**)validaddr(argv, sizeof(char**), 0);
  133. if(a == nil)
  134. break;
  135. fmtprint(&fmt, " ");
  136. fmtuserstring(&fmt, a, "");
  137. argv++;
  138. }
  139. break;
  140. case _FSESSION: /* deprecated */
  141. case _FSTAT: /* deprecated */
  142. case _FWSTAT: /* obsolete */
  143. i[0] = va_arg(list, int);
  144. a = va_arg(list, char*);
  145. fmtprint(&fmt, "%d %#p", i[0], a);
  146. break;
  147. case FAUTH:
  148. i[0] = va_arg(list, int);
  149. a = va_arg(list, char*);
  150. fmtprint(&fmt, "%d", i[0]);
  151. fmtuserstring(&fmt, a, "");
  152. break;
  153. case SEGBRK:
  154. case RENDEZVOUS:
  155. v = va_arg(list, void*);
  156. fmtprint(&fmt, "%#p ", v);
  157. v = va_arg(list, void*);
  158. fmtprint(&fmt, "%#p", v);
  159. break;
  160. case _MOUNT: /* deprecated */
  161. i[0] = va_arg(list, int);
  162. fmtprint(&fmt, "%d ", i[0]);
  163. a = va_arg(list, char*);
  164. fmtuserstring(&fmt, a, " ");
  165. i[0] = va_arg(list, int);
  166. fmtprint(&fmt, "%#ux ", i[0]);
  167. a = va_arg(list, char*);
  168. fmtuserstring(&fmt, a, "");
  169. break;
  170. case OPEN:
  171. a = va_arg(list, char*);
  172. fmtuserstring(&fmt, a, " ");
  173. i[0] = va_arg(list, int);
  174. fmtprint(&fmt, "%#ux", i[0]);
  175. break;
  176. case OSEEK: /* deprecated */
  177. i[0] = va_arg(list, int);
  178. l = va_arg(list, int32_t);
  179. i[1] = va_arg(list, int);
  180. fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
  181. break;
  182. case SLEEP:
  183. l = va_arg(list, int32_t);
  184. fmtprint(&fmt, "%ld", l);
  185. break;
  186. case _STAT: /* obsolete */
  187. case _WSTAT: /* obsolete */
  188. a = va_arg(list, char*);
  189. fmtuserstring(&fmt, a, " ");
  190. a = va_arg(list, char*);
  191. fmtprint(&fmt, "%#p", a);
  192. break;
  193. case RFORK:
  194. i[0] = va_arg(list, int);
  195. fmtprint(&fmt, "%#ux", i[0]);
  196. break;
  197. case PIPE:
  198. case BRK_:
  199. v = va_arg(list, int*);
  200. fmtprint(&fmt, "%#p", v);
  201. break;
  202. case CREATE:
  203. a = va_arg(list, char*);
  204. fmtuserstring(&fmt, a, " ");
  205. i[0] = va_arg(list, int);
  206. i[1] = va_arg(list, int);
  207. fmtprint(&fmt, "%#ux %#ux", i[0], i[1]);
  208. break;
  209. case FD2PATH:
  210. case FSTAT:
  211. case FWSTAT:
  212. i[0] = va_arg(list, int);
  213. a = va_arg(list, char*);
  214. l = va_arg(list, unsigned long);
  215. fmtprint(&fmt, "%d %#p %lud", i[0], a, l);
  216. break;
  217. case NOTIFY:
  218. case SEGDETACH:
  219. case _WAIT: /* deprecated */
  220. v = va_arg(list, void*);
  221. fmtprint(&fmt, "%#p", v);
  222. break;
  223. case SEGATTACH:
  224. i[0] = va_arg(list, int);
  225. fmtprint(&fmt, "%d ", i[0]);
  226. a = va_arg(list, char*);
  227. fmtuserstring(&fmt, a, " ");
  228. /*FALLTHROUGH*/
  229. case SEGFREE:
  230. case SEGFLUSH:
  231. v = va_arg(list, void*);
  232. l = va_arg(list, unsigned long);
  233. fmtprint(&fmt, "%#p %lud", v, l);
  234. break;
  235. case UNMOUNT:
  236. a = va_arg(list, char*);
  237. fmtuserstring(&fmt, a, " ");
  238. a = va_arg(list, char*);
  239. fmtuserstring(&fmt, a, "");
  240. break;
  241. case SEMACQUIRE:
  242. case SEMRELEASE:
  243. v = va_arg(list, int*);
  244. i[0] = va_arg(list, int);
  245. fmtprint(&fmt, "%#p %d", v, i[0]);
  246. break;
  247. case TSEMACQUIRE:
  248. v = va_arg(list, int*);
  249. l = va_arg(list, uint32_t);
  250. fmtprint(&fmt, "%#p %ld", v, l);
  251. break;
  252. case SEMSLEEP:
  253. case SEMWAKEUP:
  254. v = va_arg(list, int*);
  255. fmtprint(&fmt, "%#p", v);
  256. break;
  257. case SEMALT:
  258. ip = va_arg(list, int**);
  259. i[0] = va_arg(list, int);
  260. validaddr(ip, sizeof(int*)*i[0], 0);
  261. fmtprint(&fmt, "%#p %d", ip, i[0]);
  262. break;
  263. case SEEK:
  264. v = va_arg(list, int64_t*);
  265. i[0] = va_arg(list, int);
  266. vl = va_arg(list, int64_t);
  267. i[1] = va_arg(list, int);
  268. fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]);
  269. break;
  270. case FVERSION:
  271. i[0] = va_arg(list, int);
  272. i[1] = va_arg(list, int);
  273. fmtprint(&fmt, "%d %d ", i[0], i[1]);
  274. a = va_arg(list, char*);
  275. fmtuserstring(&fmt, a, " ");
  276. l = va_arg(list, unsigned long);
  277. fmtprint(&fmt, "%lud", l);
  278. break;
  279. case WSTAT:
  280. case STAT:
  281. a = va_arg(list, char*);
  282. fmtuserstring(&fmt, a, " ");
  283. /*FALLTHROUGH*/
  284. case ERRSTR:
  285. case AWAIT:
  286. a = va_arg(list, char*);
  287. l = va_arg(list, unsigned long);
  288. fmtprint(&fmt, "%#p %lud", a, l);
  289. break;
  290. case MOUNT:
  291. i[0] = va_arg(list, int);
  292. i[1] = va_arg(list, int);
  293. fmtprint(&fmt, "%d %d ", i[0], i[1]);
  294. a = va_arg(list, char*);
  295. fmtuserstring(&fmt, a, " ");
  296. i[0] = va_arg(list, int);
  297. fmtprint(&fmt, "%#ux ", i[0]);
  298. a = va_arg(list, char*);
  299. fmtuserstring(&fmt, a, "");
  300. break;
  301. case _READ: /* deprecated */
  302. case PREAD:
  303. i[0] = va_arg(list, int);
  304. v = va_arg(list, void*);
  305. l = va_arg(list, int32_t);
  306. fmtprint(&fmt, "%d %#p %ld", i[0], v, l);
  307. if(syscallno == PREAD){
  308. vl = va_arg(list, int64_t);
  309. fmtprint(&fmt, " %lld", vl);
  310. }
  311. break;
  312. case _WRITE: /* deprecated */
  313. case PWRITE:
  314. i[0] = va_arg(list, int);
  315. v = va_arg(list, void*);
  316. l = va_arg(list, int32_t);
  317. fmtprint(&fmt, "%d ", i[0]);
  318. len = MIN(l, 64);
  319. fmtrwdata(&fmt, v, len, " ");
  320. fmtprint(&fmt, "%ld", l);
  321. if(syscallno == PWRITE){
  322. vl = va_arg(list, int64_t);
  323. fmtprint(&fmt, " %lld", vl);
  324. }
  325. break;
  326. case ZIOPREAD:
  327. i[0] = va_arg(list, int);
  328. v = va_arg(list, void*);
  329. i[1] = va_arg(list, int);
  330. ul = va_arg(list, usize);
  331. vl = va_arg(list, int64_t);
  332. fmtprint(&fmt, "%d %#p %d %ld %ulld", i[0], v, i[1], ul, vl);
  333. break;
  334. case ZIOPWRITE:
  335. i[0] = va_arg(list, int);
  336. v = va_arg(list, void*);
  337. i[1] = va_arg(list, int);
  338. vl = va_arg(list, int64_t);
  339. fmtprint(&fmt, "%d %#p %d %ulld", i[0], v, i[1], vl);
  340. break;
  341. case ZIOFREE:
  342. v = va_arg(list, void*);
  343. i[1] = va_arg(list, int);
  344. fmtprint(&fmt, "%#p %d", v, i[1]);
  345. case NIXSYSCALL:
  346. break;
  347. }
  348. up->syscalltrace = fmtstrflush(&fmt);
  349. }
  350. void
  351. sysretfmt(int syscallno, va_list list, Ar0* ar0, uint64_t start,
  352. uint64_t stop)
  353. {
  354. int32_t l;
  355. void* v;
  356. Fmt fmt;
  357. int64_t vl;
  358. int i, len;
  359. char *a, *errstr;
  360. fmtstrinit(&fmt);
  361. if(up->syscalltrace)
  362. free(up->syscalltrace);
  363. errstr = "\"\"";
  364. switch(syscallno){
  365. default:
  366. if(ar0->i == -1)
  367. errstr = up->errstr;
  368. fmtprint(&fmt, " = %d", ar0->i);
  369. break;
  370. case ALARM:
  371. case _WRITE:
  372. case PWRITE:
  373. if(ar0->l == -1)
  374. errstr = up->errstr;
  375. fmtprint(&fmt, " = %ld", ar0->l);
  376. break;
  377. case EXEC:
  378. case EXECAC:
  379. case SEGBRK:
  380. case SEGATTACH:
  381. case RENDEZVOUS:
  382. if(ar0->v == (void*)-1)
  383. errstr = up->errstr;
  384. fmtprint(&fmt, " = %#p", ar0->v);
  385. break;
  386. case AWAIT:
  387. a = va_arg(list, char*);
  388. l = va_arg(list, unsigned long);
  389. if(ar0->i > 0){
  390. fmtuserstring(&fmt, a, " ");
  391. fmtprint(&fmt, "%lud = %d", l, ar0->i);
  392. }
  393. else{
  394. fmtprint(&fmt, "%#p/\"\" %lud = %d", a, l, ar0->i);
  395. errstr = up->errstr;
  396. }
  397. break;
  398. case _ERRSTR:
  399. case ERRSTR:
  400. a = va_arg(list, char*);
  401. if(syscallno == _ERRSTR)
  402. l = 64;
  403. else
  404. l = va_arg(list, unsigned long);
  405. if(ar0->i > 0){
  406. fmtuserstring(&fmt, a, " ");
  407. fmtprint(&fmt, "%lud = %d", l, ar0->i);
  408. }
  409. else{
  410. fmtprint(&fmt, "\"\" %lud = %d", l, ar0->i);
  411. errstr = up->errstr;
  412. }
  413. break;
  414. case FD2PATH:
  415. i = va_arg(list, int);
  416. USED(i);
  417. a = va_arg(list, char*);
  418. l = va_arg(list, unsigned long);
  419. if(ar0->i > 0){
  420. fmtuserstring(&fmt, a, " ");
  421. fmtprint(&fmt, "%lud = %d", l, ar0->i);
  422. }
  423. else{
  424. fmtprint(&fmt, "\"\" %lud = %d", l, ar0->i);
  425. errstr = up->errstr;
  426. }
  427. break;
  428. case _READ:
  429. case PREAD:
  430. i = va_arg(list, int);
  431. USED(i);
  432. v = va_arg(list, void*);
  433. l = va_arg(list, int32_t);
  434. if(ar0->l > 0){
  435. len = MIN(ar0->l, 64);
  436. fmtrwdata(&fmt, v, len, "");
  437. }
  438. else{
  439. fmtprint(&fmt, "/\"\"");
  440. errstr = up->errstr;
  441. }
  442. fmtprint(&fmt, " %ld", l);
  443. if(syscallno == PREAD){
  444. vl = va_arg(list, int64_t);
  445. fmtprint(&fmt, " %lld", vl);
  446. }
  447. fmtprint(&fmt, " = %d", ar0->i);
  448. break;
  449. }
  450. fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop);
  451. up->syscalltrace = fmtstrflush(&fmt);
  452. }