]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/port/sysproc.c
sysexec(): make the mips compiler happy
[plan9front.git] / sys / src / 9 / port / sysproc.c
index 2b368e7ca23b239b878cfc48eb285c6d81969d34..1cbfdf2168c9cde28fee7fb647f03dbf3fb90e08 100644 (file)
@@ -125,7 +125,7 @@ sysrfork(va_list list)
                nexterror();
        }
        for(i = 0; i < NSEG; i++)
-               if(up->seg[i])
+               if(up->seg[i] != nil)
                        p->seg[i] = dupseg(up->seg, i, n);
        qunlock(&p->seglock);
        poperror();
@@ -243,7 +243,7 @@ sysexec(va_list list)
        char *a, *charp, *args, *file, *file0;
        char *progarg[sizeof(Exec)/2+1], *elem, progelem[64];
        ulong magic, ssize, nargs, nbytes, n;
-       uintptr t, d, b, entry, bssend, text, data, bss, tstk;
+       uintptr t, d, b, entry, bssend, text, data, bss, tstk, align;
        int indir;
        Exec exec;
        char line[sizeof(Exec)];
@@ -251,8 +251,7 @@ sysexec(va_list list)
        Image *img;
        Tos *tos;
 
-       a = nil;
-       elem = nil;
+       args = elem = nil;
        file0 = va_arg(list, char*);
        validaddr((uintptr)file0, 1, 0);
        argp0 = va_arg(list, char**);
@@ -260,12 +259,13 @@ sysexec(va_list list)
        if(waserror()){
                free(file0);
                free(elem);
-               free(a);
+               free(args);
                /* Disaster after commit */
                if(!up->seg[SSEG])
                        pexit(up->errstr, 1);
                nexterror();
        }
+       align = BY2PG;
        indir = 0;
        file = file0;
        for(;;){
@@ -278,12 +278,21 @@ sysexec(va_list list)
                        kstrdup(&elem, up->genbuf);
 
                n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0);
-               if(n < 2)
+               if(n <= 2)
                        error(Ebadexec);
                magic = l2be(exec.magic);
