Pristine Ack-5.5
[Ack-5.5.git] / util / int / trap.c
1 /*
2         Trap handling
3 */
4
5 /* $Id: trap.c,v 2.4 1994/06/24 10:49:29 ceriel Exp $ */
6
7 #include        <setjmp.h>
8
9 #include        <em_abs.h>
10 #include        "logging.h"
11 #include        "global.h"
12 #include        "log.h"
13 #include        "trap.h"
14 #include        "warn.h"
15 #include        "mem.h"
16 #include        "shadow.h"
17 #include        "linfil.h"
18 #include        "rsb.h"
19 #include        "fra.h"
20
21 extern jmp_buf trapbuf;                 /* from main.c */
22
23 int must_test;                          /* TEST-bit on in EM header word 2 */
24 int signalled;
25
26 PRIVATE int nonreturnable();
27
28 PRIVATE char *trap_msg[] = {
29 #include        "trap_msg"              /* generated from $(EM)/etc/traps */
30         ""
31 };
32
33 char *trap2text(nr)                     /* transient */
34         int nr;
35 {
36         if (    /* trap number in predefined range */
37                 nr < sizeof (trap_msg) / sizeof (trap_msg[0])
38         &&      /* trap message not the empty string */
39                 trap_msg[nr][0]
40         ) {
41                 return trap_msg[nr];
42         }
43         else {
44                 static char buf[50];
45
46                 sprintf(buf, "TRAP %d", nr);
47                 return buf;
48         }
49 }
50
51 /*ARGSUSED*/
52 do_trap(nr, L, F)
53         int nr;
54         int L;
55         char *F;
56 {
57         /*
58         1.      The trap has not been masked.
59         2.      This routine does not return; it either ends in a call of
60                 fatal() or in a longjmp().
61         */
62         static int rec_nr;              /* Recursive trap number */
63         static int rec_trap = 0;        /* To detect traps inside do_trap() */
64         
65         register long tpi;              /* Trap Procedure Identifier */
66
67         LOG(("@t1 trap(%d) [%s: %d]", nr, F, L));
68         warning(WMSG + nr);
69
70         switch (OnTrap) {
71         case TR_ABORT:
72                 fatal("trap \"%s\" before program started", trap2text(nr));
73                 /*NOTREACHED*/
74
75         case TR_HALT:
76                 fatal("trap \"%s\" not caught at %s",
77                                 trap2text(nr), position());
78                 /*NOTREACHED*/
79
80         case TR_TRAP:
81                 /* execute the trap */
82                 if (rec_trap) {
83                         fatal("recursive trap; first trap number was \"%s\"",
84                                         trap2text(rec_nr));
85                 }
86                 rec_trap = 1;
87                 rec_nr = nr;
88
89                 /* save the Function Return Area */
90                 pushFRA(FRASize);
91                 wpush((long)FRASize);
92                 wpush((long)FRA_def);
93
94                 /* set up the trap number as the only parameter */
95                 wpush((long) nr);
96
97                 tpi = TrapPI;           /* allowed since OnTrap == TR_TRAP */
98                 TrapPI = 0;
99                 OnTrap = TR_HALT;
100                 call(tpi, (nonreturnable(nr) ? RSB_NRT : RSB_RTT));
101                 rec_trap = 0;
102                 longjmp(trapbuf, 1);
103                 /*NOTREACHED*/
104         }
105 }
106
107 PRIVATE int nonreturnable(nr)
108         int nr;
109 {
110         switch (nr) {
111         case ESTACK:
112         case EILLINS:
113         case EODDZ:
114         case ECASE:
115         case EMEMFLT:
116         case EBADPTR:
117         case EBADPC:
118         case EBADLAE:
119         case EBADGTO:
120                 return 1;
121         default:
122                 return 0;
123         }
124         /*NOTREACHED*/
125 }
126