5e: added note support
added wstat / fwstat / alarm
This commit is contained in:
parent
b4ae96bcb9
commit
0b22dfd1f6
7 changed files with 188 additions and 13 deletions
|
@ -67,6 +67,19 @@ suicide(char *fmt, ...)
|
||||||
abort();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -90,9 +103,14 @@ main(int argc, char **argv)
|
||||||
initproc();
|
initproc();
|
||||||
if(loadtext(argv[0], argc, argv) < 0)
|
if(loadtext(argv[0], argc, argv) < 0)
|
||||||
sysfatal("%r");
|
sysfatal("%r");
|
||||||
|
atnotify(notehandler, 1);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(ultraverbose)
|
if(ultraverbose)
|
||||||
dump();
|
dump();
|
||||||
step();
|
step();
|
||||||
|
while((P->notein - P->noteout) % NNOTE) {
|
||||||
|
donote(P->notes[P->noteout % NNOTE], 0);
|
||||||
|
ainc(&P->noteout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,8 @@ typedef struct Fd Fd;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STACKSIZE = 0x100000,
|
STACKSIZE = 0x100000,
|
||||||
|
|
||||||
NAMEMAX = 27,
|
NAMEMAX = 27,
|
||||||
|
NNOTE = 5,
|
||||||
FDBLOCK = 16,
|
|
||||||
SEGNUM = 8,
|
SEGNUM = 8,
|
||||||
|
|
||||||
flN = 1<<31,
|
flN = 1<<31,
|
||||||
|
@ -26,15 +24,24 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Process {
|
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 R[16]; /* general purpose registers / PC (R15) */
|
||||||
u32int CPSR; /* status register */
|
u32int CPSR; /* status register */
|
||||||
|
|
||||||
char errbuf[ERRMAX];
|
char errbuf[ERRMAX];
|
||||||
char name[NAMEMAX+1];
|
Fd *fd; /* bitmap of OCEXEC files */
|
||||||
Ref *path; /* Ref + string data */
|
|
||||||
Fd *fd;
|
/* note handling */
|
||||||
int pid;
|
u32int notehandler;
|
||||||
Process *prev, *next;
|
int innote;
|
||||||
|
jmp_buf notejmp;
|
||||||
|
char notes[ERRMAX][NNOTE];
|
||||||
|
long notein, noteout;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void **_privates;
|
extern void **_privates;
|
||||||
|
@ -69,4 +76,3 @@ struct Fd {
|
||||||
#define havesymbols 0
|
#define havesymbols 0
|
||||||
#define ultraverbose 0
|
#define ultraverbose 0
|
||||||
#define systrace 0
|
#define systrace 0
|
||||||
|
|
||||||
|
|
|
@ -27,3 +27,6 @@ void fdclear(Fd *);
|
||||||
void addproc(Process *);
|
void addproc(Process *);
|
||||||
void remproc(Process *);
|
void remproc(Process *);
|
||||||
Process *findproc(int);
|
Process *findproc(int);
|
||||||
|
void donote(char *, ulong);
|
||||||
|
void addnote(char *);
|
||||||
|
void dump(void);
|
||||||
|
|
|
@ -181,6 +181,7 @@ loadtext(char *file, int argc, char **argv)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
copyname(file);
|
copyname(file);
|
||||||
|
P->notehandler = P->innote = P->notein = P->noteout = 0;
|
||||||
freesegs();
|
freesegs();
|
||||||
memset(P->R, 0, sizeof(P->R));
|
memset(P->R, 0, sizeof(P->R));
|
||||||
P->CPSR = 0;
|
P->CPSR = 0;
|
||||||
|
@ -315,3 +316,66 @@ fdclear(Fd *fd)
|
||||||
fd->fds = nil;
|
fd->fds = nil;
|
||||||
wunlock(fd);
|
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];
|
||||||
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ copyifnec(u32int addr, int len, int *copied)
|
||||||
if(len < 0)
|
if(len < 0)
|
||||||
len = strlen(targ) + 1;
|
len = strlen(targ) + 1;
|
||||||
ret = emalloc(len);
|
ret = emalloc(len);
|
||||||
|
setmalloctag(ret, getcallerpc(&addr));
|
||||||
memcpy(ret, targ, len);
|
memcpy(ret, targ, len);
|
||||||
segunlock(seg);
|
segunlock(seg);
|
||||||
*copied = 1;
|
*copied = 1;
|
||||||
|
@ -103,7 +104,7 @@ copyifnec(u32int addr, int len, int *copied)
|
||||||
void *
|
void *
|
||||||
bufifnec(u32int addr, int len, int *buffered)
|
bufifnec(u32int addr, int len, int *buffered)
|
||||||
{
|
{
|
||||||
void *targ;
|
void *targ, *v;
|
||||||
Segment *seg;
|
Segment *seg;
|
||||||
|
|
||||||
targ = vaddr(addr, len, &seg);
|
targ = vaddr(addr, len, &seg);
|
||||||
|
@ -113,7 +114,9 @@ bufifnec(u32int addr, int len, int *buffered)
|
||||||
}
|
}
|
||||||
segunlock(seg);
|
segunlock(seg);
|
||||||
*buffered = 1;
|
*buffered = 1;
|
||||||
return emalloc(len);
|
v = emalloc(len);
|
||||||
|
setmalloctag(v, getcallerpc(&addr));
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -122,8 +125,10 @@ copyback(u32int addr, int len, void *data)
|
||||||
void *targ;
|
void *targ;
|
||||||
Segment *seg;
|
Segment *seg;
|
||||||
|
|
||||||
if(len <= 0)
|
if(len <= 0) {
|
||||||
|
free(data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
targ = vaddr(addr, len, &seg);
|
targ = vaddr(addr, len, &seg);
|
||||||
memmove(targ, data, len);
|
memmove(targ, data, len);
|
||||||
segunlock(seg);
|
segunlock(seg);
|
||||||
|
|
|
@ -196,6 +196,46 @@ sysfstat(void)
|
||||||
copyback(edir, P->R[0], edirt);
|
copyback(edir, P->R[0], edirt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
sysexits(void)
|
sysexits(void)
|
||||||
{
|
{
|
||||||
|
@ -266,6 +306,27 @@ syschdir(void)
|
||||||
static void
|
static void
|
||||||
sysnotify(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
|
static void
|
||||||
|
@ -541,6 +602,17 @@ sysremove(void)
|
||||||
free(filet);
|
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
|
void
|
||||||
syscall(void)
|
syscall(void)
|
||||||
{
|
{
|
||||||
|
@ -556,10 +628,13 @@ syscall(void)
|
||||||
[ERRSTR] syserrstr,
|
[ERRSTR] syserrstr,
|
||||||
[STAT] sysstat,
|
[STAT] sysstat,
|
||||||
[FSTAT] sysfstat,
|
[FSTAT] sysfstat,
|
||||||
|
[WSTAT] syswstat,
|
||||||
|
[FWSTAT] sysfwstat,
|
||||||
[SEEK] sysseek,
|
[SEEK] sysseek,
|
||||||
[CHDIR] syschdir,
|
[CHDIR] syschdir,
|
||||||
[FD2PATH] sysfd2path,
|
[FD2PATH] sysfd2path,
|
||||||
[NOTIFY] sysnotify,
|
[NOTIFY] sysnotify,
|
||||||
|
[NOTED] sysnoted,
|
||||||
[RFORK] sysrfork,
|
[RFORK] sysrfork,
|
||||||
[EXEC] sysexec,
|
[EXEC] sysexec,
|
||||||
[AWAIT] sysawait,
|
[AWAIT] sysawait,
|
||||||
|
@ -571,6 +646,7 @@ syscall(void)
|
||||||
[DUP] sysdup,
|
[DUP] sysdup,
|
||||||
[MOUNT] sysmount,
|
[MOUNT] sysmount,
|
||||||
[REMOVE] sysremove,
|
[REMOVE] sysremove,
|
||||||
|
[ALARM] sysalarm,
|
||||||
};
|
};
|
||||||
|
|
||||||
n = P->R[0];
|
n = P->R[0];
|
||||||
|
|
|
@ -12,6 +12,7 @@ emalloc(u32int size)
|
||||||
v = malloc(size);
|
v = malloc(size);
|
||||||
if(v == nil)
|
if(v == nil)
|
||||||
sysfatal("%r");
|
sysfatal("%r");
|
||||||
|
setmalloctag(v, getcallerpc(&size));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ emallocz(u32int size)
|
||||||
|
|
||||||
v = emalloc(size);
|
v = emalloc(size);
|
||||||
memset(v, 0, size);
|
memset(v, 0, size);
|
||||||
|
setmalloctag(v, getcallerpc(&size));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,5 +35,6 @@ erealloc(void *old, u32int size)
|
||||||
v = realloc(old, size);
|
v = realloc(old, size);
|
||||||
if(v == nil)
|
if(v == nil)
|
||||||
sysfatal("%r");
|
sysfatal("%r");
|
||||||
|
setrealloctag(v, getcallerpc(&old));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue