/* $Header:setup.c 12.0$ */
/* $ACIS:setup.c 12.0$ */
/* $Source: /ibm/acis/usr/src/bin/adb_ca/RCS/setup.c,v $ */

#ifndef lint
static char *rcsid = "$Header:setup.c 12.0$";
#endif

/*
 * adb - routines to read a.out+core at startup
 */
#include "defs.h"
#include <sys/stat.h>
off_t   datbas;                 /* offset of the base of the data segment */
off_t   stksiz;                 /* stack size in the core image */
INT     sigcode;        /* belongs in head.h */
char    *symfil = "a.out";
char    *corfil = "core";
struct user user;
struct pte apte;
struct pte *Usrptmap;
struct pte *usrpt;
char *ar0;

setsym()
{
        off_t loc;
        struct exec hdr;
        register struct nlist *sp;
        int ssiz;
        char *strtab;
        fsym = getfile(symfil, 1);
        txtmap.ufd = fsym;
        if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr ||
            N_BADMAG(hdr)) {
                printf("%s not a.out\n", symfil);
                txtmap.e1 = MAXFILE;
                return;
        }
        filhdr = hdr;
        loc = filhdr.a_text+filhdr.a_data;
        txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr);
        txtmap.b1 = 0;
        switch (filhdr.a_magic) {
        case OMAGIC:
#ifdef vax
                txtmap.b1 = txtmap.e1 = 0;
                txtmap.b2 = datbas = 0;
                txtmap.e2 = loc;
#endif vax
#ifdef ibm032
		txtmap.b1 = filhdr.a_entry;
		txtmap.e1 = txtmap.b1 + filhdr.a_text;
		txtmap.b2 = datbas = txtmap.e1;
		txtmap.e2 = txtmap.e1 + loc;
		txtmap.f2 += filhdr.a_text;
                break;
        case ZMAGIC:
        case NMAGIC:
		txtmap.e1 = txtmap.b1 + filhdr.a_text;
		txtmap.b2 = datbas = DATABASE;
		if(kernel || (filhdr.a_entry & 0x80000000)) {
			if(!kernel && (filhdr.a_entry & 0x80000000))
				printf("Assuming kernel mapping\n");
			txtmap.b1 = filhdr.a_entry & 0xffff0000;
			txtmap.e1 = txtmap.b1 + filhdr.a_text;
			txtmap.b2 = datbas = 
				addr_round(filhdr.a_text+txtmap.b1,PAGSIZ);
		}
                txtmap.e2 = datbas + filhdr.a_data;
		txtmap.f2 += filhdr.a_text;
#endif ibm032
        }
#ifdef DEBUG
	if (debug) printf("%s (b1,e1,f1)=(0x%X,0x%X,0x%X) (b2,e2,f2)=(0x%X,0x%X,0x%X)\n",
                symfil,
                txtmap.b1, txtmap.e1, txtmap.f1,
                txtmap.b2, txtmap.e2, txtmap.f2 );
#endif
        loc = N_SYMOFF(filhdr);
        symtab = (struct nlist *) malloc(filhdr.a_syms);
        esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)];
        if (symtab == NULL)
                goto nospac;
        lseek(fsym, loc, 0);
        if (filhdr.a_syms == 0){
                printf("%s has no symbol table\n", symfil );
                goto nosymt;
        }
        /* SHOULD SQUISH OUT STABS HERE!!! */
        if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms)
                goto readerr;
        if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz))
                goto oldfmt;
        strtab = (char *) malloc(ssiz);
        if (strtab == 0)
                goto nospac;
        *(int *)strtab = ssiz;
        ssiz -= sizeof (ssiz);
        if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz)
                goto readerr;
        for (sp = symtab; sp < esymtab; sp++)
                if (sp->n_un.n_strx)
                        /* SHOULD PERFORM RANGE CHECK HERE */
                        sp->n_un.n_name = strtab + sp->n_un.n_strx;
nosymt:
        return;
readerr:
        printf("Error reading symbol|string table\n");
        exit(1);
nospac:
        printf("Not enough space for symbol|string table\n");
        exit(1);
oldfmt:
        printf("Old format a.out - no string table\n");
        exit(1);
}
 
