xref: /plan9/sys/src/ape/lib/ap/sparc/notetramp.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include "../plan9/lib.h"
2 #include "../plan9/sys9.h"
3 #include <signal.h>
4 #include <setjmp.h>
5 
6 /* A stack to hold pcs when signals nest */
7 #define MAXSIGSTACK 20
8 typedef struct Pcstack Pcstack;
9 static struct Pcstack {
10 	int sig;
11 	void (*hdlr)(int, char*, Ureg*);
12 	unsigned long restorepc;
13 	unsigned long restorenpc;
14 	Ureg *u;
15 } pcstack[MAXSIGSTACK];
16 static int nstack = 0;
17 
18 static void notecont(Ureg*, char*);
19 
20 void
_notetramp(int sig,void (* hdlr)(int,char *,Ureg *),Ureg * u)21 _notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
22 {
23 	Pcstack *p;
24 
25 	if(nstack >= MAXSIGSTACK)
26 		_NOTED(1);	/* nesting too deep; just do system default */
27 	p = &pcstack[nstack];
28 	p->restorepc = u->pc;
29 	p->restorenpc = u->npc;
30 	p->sig = sig;
31 	p->hdlr = hdlr;
32 	p->u = u;
33 	nstack++;
34 	u->pc = (unsigned long) notecont;
35 	u->npc = u->pc+4;
36 	_NOTED(2);	/* NSAVE: clear note but hold state */
37 }
38 
39 static void
notecont(Ureg * u,char * s)40 notecont(Ureg *u, char *s)
41 {
42 	Pcstack *p;
43 	void(*f)(int, char*, Ureg*);
44 
45 	p = &pcstack[nstack-1];
46 	f = p->hdlr;
47 	u->pc = p->restorepc;
48 	u->npc = p->restorenpc;
49 	nstack--;
50 	(*f)(p->sig, s, u);
51 	_NOTED(3);	/* NRSTR */
52 }
53 
54 int	__noterestore(void);
55 
56 #define JMPBUFPC 1
57 #define JMPBUFSP 0
58 #define	JMPBUFDPC (-8)
59 
60 extern sigset_t	_psigblocked;
61 
62 void
siglongjmp(sigjmp_buf j,int ret)63 siglongjmp(sigjmp_buf j, int ret)
64 {
65 	struct Ureg *u;
66 
67 	if(j[0])
68 		_psigblocked = j[1];
69 	if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
70 		longjmp(j+2, ret);
71 	u = pcstack[nstack-1].u;
72 	nstack--;
73 	u->r8 = ret;
74 	if(ret == 0)
75 		u->r8 = 1;
76 	u->r9 = j[JMPBUFPC] - JMPBUFDPC;
77 	u->pc = (unsigned long)__noterestore;
78 	u->npc = (unsigned long)__noterestore + 4;
79 	u->sp = j[JMPBUFSP];
80 	_NOTED(3);	/* NRSTR */
81 }
82