Exemplo n.º 1
0
void seg_fault() {
    TrapDebug((dbg_file, "Apout - pid %d segmentation fault at PC 0%06o\n",
					(int)getpid(), regs[PC]));
    TrapDebug((dbg_file, "%06o  ", ir));
    TrapDebug((dbg_file, "%o %o %o %o %o %o %o %o  ",
	 regs[0], regs[1], regs[2], regs[3],
	 regs[4], regs[5], regs[6], regs[7]));
    TrapDebug((dbg_file, "NZVC3 are %d%d%d%d\n",CC_N,CC_Z,CC_V,CC_C));
    exit(EXIT_FAILURE);
}
Exemplo n.º 2
0
void bus_error(int signo)
{
    TrapDebug((dbg_file, "Apout - pid %d bus error at PC 0%06o\n",
					(int)getpid(), regs[PC]));
    TrapDebug((dbg_file, "%06o  ", ir));
    TrapDebug((dbg_file, "%o %o %o %o %o %o %o %o  ",
	 regs[0], regs[1], regs[2], regs[3],
	 regs[4], regs[5], regs[6], regs[7]));
    TrapDebug((dbg_file, "NZVC2 are %d%d%d%d\n",CC_N,CC_Z,CC_V,CC_C));
    exit(EXIT_FAILURE);
}
Exemplo n.º 3
0
/* Run until told to stop. */
void run() {
#ifdef DEBUG
    int i;

    if (trap_debug) {
	TrapDebug((dbg_file, "Just starting to run pid %d\n",(int)getpid()));
	TrapDebug((dbg_file, "Regs are           "));
	for (i=0;i<=PC;i++) TrapDebug((dbg_file, "%06o ",regs[i]));
	TrapDebug((dbg_file, "\n"));
    }
#endif

    while (1) {

	/* Fetch and execute the instruction. */

#ifdef DEBUG
	lli_word(regs[PC], ir);
	if (inst_debug) {
	   i= ir >> 6;
	   switch (i) {
		case 0: name= iname0[ir & 077]; break;
		case 2: name= iname1[ir & 077]; break;
		default: name= iname[i];
	   }
	   TrapDebug((dbg_file, "%06o %06o %4s ", regs[7], ir, name));
	   TrapDebug((dbg_file, "%06o %06o %06o %06o %06o %06o %06o   ",
		regs[0], regs[1], regs[2], regs[3],
		regs[4], regs[5], regs[6]));
	   TrapDebug((dbg_file, "NZVC1 %d%d%d%d\n",CC_N,CC_Z,CC_V,CC_C));
	   fflush(dbg_file);
	}
	regs[PC] += 2; itab[ir >> 6] ();
	if ((Sighead!=NULL) && (sigrunner!=NULL)) (void) (*sigrunner)();
#else
	/* When not debugging, we can manually unroll this inner loop */
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] ();
	if ((Sighead!=NULL) && (sigrunner!=NULL)) (void) (*sigrunner)();
#endif
    }
}
Exemplo n.º 4
0
/* This is the generic function which catches
 * a signal, and appends it to the queue.
 */
void sigcatcher(int sig)
{
 struct our_siglist *this;

 this= (struct our_siglist *)malloc(sizeof(struct our_siglist));
 if (this==NULL) return;

 TrapDebug((dbg_file, "Caught signal %d\n",sig));

 this->sig=sig; this->next=NULL;
 if (Sighead==NULL) { Sighead=Sigtail=this; }
 else { Sigtail->next= this; Sigtail=this; }
}
Exemplo n.º 5
0
void bad_FP_reg() {
    TrapDebug((stderr, "Apout - pid %d bad FP register used at PC 0%o\n",
					(int)getpid(), regs[PC]));
    exit(EXIT_FAILURE);
}
Exemplo n.º 6
0
void trap() {
    TrapDebug((stderr, "Apout - pid %d trap instruction at PC 0%o\n",
					(int)getpid(), regs[PC]));
    exit(EXIT_FAILURE);
}
Exemplo n.º 7
0
void not_impl() {
    TrapDebug((stderr, "Apout - pid %d unimplemented instruction at PC 0%o\n",
					(int)getpid(), regs[PC]));
    exit(EXIT_FAILURE);
}
Exemplo n.º 8
0
void illegal() {
    TrapDebug((stderr, "Apout - pid %d illegal instruction %o at PC 0%o\n",
					(int)getpid(),ir, regs[PC]));
    exit(EXIT_FAILURE);
}
Exemplo n.º 9
0
/* Load the named PDP-11 executable file into the emulator's memory.
 * Returns 0 if ok, -1 if error. Also initialise the simulator and set
 * up the stack for the process with Argc, Argv, Envc, Envp.
 * origpath is the path to the executable as seen by the simulated
 * parent, or NULL if this is not known.
 */
