/* * Call user, if necessary, with note. * Pass user the Ureg struct and the note on his stack. */ int notify(Ureg* ureg) { int l; Mpl pl; Note note; uintptr sp; NFrame *nf; /* * Calls procctl splhi, see comment in procctl for the reasoning. */ if(up->procctl) procctl(up); if(up->nnote == 0) return 0; fpunotify(ureg); pl = spllo(); qlock(&up->debug); up->notepending = 0; memmove(¬e, &up->note[0], sizeof(Note)); if(strncmp(note.msg, "sys:", 4) == 0){ l = strlen(note.msg); if(l > ERRMAX-sizeof(" pc=0x0123456789abcdef")) l = ERRMAX-sizeof(" pc=0x0123456789abcdef"); sprint(note.msg+l, " pc=%#p", ureg->ip); } if(note.flag != NUser && (up->notified || up->notify == nil)){ qunlock(&up->debug); if(note.flag == NDebug) pprint("suicide: %s\n", note.msg); pexit(note.msg, note.flag != NDebug); } if(up->notified){ qunlock(&up->debug); splhi(); return 0; } if(up->notify == nil){ qunlock(&up->debug); pexit(note.msg, note.flag != NDebug); } if(!okaddr(PTR2UINT(up->notify), sizeof(ureg->ip), 0)){ qunlock(&up->debug); pprint("suicide: bad function address %#p in notify\n", up->notify); pexit("Suicide", 0); } sp = ureg->sp - sizeof(NFrame); if(!okaddr(sp, sizeof(NFrame), 1)){ qunlock(&up->debug); pprint("suicide: bad stack address %#p in notify\n", sp); pexit("Suicide", 0); } nf = UINT2PTR(sp); memmove(&nf->ureg, ureg, sizeof(Ureg)); nf->old = up->ureg; up->ureg = nf; /* actually the NFrame, for noted */ memmove(nf->msg, note.msg, ERRMAX); nf->arg1 = nf->msg; nf->arg0 = &nf->ureg; ureg->bp = PTR2UINT(nf->arg0); nf->ip = 0; ureg->sp = sp; ureg->ip = PTR2UINT(up->notify); up->notified = 1; up->nnote--; memmove(&up->lastnote, ¬e, sizeof(Note)); memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note)); qunlock(&up->debug); splx(pl); return 1; }
/* * Call user, if necessary, with note. * Pass user the Ureg struct and the note on his stack. */ int notify(Ureg* ureg) { int l; Note *n; u32int s; uintptr sp; NFrame *nf; if(up->procctl) procctl(up); if(up->nnote == 0) return 0; fpunotify(ureg); s = spllo(); qlock(&up->debug); up->notepending = 0; n = &up->note[0]; if(strncmp(n->msg, "sys:", 4) == 0){ l = strlen(n->msg); if(l > ERRMAX-23) /* " pc=0x0123456789abcdef\0" */ l = ERRMAX-23; snprint(n->msg + l, sizeof n->msg - l, " pc=%#lux", ureg->pc); } if(n->flag != NUser && (up->notified || up->notify == 0)){ if(n->flag == NDebug) pprint("suicide: %s\n", n->msg); qunlock(&up->debug); pexit(n->msg, n->flag != NDebug); } if(up->notified){ qunlock(&up->debug); splhi(); return 0; } if(up->notify == nil){ qunlock(&up->debug); pexit(n->msg, n->flag != NDebug); } if(!okaddr(PTR2UINT(up->notify), 1, 0)){ pprint("suicide: notify function address %#p\n", up->notify); qunlock(&up->debug); pexit("Suicide", 0); } sp = ureg->sp - sizeof(NFrame); if(!okaddr(sp, sizeof(NFrame), 1)){ qunlock(&up->debug); pprint("suicide: notify stack address %#p\n", sp); pexit("Suicide", 0); } nf = UINT2PTR(sp); memmove(&nf->ureg, ureg, sizeof(Ureg)); nf->old = up->ureg; up->ureg = nf; memmove(nf->msg, up->note[0].msg, ERRMAX); nf->arg1 = nf->msg; nf->arg0 = &nf->ureg; ureg->r0 = PTR2UINT(nf->arg0); nf->ip = 0; ureg->sp = sp; ureg->pc = PTR2UINT(up->notify); up->notified = 1; up->nnote--; memmove(&up->lastnote, &up->note[0], sizeof(Note)); memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note)); qunlock(&up->debug); splx(s); return 1; }