syscall 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // print system calls
  2. defn printstring(s)
  3. {
  4. print("\"", s, "\"");
  5. }
  6. defn printtextordata(addr, n)
  7. {
  8. local a, i;
  9. a = addr\c;
  10. i = 0;
  11. loop 1, n do {
  12. if (a[i]>=127) then {
  13. print(fmt(addr, 'X'), ", ", n\D);
  14. return {};
  15. }
  16. i = i+1;
  17. }
  18. print("\"");
  19. printstringn(addr, n);
  20. print("\"");
  21. }
  22. defn printstringn(s, n)
  23. {
  24. local m;
  25. m = n;
  26. if (m > 100) then m = 100;
  27. loop 1,m do {
  28. print(*(s\c)); s=s+1;
  29. }
  30. if(m != n) then print("...");
  31. }
  32. defn printsyscall(name, fmt, arg) {
  33. local f, i, a, argp, sl;
  34. print(name, "(");
  35. i = 0;
  36. a = eval arg;
  37. while fmt[i] != 0 do {
  38. if fmt[i] == 's' then {
  39. if *a == 0 then
  40. print("nil");
  41. else
  42. printstring(*(*a\s));
  43. } else if fmt[i] == 'S' then {
  44. argp = *a;
  45. argl = {};
  46. while *argp != 0 do {
  47. argl = append argl, *(*argp\s);
  48. argp++;
  49. }
  50. print(argl);
  51. } else if (fmt[i] == 'Z') && (~*a == 0) then {
  52. print("-1");
  53. a++; // advance extra word for quadword
  54. } else if (fmt[i] == 'Y') || (fmt[i] == 'V') then {
  55. print(fmt(*a, fmt[i]));
  56. a++; // advance extra word for quadword
  57. } else if (fmt[i] == 'T') then {
  58. if *a == 0 then
  59. print("nil");
  60. else
  61. printtextordata(*a, a[1]);
  62. } else
  63. print(fmt(*a, fmt[i]));
  64. if fmt[i+1] != 0 then
  65. print(", ");
  66. i = i+1;
  67. a++;
  68. }
  69. print(")\n");
  70. }
  71. defn code(*e) { return e; }
  72. syscalls = {
  73. { 0, {"sysr1", "s", code(0)}},
  74. { 1, {"_errstr", "s", code(*sys_errstr:arg)}},
  75. { 2, {"bind", "ssX", code(*sysbind:arg)}},
  76. { 3, {"chdir", "s", code(*sysbind:arg)}},
  77. { 4, {"close", "D", code(*sysclose:arg)}},
  78. { 5, {"dup", "DD", code(*sysdup:arg)}},
  79. { 6, {"alarm", "D", code(*sysalarm:arg)}},
  80. { 7, {"exec", "sS", code(*sysexec:arg)}},
  81. { 8, {"exits", "s", code(*sysexits:arg)}},
  82. { 9, {"_fsession", "DX", code(*sys_fsession:arg)}},
  83. {10, {"fauth", "DX", code(*sysfauth:arg)}},
  84. {11, {"_fstat", "DX", code(*sys_fstat:arg)}},
  85. {12, {"segbrk", "XX", code(*syssegbrk:arg)}},
  86. {13, {"_mount", "DsXs", code(*sys_mount:arg)}},
  87. {14, {"open", "sD", code(*sysopen:arg)}},
  88. {15, {"_read", "DXD", code(*sys_read:arg)}},
  89. {16, {"oseek", "DDD", code(*sysoseek:arg)}},
  90. {17, {"sleep", "D", code(*syssleep:arg)}},
  91. {18, {"_stat", "sX", code(*sys_stat:arg)}},
  92. {19, {"rfork", "X", code(*sysstat:arg)}},
  93. {20, {"_write", "DXD", code(*sys_write:arg)}},
  94. {21, {"pipe", "X", code(*syspipe:arg)}},
  95. {22, {"create", "sDO", code(*syscreate:arg)}},
  96. {23, {"fd2path", "DXD", code(*sysfd2path:arg)}},
  97. {24, {"brk_", "X", code(*sysbrk_:arg)}},
  98. {25, {"remove", "s", code(*sysremove:arg)}},
  99. {26, {"_wstat", "sX", code(*sys_wstat:arg)}},
  100. {27, {"_fwstat", "DX", code(*sys_fwstat:arg)}},
  101. {28, {"notify", "X", code(*sysnotify:arg)}},
  102. {29, {"noted", "D", code(*sysnoted:arg)}},
  103. {30, {"segattach", "DsXD", code(*syssegattach:arg)}},
  104. {31, {"segdetach", "X", code(*syssegdetach:arg)}},
  105. {32, {"segfree", "XD", code(*syssegfree:arg)}},
  106. {33, {"segflush", "XD", code(*syssegflush:arg)}},
  107. {34, {"rendezvous", "XX", code(*sysrendezvous:arg)}},
  108. {35, {"unmount", "ss", code(*sysunmount:arg)}},
  109. {36, {"_wait", "X", code(*sys_wait:arg)}},
  110. {39, {"seek", "XDVD", code(*sysseek:arg)}},
  111. {40, {"fversion", "DDsD", code(*sysfversion:arg)}},
  112. {41, {"errstr", "TD", code(*syserrstr:arg)}},
  113. {42, {"stat", "sXD", code(*sysstat:arg)}},
  114. {43, {"fstat", "DXD", code(*sysfstat:arg)}},
  115. {44, {"wstat", "sXD", code(*syswstat:arg)}},
  116. {45, {"fwstat", "DXD", code(*sysfwstat:arg)}},
  117. {46, {"mount", "DDsXs", code(*sysmount:arg)}},
  118. {47, {"await", "TD", code(*sysawait:arg)}},
  119. {50, {"pread", "DXDZ", code(*syspread:arg)}},
  120. {51, {"pwrite", "DTDZ", code(*syspwrite:arg)}},
  121. };
  122. defn syscall() {
  123. local n, sl, h, p;
  124. map({"*data", 0, 0xffffffff, 0});
  125. n = *syscall:scallnr;
  126. sl = syscalls;
  127. while sl != {} do {
  128. h = head sl;
  129. sl = tail sl;
  130. if n == h[0] then {
  131. p = h[1];
  132. printsyscall(p[0], p[1], p[2]);
  133. }
  134. }
  135. }
  136. defn UPCSPRET() {
  137. // return sys call number, address of first argument, location of syscall return value
  138. if objtype == "386" then
  139. return { code(*(*PC-4)), code(*SP+4), code(*AX) };
  140. if (objtype == "mips") || (objtype == "mips2") then
  141. return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R1) };
  142. if objtype == "arm" then
  143. return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R0) }; // untested
  144. if objtype == "alpha" then
  145. return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R0) }; // untested
  146. }
  147. defn trapoffset() {
  148. // return offset from entry point to trap instr
  149. if objtype == "386" then return 5;
  150. if objtype == "mips" then return 8;
  151. if objtype == "mips2" then return 8;
  152. if objtype == "arm" then return 8; // untested
  153. if objtype == "alpha" then return 8; // untested
  154. }
  155. defn trapreason() {
  156. // return reason for trap
  157. if objtype == "386" then return reason(*TRAP);
  158. if objtype == "mips" then return reason(*CAUSE);
  159. if objtype == "mips2" then return reason(*CAUSE);
  160. if objtype == "arm" then return "unknown trap"; // untested
  161. if objtype == "alpha" then return reason(cause); // untested
  162. }
  163. defn usyscall() { // gives args for system call in user level; not useful with -k
  164. local n, sl, h, p;
  165. // stopped at TRAP instruction in system call library
  166. pcsp = UPCSPRET();
  167. n = eval pcsp[0];
  168. sl = syscalls;
  169. while sl != {} do {
  170. h = head sl;
  171. sl = tail sl;
  172. if n == h[0] then {
  173. p = h[1];
  174. printsyscall(p[0], p[1], pcsp[1]);
  175. }
  176. }
  177. }