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