int load_a_out(const char *file, const char *origpath, int want_env)
{
    /* @globals errno,stdout,stderr; @ */
#define V12_MEMBASE 16384	/* Offset for V1/V2 binaries load */
    FILE *zin;
    struct exec e;
    u_int8_t *ibase, *dbase, *bbase;	/* Instruction, data, bss bases */
    u_int16_t size;
    int i;
#ifdef EMU211
    int j;
#endif
#ifdef RUN_V1_RAW
    struct stat stb;
#endif

    for (i = 0; i < Argc; i++)
        TrapDebug((dbg_file, "In load_a_out Argv[%d] is %s\n", i,
                   Argv[i]));

    (void) signal(SIGBUS, bus_error);	/* Catch all bus errors here */

    if ((zin = fopen(file, "r")) == NULL)	/* Open the file */
        return (-1);

    Binary = load_aout_header(zin, &e);	/* Determine a.out & Unix type */

    if (e.a_magic == ANY_SCRIPT) {	/* Shell script, run that */
        return (load_script(file, origpath, zin, want_env));
    }
#ifndef EMU211
    if (Binary == IS_211BSD) {
        (void) fprintf(stderr,
                       "Apout not compiled to support 2.11BSD binaries\n");
        (void) fclose(zin);
        return (-1);
    }
#endif
#ifndef EMUV1
    if (Binary == IS_V1) {
        (void) fprintf(stderr,
                       "Apout not compiled to support 1st Edition binaries\n");
        (void) fclose(zin);
        return (-1);
    }
    if (Binary == IS_V2) {
        (void) fprintf(stderr,
                       "Apout not compiled to support 2nd Edition binaries\n");
        (void) fclose(zin);
        return (-1);
    }
#endif

#ifdef NATIVES
    /* Executable was not recognised.
     * Try to exec it as a native binary.
     * If it fails, doesn't matter. If it
     * succeeds, then great. This allows
     * us to have mixed native and PDP-11
     * binaries in the same filespace.
     */
    if (e.a_magic == UNKNOWN_AOUT) {
#ifdef DEBUG
        TrapDebug((dbg_file, "About to try native exec on %s\n", file));
        fflush(dbg_file);
#endif
        (void) fclose(zin);
        execv(file, Argv);	/* envp[] is the one Apout's main() got */
        TrapDebug((dbg_file, "Nope, didn't work\n"));
#endif

#ifdef RUN_V1_RAW
        /* Try to run it as a V1 raw binary */
#ifdef DEBUG
        TrapDebug((dbg_file, "About to try PDP-11 raw exec on %s\n",
                   file));
        fflush(dbg_file);
#endif				/* DEBUG */
        if ((zin = fopen(file, "r")) == NULL)	/* reopen the file */
            return (-1);
        e.a_magic = V1_RAW;
        Binary = IS_V1;
#else
        (void) fprintf(stderr, "Apout - unknown a.out file %s\n", file);
        return (-1);
#endif				/* RUN_V1_RAW */
    }
    /* Now we know what environment to
     * create, set up the memory areas
     * according to the magic numbers
     */
#ifdef DEBUG
    switch (Binary) {
    case IS_A68:
        TrapDebug((dbg_file, "A68 binary\n"));
        break;
    case IS_V1:
        TrapDebug((dbg_file, "V1 binary\n"));
        break;
    case IS_V2:
        TrapDebug((dbg_file, "V2 binary\n"));
        break;
    case IS_V5:
        TrapDebug((dbg_file, "V5 binary\n"));
        break;
    case IS_V6:
        TrapDebug((dbg_file, "V6 binary\n"));
        break;
    case IS_V7:
        TrapDebug((dbg_file, "V7 binary\n"));
        break;
    case IS_211BSD:
        TrapDebug((dbg_file, "2.11BSD binary\n"));
        break;
    }
#endif

    switch (e.a_magic) {
#ifdef RUN_V1_RAW
    case V1_RAW:
        if (fseek(zin, 0, SEEK_SET) != 0) {
            (void) fclose(zin);
            return (-1);
        }
        ispace = dspace = darray;
        ibase = &(ispace[V12_MEMBASE]);	/* Load & run the binary starting */
        dbase = ibase;	/* at address 16384 (040000) */
        dwrite_base = 0;
        e.a_entry = V12_MEMBASE;
        /* Reset the exec header fields to make loading code below
         * work properly
         */
        if (stat(file, &stb)) {
            fprintf(stderr, "Apout - cannot stat %s\n", file);
            return -1;
        }
        e.a_text = stb.st_size;
        bbase = &(ispace[V12_MEMBASE + e.a_text]);
        e.a_data = 0;
        break;
#endif
#ifdef EMUV1
    case V1_NORMAL:	/* V1 a.out binary looks like */
        e.a_bss = e.a_syms;	/* 0405                       */
        e.a_syms = e.a_data;	/* size of text               */
        e.a_data = 0;	/* size of symbol table       */
        /* reloc bits                 */
        /* size of data (i.e bss)     */
        /* unused and zeroed          */
        /* We must rearrange fields   */
        /* Move back to start of V1 header */
        if (fseek(zin, 0, SEEK_SET) != 0) {
            (void) fclose(zin);
            return (-1);
        }
        ispace = dspace = darray;
        ibase = &(ispace[V12_MEMBASE]);	/* Load & run the binary starting */
        dbase = &(ispace[e.a_text]);	/* at address 16384 (040000) */
        bbase = &(ispace[e.a_text + e.a_data]);
        dwrite_base = 0;
        e.a_entry = V12_MEMBASE;
        break;
#endif
    case A68_MAGIC:	/* Algol 68 image */
        if (fseek(zin, 0, SEEK_SET) != 0) {
            (void) fclose(zin);
            return (-1);
        }
        e.a_text = e.ov_siz[0] + 1;
        e.a_data = 0;
        e.a_bss = 0160000 - e.a_text;
        e.a_entry = e.a_flag;
        ibase = ispace = dspace = darray;
        dbase = ibase;
        dwrite_base = 0;
        bbase = &(ispace[e.a_text + e.a_data]);
        break;
    case ANY_NORMAL:
        /* Move back to end of V5/6/7 header */
        if (fseek(zin, 16, SEEK_SET) != 0) {
            (void) fclose(zin);
            return (-1);
        }
        ibase = ispace = dspace = darray;
#ifdef EMUV1
        if (Binary == IS_V2) {
            ibase = &(ispace[V12_MEMBASE]);
            e.a_entry = V12_MEMBASE;
            dbase = &(ispace[e.a_text + V12_MEMBASE]);
            bbase = &(ispace[e.a_text + e.a_data + V12_MEMBASE]);
        } else
#endif
        {
            dbase = &(ispace[e.a_text]);
            bbase = &(ispace[e.a_text + e.a_data]);
        }
        if ((Binary < IS_V7))
            dwrite_base = 0;
        else
            dwrite_base = e.a_text;
        break;
    case ANY_ROTEXT:
        /* Move back to end of V5/6/7 header */
        if (fseek(zin, 16, SEEK_SET) != 0) {
            (void) fclose(zin);
            return (-1);
        }
    /* @fallthrough@ */
    case BSD_OVERLAY:
        /* Round up text area to next 8K boundary */
        if (e.a_text % EIGHT_K) {
            size = EIGHT_K * (1 + e.a_text / EIGHT_K);
        } else
            size = e.a_text;
        /* And the next 8K boundary if overlays! */
        if (e.a_magic == BSD_OVERLAY) {
            if (e.max_ovl % EIGHT_K) {
                size += EIGHT_K * (1 + e.max_ovl / EIGHT_K);
            } else
                size += e.max_ovl;
        }
        ibase = ispace = dspace = darray;
        dbase = &(ispace[size]);
        bbase = &(ispace[size + e.a_data]);
        dwrite_base = size;
        break;
    case ANY_SPLITID:
        /* Move back to end of V5/6/7 header */
        if (fseek(zin, 16, SEEK_SET) != 0) {
            (void) fclose(zin);
            return (-1);
        }
    /* @fallthrough@ */
    case BSD_ROVERLAY:
        ibase = ispace = iarray;
        dbase = dspace = darray;
        bbase = &(dspace[e.a_data]);

        /* Try to stop null refs */
        if (Binary == IS_211BSD)
            dwrite_base = 0;
        else
            dwrite_base = 2;
        break;
    default:
        (void) fprintf(stderr, "Apout - unknown a.out format 0%o\n",
                       e.a_magic);
        (void) fclose(zin);
        return (-1);
    }


    /* Initialise the instruction table for our environment */
    switch (Binary) {
#ifdef EMU211
    case IS_211BSD:
        for (i = 548; i < 552; i++)
            itab[i] = bsdtrap;
        break;
#endif
#ifdef EMUV1
    case IS_V1:
    case IS_V2:
        for (i = 544; i < 548; i++)
            itab[i] = rts;
        for (i = 548; i < 552; i++)
            itab[i] = v1trap;
        break;
#endif
    case IS_A68:
        for (i = 544; i < 552; i++)
            itab[i] = v7trap;
        break;
    case IS_V5:
    case IS_V6:
    case IS_V7:
        for (i = 548; i < 552; i++)
            itab[i] = v7trap;
        break;
    default:
        fprintf(stderr, "Apout - unknown Unix version for %s\n", file);
        exit(EXIT_FAILURE);
    }

#ifdef ZERO_MEMORY
    memset(darray, 0, PDP_MEM_SIZE);	/* Clear all memory */
    if (ispace != dspace)
        memset(iarray, 0, PDP_MEM_SIZE);
#endif

    /* Now load the text into ibase */
    for (size = e.a_text; size;) {
        i = (int) fread(ibase, 1, (size_t) size, zin);
        if (i == -1) {
            (void) fclose(zin);
            return (i);
        }
        size -= i;
        ibase += i;
    }

#ifdef EMU211
    /* Now deal with any overlays */
    if (Binary == IS_211BSD)
        switch (e.a_magic) {
        case BSD_OVERLAY:
        case BSD_ROVERLAY:
            /* Round up text area to next 8K boundary */
            if (e.a_text % EIGHT_K) {
                size = EIGHT_K * (1 + e.a_text / EIGHT_K);
            } else
                size = e.a_text;
            ovbase = &ispace[size];

            for (i = 0; i < NOVL; i++) {
                if (e.ov_siz[i] == 0) {
                    ovlist[i].size = 0;
                    ovlist[i].ovlay = NULL;
                    continue;
                }
                /* Create memory for the overlay */
                ovlist[i].size = e.ov_siz[i];
                if (ovlist[i].ovlay)
                    free(ovlist[i].ovlay);
                ovlist[i].ovlay = (u_int8_t *) malloc(e.ov_siz[i]);
                if (ovlist[i].ovlay == NULL) {
                    fprintf(stderr, "Apout - can't malloc overlay!\n");
                    exit(EXIT_FAILURE);
                }
                /* Load the overlay into memory */
                for (size = ovlist[i].size, ibase = ovlist[i].ovlay;
                        size;) {
                    j = fread(ibase, 1, size, zin);
                    if (j == -1) {
                        fclose(zin);
                        return (j);
                    }
                    size -= j;
                    ibase += j;
                }
            }

            /* And deal with the emt instructions */
            for (i = 544; i < 548; i++)
                itab[i] = do_bsd_overlay;
        }
#endif

    /* Now load the data into dbase */
    if (dbase)
        for (size = e.a_data; size;) {
            i = (int) fread(dbase, 1, (size_t) size, zin);
            if (i == -1) {
                (void) fclose(zin);
                return (i);
            }
            size -= i;
            dbase += i;
        }

    /* Now clear the bss */
    if ((bbase != 0) && (e.a_bss != 0))
        memset(bbase, 0, (size_t) e.a_bss);


    /* Set up the registers and flags, and the stack */
    (void) fclose(zin);
    sim_init();
    regs[PC] = e.a_entry;
    if (Binary == IS_A68) {
        regs[5] = e.max_ovl;
        regs[4] = 0160000;
    }
    set_arg_env(want_env);
    return (0);
}
Exemplo n.º 10
0
/* Read in the executable name and its arguments from the shell script,
 * and the re-call load_a_out to load in that binary. Returns 0 on
 * success, -1 on error. Input file is always closed by this routine.
 */
