syscall (5353B)
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 }