-               text = l2be(exec.text);
-               entry = l2be(exec.entry);
-               if(n==sizeof(Exec) && (magic == AOUT_MAGIC)){
+               if(n == sizeof(Exec) && magic == AOUT_MAGIC){
+                       text = l2be(exec.text);
+                       entry = l2be(exec.entry);
+                       switch(magic){
+                       case S_MAGIC:
+                               text += 8;
+                               align = 0x200000;       /* 2MB segment alignment for amd64 */
+                               break;
+                       case V_MAGIC:
+                               align = 0x4000;         /* MIPS has 16K page alignment */
+                               break;
+                       }
                        if(text >= (USTKTOP-USTKSIZE)-(UTZERO+sizeof(Exec))
                        || entry < UTZERO+sizeof(Exec)
                        || entry >= UTZERO+sizeof(Exec)+text)
@@ -294,18 +303,18 @@ sysexec(va_list list)
                /*
                 * Process #! /bin/sh args ...
                 */
-               memmove(line, &exec, sizeof(Exec));
+               memmove(line, &exec, n);
                if(indir || line[0]!='#' || line[1]!='!')
                        error(Ebadexec);
                n = shargs(line, n, progarg);
-               if(n == 0)
+               if(n < 1)
                        error(Ebadexec);
                indir = 1;
                /*
                 * First arg becomes complete file name
                 */
                progarg[n++] = file;
-               progarg[n] = 0;
+               progarg[n] = nil;
                argp0++;
                file = progarg[0];
                if(strlen(elem) >= sizeof progelem)
@@ -318,10 +327,12 @@ sysexec(va_list list)
 
        data = l2be(exec.data);
        bss = l2be(exec.bss);
-       t = (UTZERO+sizeof(Exec)+text+(BY2PG-1)) & ~(BY2PG-1);
-       d = (t + data + (BY2PG-1)) & ~(BY2PG-1);
+       align--;
+       t = (UTZERO+sizeof(Exec)+text+align) & ~align;
+       align = BY2PG-1;
+       d = (t + data + align) & ~align;
        bssend = t + data + bss;
-       b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
+       b = (bssend + align) & ~align;
        if(t >= (USTKTOP-USTKSIZE) || d >= (USTKTOP-USTKSIZE) || b >= (USTKTOP-USTKSIZE))
                error(Ebadexec);
 
@@ -332,7 +343,7 @@ sysexec(va_list list)
        nargs = 0;
        if(indir){
                argp = progarg;
-               while(*argp){
+               while(*argp != nil){
                        a = *argp++;
                        nbytes += strlen(a) + 1;
                        nargs++;
@@ -355,7 +366,7 @@ sysexec(va_list list)
         * 8-byte align SP for those (e.g. sparc) that need it.
         * execregs() will subtract another 4 bytes for argc.
         */
-       if((ssize+4) & 7)
+       if(BY2WD == 4 && (ssize+4) & 7)
                ssize += 4;
 
        if(PGROUND(ssize) >= USTKSIZE)
@@ -389,14 +400,14 @@ sysexec(va_list list)
 
        argv = (char**)(tstk - ssize);
        charp = (char*)(tstk - nbytes);
-       args = charp;
+       a = charp;
        if(indir)
                argp = progarg;
        else
                argp = argp0;
 
        for(i=0; i<nargs; i++){
-               if(indir && *argp==0) {
+               if(indir && *argp==nil) {
                        indir = 0;
                        argp = argp0;
                }
@@ -407,18 +418,18 @@ sysexec(va_list list)
        }
 
        /* copy args; easiest from new process's stack */
-       n = charp - args;
+       n = charp - a;
        if(n > 128)     /* don't waste too much space on huge arg lists */
                n = 128;
-       a = smalloc(n);
-       memmove(a, args, n);
-       if(n>0 && a[n-1]!='\0'){
+       args = smalloc(n);
+       memmove(args, a, n);
+       if(n>0 && args[n-1]!='\0'){
                /* make sure last arg is NUL-terminated */
                /* put NUL at UTF-8 character boundary */
                for(i=n-1; i>0; --i)
-                       if(fullrune(a+i, n-i))
+                       if(fullrune(args+i, n-i))
                                break;
-               a[i] = 0;
+               args[i] = 0;
                n = i+1;
        }
 
@@ -430,20 +441,20 @@ sysexec(va_list list)
        for(i = SSEG; i <= BSEG; i++) {
                putseg(up->seg[i]);
                /* prevent a second free if we have an error */
-               up->seg[i] = 0;
+               up->seg[i] = nil;
        }
        for(i = ESEG+1; i < NSEG; i++) {
                s = up->seg[i];
-               if(s != 0 && (s->type&SG_CEXEC) != 0) {
+               if(s != nil && (s->type&SG_CEXEC) != 0) {
                        putseg(s);
-                       up->seg[i] = 0;
+                       up->seg[i] = nil;
                }
        }
 
        /*
         * Close on exec
         */
-       if((f = up->fgrp) != nil){
+       if((f = up->fgrp) != nil) {
                for(i=0; i<=f->maxfd; i++)
                        fdclose(i, CCEXEC);
        }
@@ -475,7 +486,7 @@ sysexec(va_list list)
         * Move the stack
         */
        s = up->seg[ESEG];
-       up->seg[ESEG] = 0;
+       up->seg[ESEG] = nil;
        s->base = USTKTOP-USTKSIZE;
        s->top = USTKTOP;
        relocateseg(s, USTKTOP-tstk);
@@ -498,7 +509,7 @@ sysexec(va_list list)
        free(up->text);
        up->text = elem;
        free(up->args);
-       up->args = a;
+       up->args = args;
        up->nargs = n;
        up->setargs = 0;
 
@@ -506,6 +517,7 @@ sysexec(va_list list)
        up->notify = 0;
        up->notified = 0;
        up->privatemem = 0;
+       up->noswap = 0;
        procsetup(up);
        qunlock(&up->debug);
 
@@ -527,27 +539,28 @@ shargs(char *s, int n, char **ap)
 
        s += 2;
        n -= 2;         /* skip #! */
-       for(i=0; s[i]!='\n'; i++)
-               if(i == n-1)
+       for(i=0;; i++){
+               if(i >= n)
                        return 0;
+               if(s[i]=='\n')
+                       break;
+       }
        s[i] = 0;
-       *ap = 0;
+
        i = 0;
        for(;;) {
                while(*s==' ' || *s=='\t')
                        s++;
                if(*s == 0)
                        break;
-               i++;
-               *ap++ = s;
-               *ap = 0;
+               ap[i++] = s++;
                while(*s && *s!=' ' && *s!='\t')
                        s++;
                if(*s == 0)
                        break;
-               else
-                       *s++ = 0;
+               *s++ = 0;
        }
+       ap[i] = nil;
        return i;
 }
 
@@ -564,7 +577,7 @@ syssleep(va_list list)
 
        ms = va_arg(list, long);
        if(ms <= 0) {
-               if (up->edf && (up->edf->flags & Admitted))
+               if (up->edf != nil && (up->edf->flags & Admitted))
                        edfyield();
                else
                        yield();
@@ -591,7 +604,7 @@ sysexits(va_list list)
        char buf[ERRMAX];
 
        status = va_arg(list, char*);
-       if(status){
+       if(status != nil){
                if(waserror())
                        status = inval;
                else{
@@ -708,7 +721,7 @@ sysnotify(va_list list)
 {
        int (*f)(void*, char*);
        f = va_arg(list, void*);
-       if(f != 0)
+       if(f != nil)
                validaddr((uintptr)f, sizeof(void*), 0);
        up->notify = f;
        return 0;
@@ -717,7 +730,7 @@ sysnotify(va_list list)
 uintptr
 sysnoted(va_list list)
 {
-       if(va_arg(list, int) !=NRSTR && !up->notified)
+       if(va_arg(list, int) != NRSTR && !up->notified)
                error(Egreg);
        return 0;
 }
@@ -732,12 +745,14 @@ syssegbrk(va_list list)
        addr = va_arg(list, uintptr);
        for(i = 0; i < NSEG; i++) {
                s = up->seg[i];
-               if(s == 0 || addr < s->base || addr >= s->top)
+               if(s == nil || addr < s->base || addr >= s->top)
                        continue;
                switch(s->type&SG_TYPE) {
                case SG_TEXT:
                case SG_DATA:
                case SG_STACK:
+               case SG_PHYSICAL:
+               case SG_FIXED:
                        error(Ebadarg);
                default:
                        return (uintptr)ibrk(va_arg(list, uintptr), i);
@@ -777,14 +792,14 @@ syssegdetach(va_list list)
                nexterror();
        }
 
-       s = 0;
+       s = nil;
        for(i = 0; i < NSEG; i++)
-               if(s = up->seg[i]) {
-                       qlock(&s->lk);
+               if((s = up->seg[i]) != nil) {
+                       qlock(s);
                        if((addr >= s->base && addr < s->top) ||
                           (s->top == s->base && addr == s->base))
                                goto found;
-                       qunlock(&s->lk);
+                       qunlock(s);
                }
 
        error(Ebadarg);
@@ -794,11 +809,11 @@ found:
         * Check we are not detaching the initial stack segment.
         */
        if(s == up->seg[SSEG]){
-               qunlock(&s->lk);
+               qunlock(s);
                error(Ebadarg);
        }
-       up->seg[i] = 0;
-       qunlock(&s->lk);
+       up->seg[i] = nil;
+       qunlock(s);
        putseg(s);
        qunlock(&up->seglock);
        poperror();
@@ -815,21 +830,25 @@ syssegfree(va_list list)
        uintptr from, to;
 
        from = va_arg(list, uintptr);
+       to = va_arg(list, ulong);
+       to += from;
+       if(to < from)
+               error(Ebadarg);
        s = seg(up, from, 1);
        if(s == nil)
                error(Ebadarg);
-       to = va_arg(list, ulong);
-       to += from;
        to &= ~(BY2PG-1);
        from = PGROUND(from);
-
+       if(from >= to) {
+               qunlock(s);
+               return 0;
+       }
        if(to > s->top) {
-               qunlock(&s->lk);
+               qunlock(s);
                error(Ebadarg);
        }
-
        mfreeseg(s, from, (to - from) / BY2PG);
-       qunlock(&s->lk);
+       qunlock(s);
        flushmmu();
        return 0;
 }
@@ -852,7 +871,7 @@ sysrendezvous(va_list list)
        l = &REND(up->rgrp, tag);
 
        lock(up->rgrp);
-       for(p = *l; p; p = p->rendhash) {
+       for(p = *l; p != nil; p = p->rendhash) {
                if(p->rendtag == tag) {
                        *l = p->rendhash;
                        val = p->rendval;
@@ -1176,3 +1195,22 @@ syssemrelease(va_list list)
                error(Ebadarg);
        return (uintptr)semrelease(s, addr, delta);
 }
+
+/* For binary compatibility */
+uintptr
+sys_nsec(va_list list)
+{
+       vlong *v;
+
+       /* return in register on 64bit machine */
+       if(sizeof(uintptr) == sizeof(vlong)){
+               USED(list);
+               return (uintptr)todget(nil);
+       }
+
+       v = va_arg(list, vlong*);
+       evenaddr((uintptr)v);
+       validaddr((uintptr)v, sizeof(vlong), 1);
+       *v = todget(nil);
+       return 0;
+}