int load_script(const char *file, const char *origpath, FILE * zin,
                int want_env)
{
#define SCRIPT_LINESIZE 512	/* Max size of 1st line in script */
    char *script_line;
    char *script_arg[MAX_ARGS];
    int i, script_cnt = 0;
    char **ap;

    for (i = 0; i < Argc; i++)
        TrapDebug((dbg_file, "In load_script Argv[%d] is %s\n", i,
                   Argv[i]));
    /* Get the first line of the file */
    if (((script_line = (char *) malloc(SCRIPT_LINESIZE)) == NULL) ||
            (fgets(script_line, SCRIPT_LINESIZE, zin) == NULL)) {
        (void) fprintf(stderr,
                       "Apout - could not read 1st line of script\n");
        (void) fclose(zin);
        return (-1);
    }
    /* Now break into separate words */
    for (ap = script_arg; (*ap = strsep(&script_line, " \t\n")) != NULL;)
        if (**ap != '\0') {
            ap++;
            script_cnt++;
            if (script_cnt >= MAX_ARGS)
                break;
        }
    if (fclose(zin) != 0) {
        free(script_line);
        return (-1);
    }
#ifdef DEBUG
    TrapDebug((dbg_file, "Script: extra args are is %d\n", script_cnt));
    if (trap_debug) {
        for (i = 0; i < script_cnt; i++)
            fprintf(dbg_file, " script_arg[%d] is %s\n", i, script_arg[i]);
    }
#endif

    /* Ensure we have room to shift the args */
    if ((Argc + script_cnt) > MAX_ARGS) {
        (void) fprintf(stderr, "Apout - out of argv space in script\n");
        free(script_line);
        return (-1);
    }
    /* Now shift the args up and insert new ones */
    for (i = Argc - 1; i != 0; i--)
        Argv[i + script_cnt] = Argv[i];
    for (i = 0; i < Argc; i++)
        TrapDebug((dbg_file, "Part A load_script Argv[%d] is %s\n", i,
                   Argv[i]));
    for (i = 0; i < script_cnt; i++)
        Argv[i] = script_arg[i];
    if (origpath != NULL)
        Argv[i] = strdup(origpath);
    else
        Argv[i] = strdup(file);
    Argc += script_cnt;
    for (i = 0; i < Argc; i++)
        TrapDebug((dbg_file, "Part B load_script Argv[%d] is %s\n", i,
                   Argv[i]));

    file = xlate_filename(script_arg[0]);
    free(script_line);
    for (i = 0; i < Argc; i++)
        TrapDebug((dbg_file, "Leaving load_script Argv[%d] is %s\n", i,
                   Argv[i]));
    return (load_a_out(file, origpath, want_env));
}