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