syscallfmt.c 10 KB

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