diff --git a/sys/src/9/kw/syscall.c b/sys/src/9/kw/syscall.c index d1fcd9fc5..6aaba6db2 100644 --- a/sys/src/9/kw/syscall.c +++ b/sys/src/9/kw/syscall.c @@ -206,40 +206,26 @@ syscall(Ureg* ureg) spllo(); sp = ureg->sp; - if(up->procctl == Proc_tracesyscall){ - /* - * Redundant validaddr. Do we care? - * Tracing syscalls is not exactly a fast path... - * Beware, validaddr currently does a pexit rather - * than an error if there's a problem; that might - * change in the future. - */ - if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD)) - validaddr(sp, sizeof(Sargs)+BY2WD, 0); - - syscallfmt(scallnr, ureg->pc, (va_list)(sp+BY2WD)); - up->procctl = Proc_stopme; - procctl(up); - if (up->syscalltrace) - free(up->syscalltrace); - up->syscalltrace = nil; - } - up->nerrlab = 0; ret = -1; - startns = todget(nil); if(!waserror()){ + if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD)) + validaddr(sp, sizeof(Sargs)+BY2WD, 0); + up->s = *((Sargs*)(sp+BY2WD)); + if(up->procctl == Proc_tracesyscall){ + syscallfmt(scallnr, ureg->pc, (va_list)up->s.args); + s = splhi(); + up->procctl = Proc_stopme; + procctl(up); + splx(s); + startns = todget(nil); + } if(scallnr >= nsyscall){ pprint("bad sys call number %d pc %#lux\n", scallnr, ureg->pc); postnote(up, 1, "sys: bad sys call", NDebug); error(Ebadarg); } - - if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD)) - validaddr(sp, sizeof(Sargs)+BY2WD, 0); - - up->s = *((Sargs*)(sp+BY2WD)); up->psstate = sysctab[scallnr]; /* iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */ @@ -270,21 +256,18 @@ syscall(Ureg* ureg) if(up->procctl == Proc_tracesyscall){ stopns = todget(nil); - up->procctl = Proc_stopme; - sysretfmt(scallnr, (va_list)(sp+BY2WD), ret, startns, stopns); + sysretfmt(scallnr, (va_list)up->s.args, ret, startns, stopns); s = splhi(); + up->procctl = Proc_stopme; procctl(up); splx(s); - if(up->syscalltrace) - free(up->syscalltrace); - up->syscalltrace = nil; } up->insyscall = 0; up->psstate = 0; if(scallnr == NOTED) - noted(ureg, *(ulong*)(sp+BY2WD)); + noted(ureg, up->s.args[0]); splhi(); if(scallnr != RFORK && (up->procctl || up->nnote)) diff --git a/sys/src/9/omap4/trap.c b/sys/src/9/omap4/trap.c index 2d8b9eb04..653334726 100644 --- a/sys/src/9/omap4/trap.c +++ b/sys/src/9/omap4/trap.c @@ -317,16 +317,13 @@ syscall(Ureg *ureg) int scall, ret; ulong s, sp; char *e; + vlong startns, stopns; m->syscall++; up->insyscall = 1; up->pc = ureg->pc; up->dbgreg = ureg; cycles(&up->kentry); - if(up->procctl == Proc_tracesyscall){ - up->procctl = Proc_stopme; - procctl(up); - } scall = ureg->r0; up->scallnr = scall; spllo(); @@ -335,12 +332,20 @@ syscall(Ureg *ureg) up->nerrlab = 0; ret = -1; if(!waserror()){ + validaddr(sp, sizeof(Sargs) + BY2WD, 0); + up->s = *((Sargs*)(sp + BY2WD)); + if(up->procctl == Proc_tracesyscall){ + syscallfmt(scall, ureg->pc, (va_list)up->s.args); + s = splhi(); + up->procctl = Proc_stopme; + procctl(up); + splx(s); + startns = todget(nil); + } if(scall >= nsyscall){ postnote(up, 1, "sys: bad syscall", NDebug); error(Ebadarg); } - validaddr(sp, sizeof(Sargs) + BY2WD, 0); - up->s = *((Sargs*)(sp + BY2WD)); up->psstate = sysctab[scall]; ret = systab[scall](up->s.args); poperror(); @@ -354,8 +359,10 @@ syscall(Ureg *ureg) ureg->r0 = ret; if(up->procctl == Proc_tracesyscall){ - up->procctl = Proc_stopme; + stopns = todget(nil); + sysretfmt(scall, (va_list)up->s.args, ret, startns, stopns); s = splhi(); + up->procctl = Proc_stopme; procctl(up); splx(s); } @@ -364,7 +371,7 @@ syscall(Ureg *ureg) up->psstate = nil; if(scall == NOTED) - noted(ureg, *(ulong *)(sp + BY2WD)); + noted(ureg, up->s.args[0]); if(scall != RFORK && (up->procctl || up->nnote)){ splhi(); notify(ureg);