ack/util/int/trap.c

126 lines
2.2 KiB
C
Raw Normal View History

2019-03-17 14:42:00 +00:00
/** @file
* Trap handling and management routines.
*/
1988-06-22 16:57:09 +00:00
1994-06-24 11:31:16 +00:00
/* $Id$ */
1988-06-22 16:57:09 +00:00
#include <setjmp.h>
#include <em_abs.h>
#include "logging.h"
#include "global.h"
#include "log.h"
#include "trap.h"
2019-03-17 14:42:00 +00:00
#include "io.h"
1988-06-22 16:57:09 +00:00
#include "warn.h"
#include "mem.h"
#include "shadow.h"
#include "linfil.h"
#include "rsb.h"
#include "fra.h"
#include "whatever.h"
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
extern jmp_buf trapbuf; /* from main.c */
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
int must_test; /* TEST-bit on in EM header word 2 */
1988-06-22 16:57:09 +00:00
int signalled;
PRIVATE int nonreturnable();
2019-03-17 14:42:00 +00:00
PRIVATE char *trap_msg[] =
{
1988-06-22 16:57:09 +00:00
#include "trap_msg" /* generated from $(EM)/etc/traps */
2019-03-17 14:42:00 +00:00
"" };
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
char *trap2text(int nr)
1988-06-22 16:57:09 +00:00
{
2019-03-17 14:42:00 +00:00
if ( /* trap number in predefined range */
nr < sizeof(trap_msg) / sizeof(trap_msg[0]) && /* trap message not the empty string */
trap_msg[nr][0])
{
1988-06-22 16:57:09 +00:00
return trap_msg[nr];
}
2019-03-17 14:42:00 +00:00
else
{
1988-06-22 16:57:09 +00:00
static char buf[50];
sprintf(buf, "TRAP %d", nr);
return buf;
}
}
/*ARGSUSED*/
2019-03-17 14:42:00 +00:00
void do_trap(int nr, int L, char *F)
1988-06-22 16:57:09 +00:00
{
/*
2019-03-17 14:42:00 +00:00
1. The trap has not been masked.
2. This routine does not return; it either ends in a call of
fatal() or in a longjmp().
*/
static int rec_nr; /* Recursive trap number */
static int rec_trap = 0; /* To detect traps inside do_trap() */
register long tpi; /* Trap Procedure Identifier */
1988-06-22 16:57:09 +00:00
LOG(("@t1 trap(%d) [%s: %d]", nr, F, L));
warning(WMSG + nr);
2019-03-17 14:42:00 +00:00
switch (OnTrap)
{
1988-06-22 16:57:09 +00:00
case TR_ABORT:
fatal("trap \"%s\" before program started", trap2text(nr));
/*NOTREACHED*/
case TR_HALT:
2019-03-17 14:42:00 +00:00
fatal("trap \"%s\" not caught at %s", trap2text(nr), position());
1988-06-22 16:57:09 +00:00
/*NOTREACHED*/
case TR_TRAP:
/* execute the trap */
2019-03-17 14:42:00 +00:00
if (rec_trap)
{
1988-06-22 16:57:09 +00:00
fatal("recursive trap; first trap number was \"%s\"",
trap2text(rec_nr));
}
rec_trap = 1;
rec_nr = nr;
/* save the Function Return Area */
pushFRA(FRASize);
2019-03-17 14:42:00 +00:00
wpush((long) FRASize);
wpush((long) FRA_def);
1988-06-22 16:57:09 +00:00
/* set up the trap number as the only parameter */
wpush((long) nr);
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
tpi = TrapPI; /* allowed since OnTrap == TR_TRAP */
1988-06-22 16:57:09 +00:00
TrapPI = 0;
OnTrap = TR_HALT;
call(tpi, (nonreturnable(nr) ? RSB_NRT : RSB_RTT));
rec_trap = 0;
longjmp(trapbuf, 1);
/*NOTREACHED*/
}
}
2019-03-17 14:42:00 +00:00
PRIVATE int nonreturnable(int nr)
1988-06-22 16:57:09 +00:00
{
2019-03-17 14:42:00 +00:00
switch (nr)
{
1988-06-22 16:57:09 +00:00
case ESTACK:
case EILLINS:
case EODDZ:
case ECASE:
case EMEMFLT:
case EBADPTR:
case EBADPC:
case EBADLAE:
case EBADGTO:
return 1;
default:
return 0;
}
/*NOTREACHED*/
}