/*************************************************************************
* *
* Program Trap Handler *
* *
* realizzato dal Gruppo 17 di Lab2 Anno Accademico 1995/96 *
* *
* Lorenzo Claudio Valerio Riccardo Emiliano *
* Coronati Lanconelli Paolini Solmi Trentini *
* *
**************************************************************************/
#include "../h/tproc.h"
#include "../h/services.e"
#include "../h/supglobals.e"
/***
* Gestore delle program trap. L'unica trap recuperabile e` la
* stack limit yellow in cui il gestore estende lo stack a tutto
* lo spazio a disposizione del T-process nel segmento privato
* (togliendo lo spazio occupato da codice e dati). Cio` e` possibile
* in quanto non manteniamo uno Heap. Notare che non possiamo caricare
* subito STL con tale valore in quanto non conosciamo la lunghezza
* del programma caricato se non dopo averlo eseguito (questo per il
* caricatore contenuto nel programma stesso del T-process).
***/
/*
* struttura dell'intestazione del programma da caricare (molti campi
* non sono utilizzati).
*/
typedef struct a_out {
unsigned short magic;
unsigned int text_size; /* length of text section in bytes */
unsigned int data_size; /* length of data section in bytes */
unsigned int bss_size; /* length of bss data area in bytes */
unsigned int sym_size; /* length of symbol table in bytes */
unsigned int entry; /* start address */
unsigned int trel_size; /* length of text relocation info */
unsigned int drel_size; /* length of data relocation info */
} a_out;
void
progt()
{
register thr_t *sender; /* R4 */
register state_t *msg; /* R3 */
register int term_no; /* R2 - inizializzato al numero di terminale */
a_out *hdr = (a_out *)(BEGUSERADDR + BOOTSIZE);
unsigned int newlimit;
/* inizializzazione dati del gestore */
while(TRUE)
{
sender = ANYSENDER;
DO_MSGRECV();
switch (msg->s_ps2.p2_pr.pr_typ)
{
case STKLIMYELLOW:
break;
case STKLIMRED:
if (msg->s_ps1.ps_ku == FALSE)
{
newlimit = (unsigned int)hdr + sizeof(hdr) +
hdr->text_size +
hdr->data_size +
hdr->bss_size;
/* arrotonda alla word successiva */
newlimit = (newlimit + 1) & ~1;
if (newlimit < msg->s_stl)
msg->s_stl = newlimit;
else
killTerminal(term_no, "Stack overflow");
}
else
killTerminal(term_no, "Support error: stack overflow");
break;
case ILOPCODE:
killTerminal(term_no, "Illegal opcode");
break;
case NONSUPINSTR:
killTerminal(term_no, "Non supported instruction");
break;
case PRIVINSTR:
killTerminal(term_no, "Privileged instruction");
break;
case ILLINSTR:
killTerminal(term_no, "Illegal instruction");
break;
case ODDADD:
killTerminal(term_no, "Odd address");
break;
case NONPAGEALL:
killTerminal(term_no, "Non page allignment");
break;
case NONEXISTMEM:
killTerminal(term_no, "Non existent memory");
break;
case ZERODIV:
killTerminal(term_no, "Divide by zero");
break;
case SENDTODEADTHR:
killTerminal(term_no, "Send to dead thread");
break;
case RECVFROMDEADTHR:
killTerminal(term_no, "Receive from dead thread");
break;
default:
killTerminal(term_no, "Unknown program trap");
break;
}
DO_MSGSEND();
}
}