1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <ctype.h> 5 #include <mach.h> 6 #define Extern extern 7 #include "acid.h" 8 #include "y.tab.h" 9 10 static void install(int); 11 12 static void 13 fixregs(Map *map) 14 { 15 Reglist *rp; 16 Lsym *l; 17 long flen; 18 19 static int doneonce; 20 21 switch(mach->mtype) { 22 default: 23 case MMIPS: 24 case MSPARC: 25 return; 26 case MI386: 27 if (doneonce) 28 return; 29 doneonce = 1; 30 flen = 0; 31 break; 32 case M68020: 33 if (machdata->ufixup(map, &flen) < 0) 34 error("fixregs: %r\n"); 35 break; 36 } 37 for (rp = mach->reglist; rp->rname; rp++) { 38 if ((rp->rflags&RFLT)) 39 continue; 40 l = look(rp->rname); 41 if(l == 0) 42 print("lost register %s\n", rp->rname); 43 else 44 l->v->ival = mach->kbase+rp->roffs-flen; 45 } 46 } 47 48 void 49 sproc(int pid) 50 { 51 Lsym *s; 52 ulong ksp; 53 char buf[64]; 54 int fd, fcor; 55 56 if(symmap == 0) 57 error("no map"); 58 59 sprint(buf, "/proc/%d/mem", pid); 60 fcor = open(buf, ORDWR); 61 if(fcor < 0) 62 error("setproc: open %s: %r", buf); 63 64 checkqid(symmap->fd, pid); 65 66 if(cormap) 67 close(cormap->fd); 68 69 s = look("pid"); 70 s->v->ival = pid; 71 72 sprint(buf, "/proc/%d/proc", pid); 73 fd = open(buf, 0); 74 if(fd >= 0){ 75 seek(fd, mach->kspoff, 0); 76 if(read(fd, (char *)&ksp, 4L) == 4) 77 mach->kbase = machdata->swal(ksp) & ~(mach->pgsize-1); 78 close(fd); 79 } 80 81 cormap = newmap(cormap, fcor, 3); 82 if (cormap == 0) 83 error("setproc: cant make coremap"); 84 85 setmap(cormap, fhdr.txtaddr, fhdr.txtaddr+fhdr.txtsz, fhdr.txtaddr, "*text"); 86 setmap(cormap, fhdr.dataddr, mach->kbase&~mach->ktmask, fhdr.dataddr, "*data"); 87 setmap(cormap, mach->kbase, mach->kbase+mach->pgsize, mach->kbase, "*ublock"); 88 install(pid); 89 fixregs(cormap); 90 } 91 92 int 93 nproc(char **argv) 94 { 95 char buf[128]; 96 int pid, i, fd; 97 98 pid = fork(); 99 switch(pid) { 100 case -1: 101 error("new: fork %r"); 102 case 0: 103 rfork(RFNAMEG|RFNOTEG); 104 105 sprint(buf, "/proc/%d/ctl", getpid()); 106 fd = open(buf, ORDWR); 107 if(fd < 0) 108 fatal("new: open %s: %r", buf); 109 write(fd, "hang", 4); 110 close(fd); 111 112 close(0); 113 close(1); 114 close(2); 115 for(i = 3; i < NFD; i++) 116 close(i); 117 118 open("/dev/cons", OREAD); 119 open("/dev/cons", OWRITE); 120 open("/dev/cons", OWRITE); 121 exec(argv[0], argv); 122 fatal("new: exec %s: %r"); 123 default: 124 install(pid); 125 msg(pid, "waitstop"); 126 notes(pid); 127 sproc(pid); 128 dostop(pid); 129 break; 130 } 131 132 return pid; 133 } 134 135 void 136 notes(int pid) 137 { 138 Lsym *s; 139 Value *v; 140 int i, fd; 141 char buf[128]; 142 List *l, **tail; 143 144 s = look("notes"); 145 if(s == 0) 146 return; 147 v = s->v; 148 149 sprint(buf, "/proc/%d/note", pid); 150 fd = open(buf, OREAD); 151 if(fd < 0) 152 error("pid=%d: open note: %r", pid); 153 154 v->set = 1; 155 v->type = TLIST; 156 v->l = 0; 157 tail = &v->l; 158 for(;;) { 159 i = read(fd, buf, sizeof(buf)); 160 if(i <= 0) 161 break; 162 buf[i] = '\0'; 163 l = al(TSTRING); 164 l->string = strnode(buf); 165 l->fmt = 's'; 166 *tail = l; 167 tail = &l->next; 168 } 169 close(fd); 170 } 171 172 void 173 dostop(int pid) 174 { 175 Lsym *s; 176 Node *np, *p; 177 178 fixregs(cormap); 179 180 s = look("stopped"); 181 if(s && s->proc) { 182 np = an(ONAME, ZN, ZN); 183 np->sym = s; 184 np->fmt = 'D'; 185 np->type = TINT; 186 p = con(pid); 187 p->fmt = 'D'; 188 np = an(OCALL, np, p); 189 execute(np); 190 } 191 } 192 193 static void 194 install(int pid) 195 { 196 Lsym *s; 197 List *l; 198 char buf[128]; 199 int i, fd, new, p; 200 201 new = -1; 202 for(i = 0; i < Maxproc; i++) { 203 p = ptab[i].pid; 204 if(p == pid) 205 return; 206 if(p == 0 && new == -1) 207 new = i; 208 } 209 if(new == -1) 210 error("no free process slots"); 211 212 sprint(buf, "/proc/%d/ctl", pid); 213 fd = open(buf, OWRITE); 214 if(fd < 0) 215 error("pid=%d: open ctl: %r", pid); 216 217 ptab[new].pid = pid; 218 ptab[new].ctl = fd; 219 220 s = look("proclist"); 221 l = al(TINT); 222 l->fmt = 'D'; 223 l->ival = pid; 224 l->next = s->v->l; 225 s->v->l = l; 226 s->v->set = 1; 227 } 228 229 void 230 deinstall(int pid) 231 { 232 int i; 233 Lsym *s; 234 List *f, **d; 235 236 for(i = 0; i < Maxproc; i++) { 237 if(ptab[i].pid == pid) { 238 close(ptab[i].ctl); 239 ptab[i].pid = 0; 240 s = look("proclist"); 241 d = &s->v->l; 242 for(f = *d; f; f = f->next) { 243 if(f->ival == pid) { 244 *d = f->next; 245 break; 246 } 247 } 248 s = look("pid"); 249 if(s->v->ival == pid) 250 s->v->ival = 0; 251 return; 252 } 253 } 254 } 255 256 void 257 msg(int pid, char *msg) 258 { 259 int i; 260 int l; 261 char err[ERRLEN]; 262 263 for(i = 0; i < Maxproc; i++) { 264 if(ptab[i].pid == pid) { 265 l = strlen(msg); 266 if(write(ptab[i].ctl, msg, l) != l) { 267 errstr(err); 268 if(strcmp(err, "process exited") == 0) 269 deinstall(pid); 270 error("msg: pid=%d %s: %s", pid, msg, err); 271 } 272 return; 273 } 274 } 275 error("msg: pid=%d: not found for %s", pid, msg); 276 } 277 278 char * 279 getstatus(int pid) 280 { 281 int fd; 282 char *p; 283 284 static char buf[128]; 285 286 sprint(buf, "/proc/%d/status", pid); 287 fd = open(buf, OREAD); 288 if(fd < 0) 289 error("open %s: %r", buf); 290 read(fd, buf, sizeof(buf)); 291 close(fd); 292 p = buf+56+12; /* Do better! */ 293 while(*p == ' ') 294 p--; 295 p[1] = '\0'; 296 return buf+56; /* ditto */ 297 } 298 299 char * 300 waitfor(int pid) 301 { 302 int n; 303 304 static Waitmsg w; 305 306 for(;;) { 307 n = wait(&w); 308 if(n < 0) 309 error("wait %r"); 310 if(n == pid) 311 return w.msg; 312 } 313 } 314