ref: b013afeab72944bb98df07fc366734d358b3024c
parent: 9e00d68ab063deec970fdb5f48a06003e72ba287
parent: 4c76f46e25f32299c1ed1534c20b5bc65d1a7b7a
author: cinap_lenrek <cinap_lenrek@localhost>
date: Sun Jun 26 03:03:44 EDT 2011
merge
--- a/rc/bin/kill
+++ b/rc/bin/kill
@@ -1,4 +1,8 @@
#!/bin/rc
+rfork e
+U=`{cat /dev/user} for(i){- ps | sed -n '/ '^$i^'$/s%^[^ ]* *([^ ]*).*%chmod 666 /proc/\1/ctl;echo kill > /proc/\1/ctl%p'
+ ps | sed -n '/^'$U' .* '$i'$/s%[^ ]* *%~>/proc/%
+ s% *.* (.*)%/note # \1%
+ s%~%echo kill%p'
}
--- a/sys/games/lib/fortunes
+++ b/sys/games/lib/fortunes
@@ -4461,3 +4461,14 @@
Alan Turing always wanted to win a McIlroy Award, but didn't qualify. No one has.
In 1984, the Department of Justice broke up AT&T because they had a monopoly. On Doug McIlroy.
<uriel> god i'm dead
+Starve before doing business with the damned Navy. -- Ben Rich
+Saw comment // NEW BOOST CODE, and had a moment of panic before realizing it was vehicle boost, not C++ boost -- John Carmack
+While attempting its first overseas deployment to the Kadena Air Base in Okinawa, Japan, on 11 February 2007, a group of six Raptors flying from Hickam AFB, Hawaii experienced multiple computer crashes coincident with their crossing of the 180th meridian of longitude (the International Date Line).
+also, plan9front claims to include a working go compiler. what did they do? -- Russ Cox
+<Tanami> plan 9 has a thriving and friendly community
+on the internet, no one knows you're ken thompson -- sl
+VEGETARYAN -- Seen on a Hipster Hitler t-shirt.
+os.Open opens the in-kernel databases, called files -- Aiju on Go's stdlib lack of database access libraries.
+<aiju> i like how 2011 cell phones emulate 1970 modems
+<ment> glenda is 19 years old, she wants to go out and have some fun, not to be locked in attic and get molested by her uncle
+<aiju> is he building the GNU ark? two of each feature ..
--- a/sys/include/libc.h
+++ b/sys/include/libc.h
@@ -691,6 +691,9 @@
extern void werrstr(char*, ...);
#pragma varargck argpos werrstr 1
+extern long ainc(long*);
+extern long adec(long*);
+
extern char *argv0;
#define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\
argv[0] && argv[0][0]=='-' && argv[0][1];\
--- /dev/null
+++ b/sys/man/1/5e
@@ -1,0 +1,137 @@
+.TH 5E 1
+.SH NAME
+5e \- user-mode ARM emulation
+.SH SYNOPSIS
+.B 5e
+[
+.B -npb
+]
+.I text
+[
+.I arguments
+]
+.SH DESCRIPTION
+.I 5e
+simulates the execution of an ARM binary in a Plan 9 environment.
+Unlike its predecessor
+.IR 5i (1)
+it supports, among others, the syscalls
+.IR rfork (2)
+and
+.IR exec (2),
+i.e. it allows execution of threaded programs, e.g.
+.IR rio (1)
+or
+.IR catclock (1).
+.PP
+.I 5e
+executes the specified binary
+.IR text ,
+which is prepended by
+.B /bin
+if it does not begin with a slash, dot or hash sign.
+Unless
+.B -n
+is specified,
+.B /bin
+is replaced by the union of
+.B /arm/bin
+and
+.BR /rc/bin .
+.PP
+Unlike
+.IR 5i (1),
+.IR 5e (1)
+does not provide built-in debugging facilities.
+It
+.I does
+provide emulation of the
+.B /proc
+directory, if the
+.B -p
+flag is specified, to attach a proper debugger like
+.IR acid (1).
+There is no equivalent of the profiling facilities, no caches or TLBs are simulated, either.
+.PP
+.IR 5e (1)
+currently has three options.
+.TP
+.B -n
+By default,
+.IR 5e (1)
+replaces
+.B /bin
+as mentioned above and also sets the variables
+.B cputype
+and
+.B objtype
+to
+.BR arm.
+Supplying the
+.B -n
+option suppresses this behaviour.
+.TP
+.B -p
+The
+.B -p
+option activates emulation of a
+.B /proc
+file system, which is mounted at
+.B /proc
+and also posted as
+.BR /srv/armproc ,
+cf.
+.IR srv (3).
+.TP
+.B -b
+Supplying
+.B -b
+causes failing processes to call
+.IR abort (2)
+instead of
+.IR sysfatal (2),
+but see below.
+.SH SOURCE
+.B /sys/src/cmd/5e
+.SH SEE ALSO
+.IR 5i (1)
+.SH BUGS
+The host is required to be little endian and is assumed to have a floating point implementation conforming to IEEE 754.
+
+Broken processes are simulated in a rather unsatisfactory manner.
+The
+.B -b
+option leaks memory.
+The emulator does not post
+.B sys:
+notes.
+
+Obscure opcodes, in particular uncommon operations on R15, are not implemented.
+Careless use of the
+.B LDREX
+and
+.B STREX
+instructions can lead to deadlock, however a real processor is supposed behave undefined in these cases.
+
+Accesses spanning segment boundaries will be treated like page faults.
+Many syscalls like
+.IR pread (2)
+will shuffle data around (in most cases unnecessarily), if invoked on potentially shared segments of variable length, in particular the bss segment.
+
+FPA emulation leaves much to desire, rounding modes are ignored, all calculations are performed at extended precision.
+Floating point exceptions crash the emulator.
+
+Several syscalls, most notably the
+.IR segattach (2)
+family, are not implemented (this should not be hard to fix).
+The emulator notes the value of
+.IR errstr (2)
+only under obvious circumstances; with most syscalls only if the return value is negative.
+
+.B /proc
+emulation is more than unsatisfactory.
+
+The
+.I text
+argument should behave more like it would if it was entered in
+.IR rc (1).
--- a/sys/man/1/ls
+++ b/sys/man/1/ls
@@ -10,7 +10,7 @@
.PP
.B lc
[
-.B -dlmnqrstuFQT
+.B -dlmnqrstuQT
]
.I name ...
.SH DESCRIPTION
--- a/sys/src/boot/pc/pbs.s
+++ b/sys/src/boot/pc/pbs.s
@@ -107,7 +107,7 @@
CLR(rCX)
LB(_nfats(SB), rCL)
MUL(rCX)
- OR(rCX, rCX)
+ OR(rAX, rAX)
JNE _fatszok /* zero? it's FAT32 */
LW(_fatsz32hi(SB), rBX)
--- a/sys/src/cmd/5e/5e.c
+++ b/sys/src/cmd/5e/5e.c
@@ -4,10 +4,9 @@
#include "dat.h"
#include "fns.h"
-Process **PP;
+int nflag, pflag, bflag;
+Ref nproc;
-static int nflag;
-
void
dump(void)
{@@ -37,8 +36,12 @@
if(P == nil)
return;
+ remproc(P);
+ decref(&nproc);
freesegs();
fddecref(P->fd);
+ if(P->path != nil && decref(P->path) == 0)
+ free(P->path);
free(P);
}
@@ -45,15 +48,61 @@
static void
usage(void)
{- fprint(2, "usage: 5e [ -n ] text [ args ]\n");
+ fprint(2, "usage: 5e [-npb] text [...]\n");
exits(nil);
}
void
+suicide(char *fmt, ...)
+{+ va_list va;
+ char buf[1024];
+
+ va_start(va, fmt);
+ vsnprint(buf, sizeof(buf), fmt, va);
+ va_end(va);
+ fprint(2, "%s\n", buf);
+ if(!bflag)
+ exits(buf);
+ abort();
+}
+
+int
+notehandler(void *, char *note)
+{+ if(strncmp(note, "sys:", 4) == 0)
+ return 0;
+
+ if(strncmp(note, "emu:", 4) == 0)
+ exits(note);
+
+ addnote(note);
+ return 1;
+}
+
+static void
+dotext(int argc, char **argv)
+{+ char *file;
+
+ if(**argv == '/' || **argv == '.' || **argv == '#') {+ if(loadtext(*argv, argc, argv) < 0)
+ sysfatal("loadtext: %r");+ return;
+ }
+ file = smprint("/bin/%s", *argv);+ if(loadtext(file, argc, argv) < 0)
+ sysfatal("loadtext: %r");+ free(file);
+}
+
+void
main(int argc, char **argv)
{ ARGBEGIN {case 'n': nflag++; break;
+ case 'p': pflag++; break;
+ case 'b': bflag++; break;
default: usage();
} ARGEND;
if(argc < 1)
@@ -63,14 +112,20 @@
if(rfork(RFREND | RFNAMEG | RFENVG) < 0)
sysfatal("rfork: %r");atexit(cleanup);
- if(nflag)
+ if(!nflag)
adjustns();
+ if(pflag)
+ initfs("armproc", "/proc");initproc();
- if(loadtext(argv[0], argc, argv) < 0)
- sysfatal("%r");+ dotext(argc, argv);
+ atnotify(notehandler, 1);
for(;;) {if(ultraverbose)
dump();
step();
+ while((P->notein - P->noteout) % NNOTE) {+ donote(P->notes[P->noteout % NNOTE], 0);
+ ainc(&P->noteout);
+ }
}
}
--- a/sys/src/cmd/5e/arm.c
+++ b/sys/src/cmd/5e/arm.c
@@ -19,10 +19,10 @@
fH = 1<<5,
};
-static void
+void
invalid(u32int instr)
{- sysfatal("undefined instruction %8ux @ %8ux", instr, P->R[15] - 4);+ suicide("undefined instruction %8ux @ %8ux", instr, P->R[15] - 4);}
static u32int
@@ -81,7 +81,7 @@
addr = *Rn;
if(instr & fP)
addr += offset;
- targ = vaddr(addr, &seg);
+ targ = vaddr(addr, 4, &seg);
switch(instr & (fB | fL)) {case 0:
*(u32int*) targ = *Rd;
@@ -120,7 +120,7 @@
Rn = P->R + ((instr >> 16) & 15);
if(Rm == P->R + 15 || Rd == P->R + 15 || Rn == P->R + 15)
invalid(instr);
- targ = (u32int *) vaddr(*Rn, &seg);
+ targ = (u32int *) vaddr(*Rn, 4, &seg);
lock(&seg->lock);
if(instr & fB) {tmp = *(u8int*) targ;
@@ -256,11 +256,11 @@
if(instr & fP)
target += offset;
switch(instr & (fSg | fH | fL)) {- case fSg: *(u8int*) vaddr(target, &seg) = *Rd; break;
- case fSg | fL: *Rd = (long) *(char*) vaddr(target, &seg); break;
- case fH: case fSg | fH: *(u16int*) vaddr(target, &seg) = *Rd; break;
- case fH | fL: *Rd = *(u16int*) vaddr(target, &seg); break;
- case fH | fL | fSg: *Rd = (long) *(short*) vaddr(target, &seg); break;
+ case fSg: *(u8int*) vaddr(target, 1, &seg) = *Rd; break;
+ case fSg | fL: *Rd = (long) *(char*) vaddr(target, 1, &seg); break;
+ case fH: case fSg | fH: *(u16int*) vaddr(target, 2, &seg) = *Rd; break;
+ case fH | fL: *Rd = *(u16int*) vaddr(target, 2, &seg); break;
+ case fH | fL | fSg: *Rd = (long) *(short*) vaddr(target, 2, &seg); break;
}
segunlock(seg);
if(!(instr & fP))
@@ -289,9 +289,9 @@
if(instr & fP)
targ += 4;
if(instr & fL)
- P->R[i] = *(u32int*) vaddr(targ, &seg);
+ P->R[i] = *(u32int*) vaddr(targ, 4, &seg);
else
- *(u32int*) vaddr(targ, &seg) = P->R[i];
+ *(u32int*) vaddr(targ, 4, &seg) = P->R[i];
segunlock(seg);
if(!(instr & fP))
targ += 4;
@@ -303,9 +303,9 @@
if(instr & fP)
targ -= 4;
if(instr & fL)
- P->R[i] = *(u32int*) vaddr(targ, &seg);
+ P->R[i] = *(u32int*) vaddr(targ, 4, &seg);
else
- *(u32int*) vaddr(targ, &seg) = P->R[i];
+ *(u32int*) vaddr(targ, 4, &seg) = P->R[i];
segunlock(seg);
if(!(instr & fP))
targ -= 4;
@@ -382,7 +382,7 @@
if(Rd == P->R + 15 || Rn == P->R + 15)
invalid(instr);
if(instr & fS) {- targ = vaddr(*Rn, &seg);
+ targ = vaddr(*Rn, 4, &seg);
lock(&seg->lock);
*Rd = *targ;
segunlock(seg);
@@ -390,11 +390,11 @@
Rm = P->R + (instr & 15);
if(Rm == P->R + 15)
invalid(instr);
- targ = vaddr(*Rn, &seg);
+ targ = vaddr(*Rn, 4, &seg);
if(canlock(&seg->lock)) {*Rd = 1;
} else {- *targ = *Rd;
+ *targ = *Rm;
unlock(&seg->lock);
*Rd = 0;
}
@@ -408,7 +408,7 @@
u32int instr;
Segment *seg;
- instr = *(u32int*) vaddr(P->R[15], &seg);
+ instr = *(u32int*) vaddr(P->R[15], 4, &seg);
segunlock(seg);
if(fulltrace) { print("%d ", P->pid);@@ -467,6 +467,12 @@
syscall();
else if((instr & (7<<25)) == (4 << 25))
block(instr);
+ else if((instr & 0x0E000F00) == 0x0C000100)
+ fpatransfer(instr);
+ else if((instr & 0x0E000F10) == 0x0E000100)
+ fpaoperation(instr);
+ else if((instr & 0x0E000F10) == 0x0E000110)
+ fparegtransfer(instr);
else
invalid(instr);
}
--- a/sys/src/cmd/5e/dat.h
+++ b/sys/src/cmd/5e/dat.h
@@ -4,10 +4,9 @@
typedef struct Fd Fd;
enum {- STACKTOP = 0x80000000UL,
- STACKSIZE = 0x10000,
-
- FDBLOCK = 16,
+ STACKSIZE = 0x100000,
+ NAMEMAX = 27,
+ NNOTE = 5,
SEGNUM = 8,
flN = 1<<31,
@@ -25,17 +24,35 @@
};
struct Process {- Segment* S[SEGNUM];
+ Process *prev, *next; /* linked list (for fs) */
+ int pid;
+ char name[NAMEMAX+1]; /* name for status file */
+ Ref *path; /* Ref + string data */
+
+ Segment *S[SEGNUM]; /* memory */
u32int R[16]; /* general purpose registers / PC (R15) */
u32int CPSR; /* status register */
+
+ u32int FPSR;
+ long double F[8];
+
char errbuf[ERRMAX];
- Fd *fd;
- int pid;
+ Fd *fd; /* bitmap of OCEXEC files */
+
+ /* note handling */
+ u32int notehandler;
+ int innote;
+ jmp_buf notejmp;
+ char notes[ERRMAX][NNOTE];
+ long notein, noteout;
};
extern void **_privates;
extern int _nprivates;
#define P (*(Process**)_privates)
+extern Ref nproc;
+extern Process plist;
+extern Lock plistlock;
enum {SEGFLLOCK = 1,
@@ -44,16 +61,16 @@
struct Segment {Ref;
int flags;
- RWLock rw; /* lock for SEGLOCK segments */
+ RWLock rw; /* lock for SEGFLLOCK segments */
Lock lock; /* atomic accesses */
u32int start, size;
void *data;
- Ref *ref;
+ Ref *dref;
};
struct Fd {RWLock;
- Ref ref;
+ Ref;
u8int *fds;
int nfds;
};
@@ -62,4 +79,3 @@
#define havesymbols 0
#define ultraverbose 0
#define systrace 0
-
--- a/sys/src/cmd/5e/fns.h
+++ b/sys/src/cmd/5e/fns.h
@@ -4,8 +4,8 @@
void initproc(void);
int loadtext(char *, int, char **);
Segment *newseg(u32int, u32int, int);
-void *vaddr(u32int, Segment **);
-void *vaddrnol(u32int);
+void *vaddr(u32int, u32int, Segment **);
+void *vaddrnol(u32int, u32int);
void step(void);
void syscall(void);
void cherrstr(char *, ...);
@@ -20,4 +20,18 @@
void segunlock(Segment *);
void *copyifnec(u32int, int, int *);
void *bufifnec(u32int, int, int *);
-void copyback(u32int, int, void *);
\ No newline at end of file
+void copyback(u32int, int, void *);
+void initfs(char *, char *);
+void suicide(char *, ...);
+void fdclear(Fd *);
+void addproc(Process *);
+void remproc(Process *);
+Process *findproc(int);
+void donote(char *, ulong);
+void addnote(char *);
+void dump(void);
+void resetfpa(void);
+void invalid(u32int);
+void fpatransfer(u32int);
+void fpaoperation(u32int);
+void fparegtransfer(u32int);
--- /dev/null
+++ b/sys/src/cmd/5e/fpa.c
@@ -1,0 +1,148 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <bio.h>
+#include <mach.h>
+#include "dat.h"
+#include "fns.h"
+
+void
+resetfpa(void)
+{+ int i;
+
+ P->FPSR = 0x81000000;
+ for(i = 0; i < 8; i++)
+ P->F[i] = 0;
+}
+
+void
+fpatransfer(u32int instr)
+{+ enum {+ fP = 1<<24,
+ fU = 1<<23,
+ fT1 = 1<<22,
+ fW = 1<<21,
+ fL = 1<<20,
+ fT0 = 1<<15,
+ };
+
+ long double *Fd;
+ u32int *Rn, addr;
+ int off;
+ void *targ;
+ Segment *seg;
+
+ Rn = P->R + ((instr >> 16) & 15);
+ Fd = P->F + ((instr >> 12) & 7);
+ if(Rn == P->R + 15)
+ invalid(instr);
+ off = (instr & 255) * 4;
+ if(!(instr & fU))
+ off = -off;
+ addr = *Rn;
+ if(instr & fP)
+ addr += off;
+ targ = vaddr(addr, 8, &seg);
+ switch(instr & (fT0 | fT1 | fL)) {+ case 0: *(float *) targ = *Fd; break;
+ case fL: *Fd = *(float *) targ; break;
+ case fT0: *(double *) targ = *Fd; break;
+ case fT0 | fL: *Fd = *(double *) targ; break;
+ default: invalid(instr);
+ }
+ segunlock(seg);
+ if(!(instr & fP))
+ addr += off;
+ if(instr & fW)
+ *Rn = addr;
+}
+
+static long double
+fpasecop(u32int instr)
+{+ switch(instr & 15) {+ case 8: return 0.0; break;
+ case 9: return 1.0; break;
+ case 10: return 2.0; break;
+ case 11: return 3.0; break;
+ case 12: return 4.0; break;
+ case 13: return 5.0; break;
+ case 14: return 0.5; break;
+ case 15: return 10.0; break;
+ }
+ return P->F[instr & 7];
+}
+
+void
+fpaoperation(u32int instr)
+{+ long double *Fn, *Fd, op, op2, res;
+ int prec, opc;
+
+ Fn = P->F + ((instr >> 16) & 7);
+ Fd = P->F + ((instr >> 12) & 7);
+ op2 = fpasecop(instr);
+ op = *Fn;
+ prec = ((instr >> 7) & 1) | ((instr >> 18) & 2);
+ opc = ((instr >> 20) & 15) | ((instr >> 11) & 16);
+ switch(opc) {+ case 0: res = op + op2; break;
+ case 1: res = op * op2; break;
+ case 2: res = op - op2; break;
+ case 3: res = op2 - op; break;
+ case 4: res = op / op2; break;
+ case 5: res = op2 / op; break;
+ case 16: res = op2; break;
+ case 17: res = - op2; break;
+ case 18: res = fabs(op2); break;
+ case 19: res = (vlong) op2; break;
+ case 20: res = sqrt(op2); break;
+ default: sysfatal("unimplemented FPA operation %#x @ %8ux", opc, P->R[15] - 4);+ }
+ switch(prec) {+ case 0: *Fd = (float) res; break;
+ case 1: *Fd = (double) res; break;
+ case 2: *Fd = res; break;
+ default: invalid(instr);
+ }
+}
+
+void
+fparegtransfer(u32int instr)
+{+ u32int *Rd;
+ long tmp;
+ long double *Fn, op, op2;
+
+ Rd = P->R + ((instr >> 12) & 15);
+ Fn = P->F + ((instr >> 16) & 7);
+ op = fpasecop(instr);
+ if(Rd == P->R + 15) {+ op2 = *Fn;
+ switch((instr >> 21) & 7) {+ case 4: break;
+ case 5: op = - op; break;
+ default: invalid(instr);
+ }
+ if(op2 < op)
+ P->CPSR = (P->CPSR & ~FLAGS) | flN;
+ else if(op2 >= op) {+ P->CPSR = (P->CPSR & ~FLAGS) | flC;
+ if(op2 == op)
+ P->CPSR |= flZ;
+ } else
+ P->CPSR = (P->CPSR & ~FLAGS) | flV;
+ return;
+ }
+ if(instr & (1<<3))
+ invalid(instr);
+ switch((instr >> 20) & 15) {+ case 0: *Fn = *(long *) Rd; break;
+ case 1: tmp = op; *Rd = tmp; break;
+ case 2: P->FPSR = *Rd; break;
+ case 3: *Rd = P->FPSR; break;
+ default: invalid(instr);
+ }
+}
--- /dev/null
+++ b/sys/src/cmd/5e/fs.c
@@ -1,0 +1,437 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include "dat.h"
+#include "fns.h"
+
+static char *luser;
+extern int pflag;
+
+enum
+{+ Qdir,
+ Qtrace,
+ Qargs,
+ Qctl,
+ Qfd,
+ Qfpregs,
+ Qkregs,
+ Qmem,
+ Qnote,
+ Qnoteid,
+ Qnotepg,
+ Qns,
+ Qproc,
+ Qregs,
+ Qsegment,
+ Qstatus,
+ Qtext,
+ Qwait,
+ Qprofile,
+ Qsyscall,
+ NQid,
+};
+
+typedef struct Aux Aux;
+typedef struct Dirtab Dirtab;
+struct Dirtab {+ char name[28];
+ Qid qid;
+ vlong length;
+ long perm;
+};
+struct Aux {+ Process *p;
+ int fd;
+ Dirtab *d;
+};
+
+Dirtab procdir[] =
+{+ "args", {Qargs}, 0, 0660,+ "ctl", {Qctl}, 0, 0600,+ "fd", {Qfd}, 0, 0444,+ "fpregs", {Qfpregs}, 0, 0400,+ "kregs", {Qkregs}, 18 * 4, 0400,+ "mem", {Qmem}, 0, 0400,+ "note", {Qnote}, 0, 0000,+ "noteid", {Qnoteid}, 0, 0664,+ "notepg", {Qnotepg}, 0, 0000,+ "ns", {Qns}, 0, 0444,+ "proc", {Qproc}, 0, 0400,+ "regs", {Qregs}, 18 * 4, 0400,+ "segment", {Qsegment}, 0, 0444,+ "status", {Qstatus}, 176, 0444,+ "text", {Qtext}, 0, 0400,+ "wait", {Qwait}, 0, 0400,+ "profile", {Qprofile}, 0, 0400,+ "syscall", {Qsyscall}, 0, 0400, + "", {0}, 0, 0,+};
+
+static char *
+readin(int pid, char *file)
+{+ char *name, *buf;
+ int fd, rc;
+
+ name = smprint("#p/%d/%s", pid, file);+ fd = open(name, OREAD);
+ if(fd < 0)
+ return nil;
+ buf = malloc(1024);
+ rc = read(fd, buf, 1023);
+ if(rc < 0)
+ return nil;
+ buf[rc] = 0;
+ free(name);
+ close(fd);
+ return buf;
+}
+
+static int
+calcmem(Process *p)
+{+ int i, r;
+
+ r = 0;
+ for(i = 0; i < SEGNUM; i++) {+ if(i == SEGSTACK)
+ continue;
+ if(p->S[i] == nil)
+ continue;
+ r += p->S[i]->size;
+ }
+ r = (r + 1023) / 1024;
+ return r;
+}
+
+static int
+copymem(Process *p, char *buf, u32int addr, int len)
+{+ int i, n, r;
+
+ r = len;
+ while(len > 0) {+ for(i = 0; i < SEGNUM; i++) {+ if(p->S[i] == nil)
+ continue;
+ if(p->S[i]->start <= addr && p->S[i]->start + p->S[i]->size > addr)
+ break;
+ }
+ if(i == SEGNUM) {+ werrstr("bad arg in syscall");+ return -1;
+ }
+ n = p->S[i]->start + p->S[i]->size - addr;
+ if(n > len)
+ n = len;
+ memcpy(buf, (char*)p->S[i]->data + addr - p->S[i]->start, n);
+ len -= n;
+ buf += n;
+ }
+ return r;
+}
+
+static char *
+segments(Process *p)
+{+ char *r, *s;
+ static char *names[] = {+ [SEGTEXT] "Text",
+ [SEGSTACK] "Stack",
+ [SEGDATA] "Data",
+ [SEGBSS] "Bss",
+ };
+ int i;
+
+ r = emalloc(1024);
+ s = r;
+ for(i = 0; i < SEGNUM; i++) {+ if(p->S[i] == nil)
+ continue;
+ s += sprint(s, "%-7s%c %.8ux %.8ux %4ld\n", names[i], i == SEGTEXT ? 'R' : ' ', p->S[i]->start, p->S[i]->start + p->S[i]->size, p->S[i]->dref->ref);
+ }
+ return r;
+}
+
+static void
+procattach(Req *req)
+{+ req->fid->qid = (Qid) {0, 0, 0x80};+ req->fid->aux = emallocz(sizeof(Aux));
+ ((Aux *) req->fid->aux)->fd = -1;
+ req->ofcall.qid = req->fid->qid;
+ respond(req, nil);
+}
+
+static char *
+procwalk(Fid *fid, char *name, Qid *qid)
+{+ int pid;
+ char buf[20];
+ Dirtab *d;
+ Aux *a;
+
+ a = fid->aux;
+ if(fid->qid.path == 0) {+ pid = atoi(name);
+ sprint(buf, "%d", pid);
+ if(strcmp(buf, name) != 0 || (a->p = findproc(pid)) == nil)
+ return "file does not exist";
+ *qid = (Qid) {pid * NQid, 0, 0x80};+ fid->qid = *qid;
+ return nil;
+ }
+ if((fid->qid.path % NQid) == 0) {+ for(d = procdir; d->name[0] != 0; d++)
+ if(strcmp(d->name, name) == 0)
+ break;
+ if(d->name[0] == 0)
+ return "file does not exist";
+ *qid = d->qid;
+ qid->path += fid->qid.path;
+ fid->qid = *qid;
+ a->d = d;
+ return nil;
+ }
+ return "the front fell off";
+}
+
+static char *
+procclone(Fid *old, Fid *new)
+{+ new->aux = emallocz(sizeof(Aux));
+ memcpy(new->aux, old->aux, sizeof(Aux));
+ return nil;
+}
+
+static void
+procopen(Req *req)
+{+ Aux *a;
+
+ a = req->fid->aux;
+ switch((int)(req->fid->qid.path % NQid)) {+ case Qtext:
+ a->fd = open((char*)(a->p->path + 1), OREAD);
+ break;
+ default:
+ respond(req, nil);
+ return;
+ }
+ if(a->fd < 0)
+ responderror(req);
+ else
+ respond(req, nil);
+}
+
+static void
+procdestroyfid(Fid *fid)
+{+ Aux *a;
+
+ a = fid->aux;
+ free(a);
+}
+
+static int
+procgen(int n, Dir *d, void *)
+{+ int i;
+ Process *p;
+
+ p = &plist;
+ for(i = 0;; i++) {+ p = p->next;
+ if(p == &plist)
+ return -1;
+ if(i == n)
+ break;
+ }
+ d->uid = estrdup9p(luser);
+ d->gid = estrdup9p(luser);
+ d->muid = estrdup9p(luser);
+ d->name = smprint("%d", p->pid);+ d->mode = DMDIR | 0555;
+ d->qid = (Qid) {p->pid * NQid, 0, 0x80};+ return 0;
+}
+
+static int
+procsubgen(int n, Dir *d, void *)
+{+ Dirtab *di;
+
+ if(n >= nelem(procdir) - 1)
+ return -1;
+
+ di = procdir + n;
+ d->uid = estrdup9p(luser);
+ d->gid = estrdup9p(luser);
+ d->muid = estrdup9p(luser);
+ d->name = estrdup9p(di->name);
+ d->mode = di->perm;
+ d->length = di->length;
+ d->qid = di->qid;
+ return 0;
+}
+
+static void
+procread(Req *req)
+{+ Aux *a;
+ Process *p;
+ char *buf;
+ int rc;
+
+ a = req->fid->aux;
+ if(a == nil) {+ respond(req, "the front fell off");
+ return;
+ }
+ if(req->fid->qid.path == 0) {+ dirread9p(req, procgen, nil);
+ respond(req, nil);
+ return;
+ }
+ p = a->p;
+ switch((int)(req->fid->qid.path % NQid)) {+ case Qdir:
+ dirread9p(req, procsubgen, nil);
+ respond(req, nil);
+ break;
+ case Qstatus:
+ buf = readin(p->pid, "status");
+ if(buf == nil)
+ responderror(req);
+ else {+ memset(buf, ' ', 27);
+ memcpy(buf, p->name, strlen(p->name));
+ sprint(buf + 149, "%d", calcmem(p));
+ buf[strlen(buf)] = ' ';
+ readstr(req, buf);
+ free(buf);
+ respond(req, nil);
+ }
+ break;
+ case Qsegment:
+ buf = segments(p);
+ readstr(req, buf);
+ free(buf);
+ respond(req, nil);
+ break;
+ case Qtext:
+ rc = pread(a->fd, req->ofcall.data, req->ifcall.count, req->ifcall.offset);
+ if(rc >= 0) {+ req->ofcall.count = rc;
+ respond(req, nil);
+ } else
+ responderror(req);
+ break;
+ case Qmem:
+ rc = copymem(p, req->ofcall.data, req->ifcall.offset, req->ifcall.count);
+ if(rc >= 0) {+ req->ofcall.count = rc;
+ respond(req, nil);
+ } else
+ responderror(req);
+ break;
+ case Qregs:
+ buf = emallocz(18 * 4);
+ memcpy(buf, p->R, 15 * 4);
+ memcpy(buf + 16 * 4, &p->CPSR, 4);
+ memcpy(buf + 17 * 4, p->R + 15, 4);
+ readbuf(req, buf, 18 * 4);
+ free(buf);
+ respond(req, nil);
+ break;
+ default:
+ respond(req, "the front fell off");
+ }
+}
+
+static void
+writeto(Req *req, char *fmt, ...)
+{+ int fd, rc;
+ va_list va;
+ char *file;
+
+ va_start(va, fmt);
+ file = vsmprint(fmt, va);
+ va_end(va);
+ fd = open(file, OWRITE);
+ free(file);
+ if(fd < 0) {+ responderror(req);
+ return;
+ }
+ rc = write(fd, req->ifcall.data, req->ifcall.count);
+ req->ofcall.count = rc;
+ if(rc < req->ifcall.count)
+ responderror(req);
+ else
+ respond(req, nil);
+ close(fd);
+}
+
+static void
+procwrite(Req *req)
+{+ switch((int)(req->fid->qid.path % NQid)) {+ case Qnote:
+ writeto(req, "#p/%lld/note", req->fid->qid.path / NQid);
+ break;
+ default:
+ respond(req, "the front fell off");
+ }
+}
+
+static void
+procstat(Req *req)
+{+ Aux *a;
+ Dir *d;
+
+ d = &req->d;
+ a = req->fid->aux;
+ if(a == nil) {+ respond(req, "the front fell off");
+ return;
+ }
+ d->qid = req->fid->qid;
+ if(a->d != nil) {+ d->mode = a->d->perm;
+ d->length = a->d->length;
+ d->name = strdup(a->d->name);
+ } else {+ d->mode = 0555 | DMDIR;
+ if(d->qid.path != 0)
+ d->name = smprint("%lld", d->qid.path / NQid);+ }
+ d->uid = strdup(luser);
+ d->gid = strdup(luser);
+ d->muid = strdup(luser);
+ respond(req, nil);
+}
+
+static Srv procsrv = {+ .attach = procattach,
+ .walk1 = procwalk,
+ .clone = procclone,
+ .destroyfid = procdestroyfid,
+ .open = procopen,
+ .read = procread,
+ .stat = procstat,
+};
+
+void
+initfs(char *name, char *mtpt)
+{+ luser = getuser();
+ remove("/srv/armproc");+ postmountsrv(&procsrv, name, mtpt, MREPL);
+}
--- a/sys/src/cmd/5e/mkfile
+++ b/sys/src/cmd/5e/mkfile
@@ -1,7 +1,7 @@
</$objtype/mkfile
TARG=5e
-OFILES=5e.$O seg.$O proc.$O util.$O arm.$O sys.$O
+OFILES=5e.$O seg.$O proc.$O util.$O arm.$O sys.$O fs.$O fpa.$O
HFILES=dat.h fns.h
BIN=/$objtype/bin
--- a/sys/src/cmd/5e/proc.c
+++ b/sys/src/cmd/5e/proc.c
@@ -8,6 +8,9 @@
#include "dat.h"
#include "fns.h"
+Process plist;
+Lock plistlock;
+
void
initproc(void)
{@@ -14,14 +17,74 @@
P = emallocz(sizeof(Process));
P->pid = getpid();
P->fd = newfd();
+ incref(&nproc);
+ plist.prev = P;
+ plist.next = P;
+ P->prev = &plist;
+ P->next = &plist;
+ resetfpa();
}
+void
+addproc(Process *p)
+{+ lock(&plistlock);
+ p->prev = plist.prev;
+ p->next = &plist;
+ plist.prev->next = p;
+ plist.prev = p;
+ unlock(&plistlock);
+}
+
+void
+remproc(Process *p)
+{+ lock(&plistlock);
+ p->prev->next = p->next;
+ p->next->prev = p->prev;
+ unlock(&plistlock);
+}
+
+Process *
+findproc(int pid)
+{+ Process *p;
+
+ lock(&plistlock);
+ for(p = plist.next; p != &plist; p = p->next)
+ if(p->pid == pid)
+ break;
+ unlock(&plistlock);
+ if(p != &plist)
+ return p;
+ return nil;
+}
+
static void
+copyname(char *file)
+{+ char *p;
+
+ p = strrchr(file, '/');
+ if(p == nil)
+ p = file;
+ else
+ p++;
+ strncpy(P->name, p, NAMEMAX);
+
+ if(P->path != nil && decref(P->path) == 0)
+ free(P->path);
+ P->path = emallocz(5 + strlen(file));
+ incref(P->path);
+ strcpy((char*)(P->path + 1), file);
+}
+
+static void
initstack(int argc, char **argv)
{ulong tos, sp, ap, size, i, len;
- tos = STACKTOP - sizeof(Tos) * 2;
+ tos = mach->utop - sizeof(Tos) * 2;
sp = tos;
size = 8;
@@ -31,22 +94,22 @@
sp -= size;
sp &= ~7;
P->R[0] = tos;
- P->R[1] = STACKTOP - 4;
+ P->R[1] = mach->utop - 4;
P->R[13] = sp;
- *(ulong *) vaddrnol(sp) = argc;
+ *(ulong *) vaddrnol(sp, 4) = argc;
sp += 4;
ap = sp + (argc + 1) * 4;
for(i = 0; i < argc; i++) {- *(ulong *) vaddrnol(sp) = ap;
+ *(ulong *) vaddrnol(sp, 4) = ap;
sp += 4;
len = strlen(argv[i]) + 1;
- memcpy(vaddrnol(ap), argv[i], len);
+ memcpy(vaddrnol(ap, len), argv[i], len);
ap += len;
}
- *(ulong *) vaddrnol(sp) = 0;
+ *(ulong *) vaddrnol(sp, 4) = 0;
- ((Tos *) vaddrnol(tos))->pid = getpid();
+ ((Tos *) vaddrnol(tos, sizeof(Tos)))->pid = getpid();
}
static int
@@ -104,9 +167,9 @@
int
loadtext(char *file, int argc, char **argv)
{- int fd, i;
+ int fd;
Fhdr fp;
- Segment *text, *data, *bss, *stack;
+ Segment *text, *data, *bss;
char buf[2];
fd = open(file, OREAD);
@@ -114,14 +177,12 @@
if(pread(fd, buf, 2, 0) == 2 && buf[0] == '#' && buf[1] == '!')
return loadscript(fd, file, argc, argv);
seek(fd, 0, 0);
- if(crackhdr(fd, &fp) == 0) {+ if(crackhdr(fd, &fp) == 0 || fp.magic != E_MAGIC) { werrstr("exec header invalid");return -1;
}
- if(fp.magic != E_MAGIC) {- werrstr("exec header invalid");- return -1;
- }
+ copyname(file);
+ P->notehandler = P->innote = P->notein = P->noteout = 0;
freesegs();
memset(P->R, 0, sizeof(P->R));
P->CPSR = 0;
@@ -128,7 +189,7 @@
text = newseg(fp.txtaddr - fp.hdrsz, fp.txtsz + fp.hdrsz, SEGTEXT);
data = newseg(fp.dataddr, fp.datsz, SEGDATA);
bss = newseg(fp.dataddr + fp.datsz, fp.bsssz, SEGBSS);
- stack = newseg(STACKTOP - STACKSIZE, STACKSIZE, SEGSTACK);
+ newseg(mach->utop - STACKSIZE, STACKSIZE, SEGSTACK);
seek(fd, fp.txtoff - fp.hdrsz, 0);
if(readn(fd, text->data, fp.txtsz + fp.hdrsz) < fp.txtsz + fp.hdrsz)
sysfatal("%r");@@ -136,20 +197,13 @@
if(readn(fd, data->data, fp.datsz) < fp.datsz)
sysfatal("%r");memset(bss->data, 0, bss->size);
- memset(stack->data, 0, stack->size);
P->R[15] = fp.entry;
if(havesymbols && syminit(fd, &fp) < 0)
fprint(2, "initializing symbol table: %r\n");
close(fd);
- for(i = 0; i < P->fd->nfds * 8; i++)
- if(iscexec(P->fd, i))
- close(i);
- wlock(P->fd);
- free(P->fd->fds);
- P->fd->fds = nil;
- P->fd->nfds = 0;
- wunlock(P->fd);
+ fdclear(P->fd);
initstack(argc, argv);
+ resetfpa();
return 0;
}
@@ -178,7 +232,7 @@
Fd *fd;
fd = emallocz(sizeof(*fd));
- incref(&fd->ref);
+ incref(fd);
return fd;
}
@@ -201,7 +255,7 @@
void
fddecref(Fd *fd)
{- if(decref(&fd->ref) == 0) {+ if(decref(fd) == 0) {free(fd->fds);
free(fd);
}
@@ -241,4 +295,89 @@
else
fd->fds[n / 8] |= (1 << (n % 8));
wunlock(fd);
+}
+
+void
+fdclear(Fd *fd)
+{+ int i, j, k;
+
+ wlock(fd);
+ if(fd->nfds == 0) {+ wunlock(fd);
+ return;
+ }
+ for(i = 0; i < fd->nfds; i++) {+ j = fd->fds[i];
+ for(k = 0; k < 8; k++)
+ if(j & (1<<k))
+ close(8 * i + k);
+ }
+ free(fd->fds);
+ fd->nfds = 0;
+ fd->fds = nil;
+ wunlock(fd);
+}
+
+/* call this from a notehandler if you don't want the front to fall off */
+void
+addnote(char *msg)
+{+ int new;
+
+ new = P->notein + 1;
+ if((new - P->noteout) % NNOTE == 0)
+ return;
+
+ strncpy(P->notes[P->notein % NNOTE], msg, ERRMAX - 1);
+ P->notein = new;
+}
+
+/* the following code is not for the weak of heart */
+void
+donote(char *msg, ulong type)
+{+ int rc;
+ u32int *ureg, *sp, uregp, msgp;
+ char *msgb;
+
+ if(P->notehandler == 0)
+ exits(msg);
+
+ uregp = P->R[13] - 18 * 4;
+ ureg = vaddrnol(uregp, 18 * 4);
+ memcpy(ureg, P->R, 15 * 4);
+ ureg[15] = type;
+ ureg[16] = P->CPSR;
+ ureg[17] = P->R[15];
+ P->R[13] = uregp;
+ msgp = P->R[13] -= strlen(msg) + 1;
+ msgb = vaddrnol(msgp, strlen(msg) + 1);
+ strcpy(msgb, msg);
+ P->R[13] -= 3 * 4;
+ sp = vaddrnol(P->R[13], 3 * 4);
+ sp[0] = 0;
+ sp[2] = msgp;
+ P->R[0] = uregp;
+ P->R[15] = P->notehandler;
+ P->innote = 1;
+ switch(rc = setjmp(P->notejmp) - 1) {+ case -1:
+ for(;;) {+ if(ultraverbose)
+ dump();
+ step();
+ }
+ case NDFLT:
+ exits(msg);
+ case NCONT:
+ break;
+ default:
+ sysfatal("unhandled noted argument %d", rc);+ }
+ P->innote = 0;
+ ureg = vaddrnol(uregp, 18 * 4); /* just to be sure */
+ memcpy(P->R, ureg, 15 * 4);
+ P->CPSR = ureg[16];
+ P->R[15] = ureg[17];
}
--- a/sys/src/cmd/5e/seg.c
+++ b/sys/src/cmd/5e/seg.c
@@ -13,10 +13,10 @@
incref(s);
s->start = start;
s->size = size;
- s->ref = emalloc(size + sizeof(Ref));
- memset(s->ref, 0, sizeof(Ref));
- incref(s->ref);
- s->data = s->ref + 1;
+ s->dref = emalloc(size + sizeof(Ref));
+ memset(s->dref, 0, sizeof(Ref));
+ incref(s->dref);
+ s->data = s->dref + 1;
if(idx == SEGBSS)
s->flags = SEGFLLOCK;
P->S[idx] = s;
@@ -31,8 +31,8 @@
for(s = P->S; s < P->S + SEGNUM; s++) {if(*s == nil)
continue;
- if(decref((*s)->ref) == 0)
- free((*s)->ref);
+ if(decref((*s)->dref) == 0)
+ free((*s)->dref);
if(decref(*s) == 0)
free(*s);
*s = nil;
@@ -40,7 +40,7 @@
}
void *
-vaddr(u32int addr, Segment **seg)
+vaddr(u32int addr, u32int len, Segment **seg)
{Segment **ss, *s;
@@ -49,6 +49,8 @@
continue;
s = *ss;
if(addr >= s->start && addr < s->start + s->size) {+ if(addr + len > s->start + s->size)
+ break;
if(s->flags & SEGFLLOCK)
rlock(&s->rw);
*seg = s;
@@ -55,17 +57,17 @@
return (char *)s->data + (addr - s->start);
}
}
- sysfatal("fault %.8ux @ %.8ux", addr, P->R[15]);+ suicide("fault %.8ux (%d) @ %.8ux", addr, len, P->R[15]);return nil;
}
void *
-vaddrnol(u32int addr)
+vaddrnol(u32int addr, u32int len)
{Segment *seg;
void *ret;
- ret = vaddr(addr, &seg);
+ ret = vaddr(addr, len, &seg);
segunlock(seg);
return ret;
}
@@ -84,7 +86,7 @@
void *targ, *ret;
Segment *seg;
- targ = vaddr(addr, &seg);
+ targ = vaddr(addr, len > 0 ? len : 0, &seg);
if((seg->flags & SEGFLLOCK) == 0) {*copied = 0;
return targ;
@@ -92,6 +94,7 @@
if(len < 0)
len = strlen(targ) + 1;
ret = emalloc(len);
+ setmalloctag(ret, getcallerpc(&addr));
memcpy(ret, targ, len);
segunlock(seg);
*copied = 1;
@@ -101,10 +104,10 @@
void *
bufifnec(u32int addr, int len, int *buffered)
{- void *targ;
+ void *targ, *v;
Segment *seg;
- targ = vaddr(addr, &seg);
+ targ = vaddr(addr, len, &seg);
if((seg->flags & SEGFLLOCK) == 0) {*buffered = 0;
return targ;
@@ -111,7 +114,9 @@
}
segunlock(seg);
*buffered = 1;
- return emalloc(len);
+ v = emalloc(len);
+ setmalloctag(v, getcallerpc(&addr));
+ return v;
}
void
@@ -120,9 +125,11 @@
void *targ;
Segment *seg;
- if(len <= 0)
+ if(len <= 0) {+ free(data);
return;
- targ = vaddr(addr, &seg);
+ }
+ targ = vaddr(addr, len, &seg);
memmove(targ, data, len);
segunlock(seg);
free(data);
--- a/sys/src/cmd/5e/sys.c
+++ b/sys/src/cmd/5e/sys.c
@@ -9,7 +9,7 @@
arg(int n)
{/* no locking necessary, since we're on the stack */
- return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n);
+ return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4);
}
static u64int
@@ -127,7 +127,7 @@
vlong n, *ret;
Segment *seg;
- ret = vaddr(arg(0), &seg);
+ ret = vaddr(arg(0), 8, &seg);
fd = arg(1);
n = argv(2);
type = arg(4);
@@ -197,12 +197,52 @@
}
static void
+syswstat(void)
+{+ u32int name, edir, nedir;
+ char *namet;
+ void *edirt;
+ int copied, copied2;
+
+ name = arg(0);
+ namet = copyifnec(name, -1, &copied);
+ edir = arg(1);
+ nedir = arg(2);
+ edirt = copyifnec(edir, nedir, &copied2);
+ if(systrace)
+ fprint(2, "wstat(%#ux=\"%s\", %#ux, %ud)\n", name, namet, edir, nedir);
+ P->R[0] = noteerr(wstat(namet, edirt, nedir), nedir);
+ if(copied)
+ free(namet);
+ if(copied2)
+ free(edirt);
+}
+
+static void
+sysfwstat(void)
+{+ u32int fd, edir, nedir;
+ void *edirt;
+ int copied;
+
+ fd = arg(0);
+ edir = arg(1);
+ nedir = arg(2);
+ edirt = copyifnec(edir, nedir, &copied);
+ if(systrace)
+ fprint(2, "fwstat(%d, %#ux, %d)\n", fd, edir, nedir);
+ P->R[0] = noteerr(fwstat(fd, edirt, nedir), nedir);
+ if(copied)
+ free(edirt);
+}
+
+static void
sysexits(void)
{if(arg(0) == 0)
exits(nil);
else
- exits(vaddrnol(arg(0)));
+ exits(vaddrnol(arg(0), 0));
}
static void
@@ -218,10 +258,10 @@
sysfatal("bss length < 0, wtf?");s = P->S[SEGBSS];
wlock(&s->rw);
- s->ref = realloc(s->ref, v - s->start + 4);
- if(s->ref == nil)
+ s->dref = realloc(s->dref, v - s->start + 4);
+ if(s->dref == nil)
sysfatal("error reallocating");- s->data = s->ref + 1;
+ s->data = s->dref + 1;
if(s->size < v - s->start)
memset((char*)s->data + s->size, 0, v - s->start - s->size);
s->size = v - s->start;
@@ -266,9 +306,30 @@
static void
sysnotify(void)
{+ u32int handler;
+
+ handler = arg(0);
+ if(systrace)
+ fprint(2, "notify(%#ux)\n", handler);
+ P->notehandler = handler;
+ P->R[0] = 0;
}
static void
+sysnoted(void)
+{+ u32int v;
+
+ v = arg(0);
+ if(systrace)
+ fprint(2, "noted(%d)\n", v);
+ if(P->innote)
+ longjmp(P->notejmp, v + 1);
+ cherrstr("the front fell off");+ P->R[0] = -1;
+}
+
+static void
sysrfork(void)
{u32int flags;
@@ -276,16 +337,17 @@
Process *p;
Segment *s, *t;
Fd *old;
- enum {- RFORKPASS = RFENVG | RFCENVG | RFNOTEG | RFNOMNT | RFNAMEG | RFCNAMEG | RFNOWAIT | RFREND | RFFDG | RFCFDG,
- RFORKHANDLED = RFPROC | RFMEM,
- };
flags = arg(0);
if(systrace)
fprint(2, "rfork(%#o)\n", flags);
- if(flags & ~(RFORKPASS | RFORKHANDLED))
- sysfatal("rfork with unhandled flags %#o", flags & ~(RFORKPASS | RFORKHANDLED));+ if((flags & (RFFDG | RFCFDG)) == (RFFDG | RFCFDG) ||
+ (flags & (RFNAMEG | RFCNAMEG)) == (RFNAMEG | RFCNAMEG) ||
+ (flags & (RFENVG | RFCENVG)) == (RFENVG | RFCENVG)) {+ P->R[0] = -1;
+ cherrstr("bad arg in syscall");+ return;
+ }
if((flags & RFPROC) == 0) { if(flags & RFFDG) {old = P->fd;
@@ -297,9 +359,10 @@
P->fd = newfd();
fddecref(old);
}
- P->R[0] = noteerr(rfork(flags & RFORKPASS), 0);
+ P->R[0] = noteerr(rfork(flags), 0);
return;
}
+ incref(&nproc);
p = emallocz(sizeof(Process));
memcpy(p, P, sizeof(Process));
for(i = 0; i < SEGNUM; i++) {@@ -311,15 +374,15 @@
incref(t);
t->size = s->size;
t->start = s->start;
- t->ref = emalloc(sizeof(Ref) + s->size);
- memset(t->ref, 0, sizeof(Ref));
- incref(t->ref);
- t->data = t->ref + 1;
+ t->dref = emalloc(sizeof(Ref) + s->size);
+ memset(t->dref, 0, sizeof(Ref));
+ incref(t->dref);
+ t->data = t->dref + 1;
memcpy(t->data, s->data, s->size);
p->S[i] = t;
} else {+ incref(s->dref);
incref(s);
- incref(s->ref);
}
}
@@ -328,15 +391,17 @@
else if(flags & RFCFDG)
p->fd = newfd();
else
- incref(&P->fd->ref);
+ incref(P->fd);
- rc = rfork(RFPROC | RFMEM | (flags & RFORKPASS));
- if(rc < 0)
- sysfatal("rfork: %r");+ incref(P->path);
+ rc = rfork(RFMEM | flags);
+ if(rc < 0) /* this should NEVER happen */
+ sysfatal("rfork failed wtf: %r"); if(rc == 0) {P = p;
atexit(cleanup);
P->pid = getpid();
+ addproc(P);
}
P->R[0] = rc;
}
@@ -351,9 +416,9 @@
name = arg(0);
argv = arg(1);
- namet = strdup(vaddr(name, &seg1));
+ namet = strdup(vaddr(name, 0, &seg1));
segunlock(seg1);
- argvt = vaddr(argv, &seg1);
+ argvt = vaddr(argv, 0, &seg1);
if(systrace)
fprint(2, "exec(%#ux=\"%s\", %#ux)\n", name, namet, argv);
for(argc = 0; argvt[argc]; argc++)
@@ -360,7 +425,7 @@
;
argvv = emalloc(sizeof(char *) * argc);
for(i = 0; i < argc; i++) {- argvv[i] = strdup(vaddr(argvt[i], &seg2));
+ argvv[i] = strdup(vaddr(argvt[i], 0, &seg2));
segunlock(seg2);
}
segunlock(seg1);
@@ -537,6 +602,17 @@
free(filet);
}
+static void
+sysalarm(void)
+{+ u32int msec;
+
+ msec = arg(0);
+ if(systrace)
+ fprint(2, "alarm(%d)\n", msec);
+ P->R[0] = alarm(msec);
+}
+
void
syscall(void)
{@@ -552,10 +628,13 @@
[ERRSTR] syserrstr,
[STAT] sysstat,
[FSTAT] sysfstat,
+ [WSTAT] syswstat,
+ [FWSTAT] sysfwstat,
[SEEK] sysseek,
[CHDIR] syschdir,
[FD2PATH] sysfd2path,
[NOTIFY] sysnotify,
+ [NOTED] sysnoted,
[RFORK] sysrfork,
[EXEC] sysexec,
[AWAIT] sysawait,
@@ -567,6 +646,7 @@
[DUP] sysdup,
[MOUNT] sysmount,
[REMOVE] sysremove,
+ [ALARM] sysalarm,
};
n = P->R[0];
--- a/sys/src/cmd/5e/util.c
+++ b/sys/src/cmd/5e/util.c
@@ -12,6 +12,7 @@
v = malloc(size);
if(v == nil)
sysfatal("%r");+ setmalloctag(v, getcallerpc(&size));
return v;
}
@@ -22,6 +23,7 @@
v = emalloc(size);
memset(v, 0, size);
+ setmalloctag(v, getcallerpc(&size));
return v;
}
@@ -33,5 +35,6 @@
v = realloc(old, size);
if(v == nil)
sysfatal("%r");+ setrealloctag(v, getcallerpc(&old));
return v;
}
--- a/sys/src/cmd/python/plan9.c
+++ b/sys/src/cmd/python/plan9.c
@@ -4,14 +4,6 @@
#include <u.h>
#include <lib9.h>
-#if defined(T386)
-#define FPINVAL (1<<0)
-#elif defined(Tarm)
-#define FPINVAL (1<<16)
-#else
-Error define FPINVAL for your arch. grep /$cputype/include/u.h
-#endif
-
Threadarg *_threadarg;
extern DL_EXPORT(int) Py_Main(int, char **);
@@ -21,7 +13,14 @@
{Threadarg ta;
- setfcr(getfcr()&~FPINVAL);
+#if defined(T386)
+ setfcr(getfcr()&~(1<<0));
+#elif defined(Tarm)
+ setfsr(getfsr()&~(1<<16));
+#else
+Error define code for disabling fp exceptions for your arch.
+#endif
+
memset(&ta, 0, sizeof ta);
_threadarg = &ta;
if(setjmp(ta.jb)){--
⑨