progt.c


/*************************************************************************
*                                                                        *
*   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();
    }
}



[INDICE CODICE]