setcor()
{
	struct user *uptr;
	datmap.b1 = 0;
	datmap.e1 = MAXFILE;
        fcor = datmap.ufd = getfile(corfil,2);
	if (kernel && fcor != -1 && INKERNEL(filhdr.a_entry)) {
		struct stat stb;

		kcore = 1;
		fstat(fcor, &stb);
#ifdef vax
		if (kernel == 0 && (stb.st_mode & S_IFREG))
			datmap.b1 = 0x80000000;
		lookup("_Sysmap");
		sbr = cursym->n_value;
		lookup("_Syssize");
		slr = cursym->n_value;
		printf("sbr %X slr %X\n", sbr, slr);
		lookup("_masterpaddr");
		physrw(fcor, cursym->n_value&0x7fffffff, &masterpcbb, 1);
		masterpcbb = (masterpcbb&PG_PFNUM)*512;
		getpcb();
#endif vax
#ifdef ibm032
		if (kernel == 0 && (stb.st_mode & S_IFREG))
			datmap.b1 = SYSBASE;
		lookup("_endmem");	/* these values all needed for vtop */
		physrw(fcor, cursym->n_value&~SYSBASE, &endmem, 1);

		lookup("_MMU_HASHMASK");
		physrw(fcor, cursym->n_value&~SYSBASE, &MMU_HASHMASK, 1);

		lookup("_MMU_HATIPT");
		physrw(fcor, cursym->n_value&~SYSBASE, &MMU_HATIPT, 1);

#ifdef DEBUG
		if (debug) printf("MMUHASHMASK 0x%x, MMU_HATIPT %x, endmem %x bytes\n", MMU_HASHMASK, MMU_HATIPT, ctob(endmem));
#endif
		sbr = (struct pte *)SYSBASE;  /* should also set slr */

		lookup("_masterpaddr");
		physrw(fcor, cursym->n_value&~SYSBASE, &masterpcbb, 1);
		printf("masterpaddr %X\n", masterpcbb);

		getproc();

#endif
		return;
	}

        if( read(fcor, (char *)&u, ctob(UPAGES)) != ctob(UPAGES) ){
                printf("%s not core file\n", corfil );
                datmap.e1 = MAXFILE;
                return;
        }
	uptr = (struct user *)((char *)&u.U + Uadjust);	/* adjust for different sized uareas */
        signo = uptr->u_arg[0];
        sigcode = uptr->u_code;
        filhdr.a_text = ctob(uptr->u_tsize);
        filhdr.a_data = ctob(uptr->u_dsize);
        stksiz = ctob(uptr->u_ssize);
	ar0 = (char *)uptr->u_ar0;
	init_regs();
        switch (filhdr.a_magic) {
        case OMAGIC:
                datmap.b1 = 0;
                datmap.e1 = filhdr.a_text+filhdr.a_data;
                datmap.f2 = ctob(UPAGES) + datmap.e1;
                break;
        case NMAGIC:
        case ZMAGIC:
#ifdef ibm032
                datmap.b1 = DATABASE;
                datmap.e1 = datmap.b1 + filhdr.a_data;
#else
                datmap.b1 = DATABASE + round(filhdr.a_text, PAGSIZ);
                datmap.e1 = datmap.b1 + filhdr.a_data;
#endif
                datmap.f2 = ctob(UPAGES) + filhdr.a_data;
                break;
	default:
		printf("core file --strange magic number %x", filhdr.a_magic);
		return;
        }
        datbas = datmap.b1;
        datmap.f1 = ctob(UPAGES);
        datmap.b2 = USRSTACK - stksiz;
        datmap.e2 = USRSTACK;  /* see machine/vmparam.h */
#ifdef DEBUG
        if (debug) printf("%s (b1,e1,f1)=(0x%X,0x%X,0x%X) (b2,e2,f2)=(0x%X,0x%X,0x%X)\n",
                corfil,
                datmap.b1, datmap.e1, datmap.f1,
                datmap.b2, datmap.e2, datmap.f2 );
#endif
}

getproc()
{
int procaddr, usaddr, uarea;
	
	procaddr=vtop(masterpcbb);
#ifdef DEBUG
	if (debug) printf("getproc seeks to %x\n", procaddr);
#endif

        lseek(fcor, procaddr, 0);
        read(fcor, &proc, sizeof (struct proc));
#ifdef DEBUG
	if (debug) printf("p0br %X  uarea pte at %x\n", proc.p_p0br, proc.p_addr);
#endif
	printf("p_sid0 %X, p_sid1 %X\n", proc.p_sid0, proc.p_sid1);

        lseek(fcor, uarea = vtop(proc.p_addr+btop(UPAGES*NBPG-sizeof (struct user))), 0);
#ifdef DEBUG
	if (debug) printf("uarea at %X \n", uarea);
#endif	
        read(fcor, &apte, sizeof (apte));  /* pte containing u struct beginning */
	usaddr=(int)ptob(apte.pg_pfnum)+((NBPG-sizeof (struct user))&PGOFSET);

#ifdef DEBUG
	if (debug) printf("apteaddr page %X ustruct at %X\n",  apte,  usaddr);
#endif
        lseek(fcor, usaddr, 0);
        read(fcor, &user, sizeof (user));
	if(Kernel_iar == 0)
		Kernel_iar = user.u_pcb.pcb_r15;
        printf("p0br %X, p0lr %X, p1br %X, p1lr %X\n",
            user.u_pcb.pcb_p0br, user.u_pcb.pcb_p0lr, user.u_pcb.pcb_p1br, user.u_pcb.pcb_p1lr); 
	if (user.u_procp != (struct proc *)masterpcbb)
		printf("warning: u_procp %X != masterpcbb %X\n", 
			user.u_procp, masterpcbb);
}


#ifdef vax
getpcb()
{
        lseek(fcor, masterpcbb&~SYSBASE, 0);
#ifdef DEBUG
	if (debug) printf("getpcb: seek at %x\n", masterpcbb&~SYSBASE);
#endif
        read(fcor, &pcb, sizeof (struct pcb));
        pcb.pcb_p0lr &= ~AST_CLR;
        printf("p0br %X, p0lr %X, p1br %X, p1lr %X\n",
            pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
}
#endif
 
create(f)
        char *f;
{
        register int fd;
        fd = creat(f, 0644);
        if (fd < 0)
                return (-1);
        close(fd);
        return (open(f, wtflag));
}
getfile(filnam, cnt)
        char *filnam;
{
        register int fsym;
        if (eqstr(filnam, "-"))
                return (-1);
        fsym = open(filnam, wtflag);
        if (fsym < 0 && xargc > cnt) {
                if (wtflag)
                        fsym = create(filnam);
                if (fsym < 0)
                        printf("cannot open `%s'\n", filnam);
        }
        return (fsym);
}
setvar()
{
        var[varchk('b')] = datbas;
        var[varchk('d')] = filhdr.a_data;
        var[varchk('e')] = filhdr.a_entry;
        var[varchk('m')] = filhdr.a_magic;
        var[varchk('s')] = stksiz;
        var[varchk('t')] = filhdr.a_text;
}
