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"
|
Cut down some clang warnings
Edit C code to reduce warnings from clang. Most warnings are for
implicit declarations of functions, but some warnings want me to add
parentheses or curly braces, or to cast arguments for printf().
Make a few other changes, like declaring float_cst() in h/con_float to
be static, and using C99 bool in ego/ra/makeitems.c and
ego/share/makecldef.c. Such changes don't silence warnings; I make
such changes while I silence warnings in the same file. In
float_cst(), rename parameter `str` to `float_str`, so it doesn't
share a name with the global variable `str`.
Remove `const` from `newmodule(const char *)` in mach/proto/as to
silence a warning. I wrongly added the `const` in d347207.
For warnings about implicit declarations of functions, the fix is to
declare the function before calling it. For example, my OpenBSD
system needs <sys/wait.h> to declare wait().
In util/int, add "whatever.h" to declare more functions. Remove old
declarations from "mem.h", to prefer the newer declarations of the
same functions in "data.h" and "stack.h".
2019-10-23 20:06:36 +00:00
|
|
|
#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 */
|
1989-11-13 15:36:12 +00:00
|
|
|
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*/
|
|
|
|
}
|
|
|
|
|