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();
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)];
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**);
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(;;){
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)
/*
* 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)
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);
nargs = 0;
if(indir){
argp = progarg;
- while(*argp){
+ while(*argp != nil){
a = *argp++;
nbytes += strlen(a) + 1;
nargs++;
* 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)
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;
}
}
/* 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;
}
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);
}
* 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);
free(up->text);
up->text = elem;
free(up->args);
- up->args = a;
+ up->args = args;
up->nargs = n;
up->setargs = 0;
up->notify = 0;
up->notified = 0;
up->privatemem = 0;
+ up->noswap = 0;
procsetup(up);
qunlock(&up->debug);
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;
}
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();
char buf[ERRMAX];
status = va_arg(list, char*);
- if(status){
+ if(status != nil){
if(waserror())
status = inval;
else{
{
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;
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;
}
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);
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);
* 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();
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;
}
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;
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;
+}