11 typedef struct Tos Tos;
13 struct /* Per process profiling */
15 ulong pp; /* known to be 0(ptr) */
16 ulong next; /* known to be 4(ptr) */
22 uvlong cyclefreq; /* cycle clock frequency if there is one, 0 otherwise */
23 vlong kcycles; /* cycles spent in kernel */
24 vlong pcycles; /* cycles spent in process (kernel + user) */
25 ulong pid; /* might as well put the pid here */
27 /* top of stack is here */
37 P = emallocz(sizeof(Process));
66 p->prev->next = p->next;
67 p->next->prev = p->prev;
77 for(p = plist.next; p != &plist; p = p->next)
91 p = strrchr(file, '/');
96 strncpy(P->name, p, NAMEMAX);
98 if(P->path != nil && decref(P->path) == 0)
100 P->path = emallocz(sizeof(Ref) + strlen(file)+1);
102 strcpy((char*)(P->path + 1), file);
106 initstack(int argc, char **argv)
108 ulong tos, sp, ap, size, i, len;
110 tos = (mach->utop & ~7) - sizeof(Tos) * 2;
114 for(i = 0; i < argc; i++)
115 size += strlen(argv[i]) + 5;
120 P->R[1] = mach->utop - 4;
123 *(ulong *) vaddrnol(sp, 4) = argc;
125 ap = sp + (argc + 1) * 4;
126 for(i = 0; i < argc; i++) {
127 *(ulong *) vaddrnol(sp, 4) = ap;
129 len = strlen(argv[i]) + 1;
130 memcpy(vaddrnol(ap, len), argv[i], len);
133 *(ulong *) vaddrnol(sp, 4) = 0;
142 tos = (mach->utop & ~7) - sizeof(Tos) * 2;
143 ((Tos *) vaddrnol(tos, sizeof(Tos)))->pid = P->pid;
147 loadscript(int fd, char *file, int argc, char **argv)
149 char buf[513], *p, **q, **nargv;
153 rc = readn(fd, buf, 512);
158 p = strchr(buf, '\n');
167 while(*p && isspace(*p))
170 while(*p && !isspace(*p))
175 nargv = emallocz(sizeof(char *) * (nargc + argc));
179 while(*p && isspace(*p))
183 while(*p && !isspace(*p))
187 for(i = 1; i < argc; i++)
189 rc = loadtext(*nargv, argc + nargc, nargv);
194 werrstr("exec header invalid");
199 loadtext(char *file, int argc, char **argv)
203 Segment *text, *data, *bss;
206 fd = open(file, OREAD);
207 if(fd < 0) return -1;
208 if(pread(fd, buf, 2, 0) == 2 && buf[0] == '#' && buf[1] == '!')
209 return loadscript(fd, file, argc, argv);
211 if(crackhdr(fd, &fp) == 0 || fp.magic != E_MAGIC) {
212 werrstr("exec header invalid");
216 P->notehandler = P->innote = P->notein = P->noteout = 0;
218 memset(P->R, 0, sizeof(P->R));
220 text = newseg(fp.txtaddr - fp.hdrsz, fp.txtsz + fp.hdrsz, SEGTEXT);
221 data = newseg(fp.dataddr, fp.datsz, SEGDATA);
222 bss = newseg(fp.dataddr + fp.datsz, fp.bsssz, SEGBSS);
223 newseg(mach->utop - STACKSIZE, STACKSIZE, SEGSTACK);
224 seek(fd, fp.txtoff - fp.hdrsz, 0);
225 if(readn(fd, text->data, fp.txtsz + fp.hdrsz) < fp.txtsz + fp.hdrsz)
227 seek(fd, fp.datoff, 0);
228 if(readn(fd, data->data, fp.datsz) < fp.datsz)
230 memset(bss->data, 0, bss->size);
232 if(havesymbols && syminit(fd, &fp) < 0)
233 fprint(2, "initializing symbol table: %r\n");
236 initstack(argc, argv);
245 cherrstr(char *str, ...)
250 vsnprint(P->errbuf, ERRMAX, str, va);
255 noteerr(u32int x, u32int y)
257 if(((int)x) >= ((int)y))
259 rerrstr(P->errbuf, ERRMAX);
268 fd = emallocz(sizeof(*fd));
281 new->nfds = old->nfds;
282 new->fds = emalloc(old->nfds);
283 memcpy(new->fds, old->fds, old->nfds);
292 if(decref(fd) == 0) {
299 iscexec(Fd *fd, int n)
306 r = (fd->fds[n / 8] & (1 << (n % 8))) != 0;
312 setcexec(Fd *fd, int n, int status)
317 if(n / 8 >= fd->nfds) {
323 fd->nfds = (n / 8) + 1;
324 fd->fds = erealloc(fd->fds, fd->nfds);
325 memset(fd->fds + old, 0, fd->nfds - old);
328 fd->fds[n / 8] &= ~(1 << (n % 8));
330 fd->fds[n / 8] |= (1 << (n % 8));
344 for(i = 0; i < fd->nfds; i++) {
346 for(k = 0; k < 8; k++)
356 /* call this from a notehandler if you don't want the front to fall off */
363 if((new - P->noteout) % NNOTE == 0)
366 strncpy(P->notes[P->notein % NNOTE], msg, ERRMAX - 1);
370 /* the following code is not for the weak of heart */
372 donote(char *msg, ulong type)
375 u32int *ureg, *sp, uregp, msgp;
378 if(P->notehandler == 0)
381 uregp = P->R[13] - 18 * 4;
382 ureg = vaddrnol(uregp, 18 * 4);
383 memcpy(ureg, P->R, 15 * 4);
388 msgp = P->R[13] -= ERRMAX;
389 msgb = vaddrnol(msgp, ERRMAX);
390 strncpy(msgb, msg, ERRMAX);
392 sp = vaddrnol(P->R[13], 3 * 4);
396 P->R[15] = P->notehandler;
398 switch(rc = setjmp(P->notejmp) - 1) {
410 sysfatal("unhandled noted argument %d", rc);
413 ureg = vaddrnol(uregp, 18 * 4); /* just to be sure */
414 memcpy(P->R, ureg, 15 * 4);