static char sccsid
[] = "@(#)setup.c 4.10 (Berkeley) 85/05/09";
* adb - routines to read a.out+core at startup
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 */
register struct nlist
*sp
;
fsym
= getfile(symfil
, 1);
if (read(fsym
, (char *)&hdr
, sizeof hdr
) != sizeof hdr
||
loc
= filhdr
.a_text
+filhdr
.a_data
;
txtmap
.f1
= txtmap
.f2
= N_TXTOFF(filhdr
);
txtmap
.b1
= filhdr
.a_entry
;
switch (filhdr
.a_magic
) {
txtmap
.b2
= datbas
= txtmap
.b1
;
txtmap
.e2
= txtmap
.b2
+ loc
;
txtmap
.e1
= txtmap
.b1
+ filhdr
.a_text
;
txtmap
.b2
= datbas
= round(txtmap
.e1
, PAGSIZ
);
txtmap
.e2
= datbas
+ filhdr
.a_data
;
symtab
= (struct nlist
*) malloc(filhdr
.a_syms
);
esymtab
= &symtab
[filhdr
.a_syms
/ sizeof (struct nlist
)];
/* SHOULD SQUISH OUT STABS HERE!!! */
if (read(fsym
, symtab
, filhdr
.a_syms
) != filhdr
.a_syms
)
if (read(fsym
, &ssiz
, sizeof (ssiz
)) != sizeof (ssiz
))
strtab
= (char *) malloc(ssiz
);
if (read(fsym
, strtab
+ sizeof (ssiz
), ssiz
) != ssiz
)
for (sp
= symtab
; sp
< esymtab
; sp
++)
/* SHOULD PERFORM RANGE CHECK HERE */
sp
->n_un
.n_name
= strtab
+ sp
->n_un
.n_strx
;
#ifndef hp300 /* can't debug kernel on hp without symbol table anyway */
if (INKERNEL(filhdr
.a_entry
)) {
printf("Error reading symbol|string table\n");
printf("Not enough space for symbol|string table\n");
printf("Old format a.out - no string table\n");
fcor
= datmap
.ufd
= getfile(corfil
,2);
if (kernel
&& fcor
!= -1 && INKERNEL(filhdr
.a_entry
)) {
printf("sbr %X slr %X\n", sbr
, slr
);
physrw(fcor
, KVTOPH(cursym
->n_value
), &masterpcbb
, 1);
masterpcbb
= (masterpcbb
&PG_PFNUM
)*NBPG
;
if (read(fcor
, (char *)&u
, ctob(UPAGES
))!=ctob(UPAGES
) ||
!INUDOT(u
.u_pcb
.pcb_ksp
) || !INSTACK(u
.u_pcb
.pcb_usp
)) {
if (kernel
&& fcor
!= -1) {
if ((stb
.st_mode
& S_IFMT
) == S_IFCHR
&&
stb
.st_rdev
== makedev(2,0))
* Must find lowram and get its value before
/* /dev/mem == physical memory */
lseek(fcor
, (off_t
)LOWRAM
, L_SET
);
/* normal file -- use standard offset */
lseek(fcor
, (off_t
)KVTOPH(cursym
->n_value
), L_SET
);
read(fcor
, &lowram
, sizeof (lowram
));
lowram
= roundup(lowram
, NBPG
);
physmap
.b1
= physmap
.f1
= lowram
;
physmap
.ufd
= datmap
.ufd
;
if (lookup("_mmutype") != 0) {
lseek(fcor
, (off_t
)KVTOPH(cursym
->n_value
), L_SET
);
read(fcor
, &mmutype
, sizeof mmutype
);
slr
= NPTEPG
* (NPTEPG
-1);
lseek(fcor
, (off_t
)KVTOPH(cursym
->n_value
), L_SET
);
read(fcor
, &sbr
, sizeof sbr
);
printf("sbr %X slr %X\n", sbr
, slr
);
(void) lookup("_kstack");
kernudot
= cursym
->n_value
;
* Newer versions of the kernel have masterpaddr defined
* Look for that first, else look up Umap where the
lseek(fcor
, (off_t
)KVTOPH(cursym
->n_value
), L_SET
);
read(fcor
, &masterpcbb
, sizeof (masterpcbb
));
lseek(fcor
, (off_t
)KVTOPH(cursym
->n_value
), L_SET
);
read(fcor
, &masterpcbb
, sizeof (masterpcbb
));
masterpcbb
= PG_PFNUM(masterpcbb
)*NBPG
;
if (read(fcor
, (char *)&u
, ctob(UPAGES
))!=ctob(UPAGES
)) {
/* add paranoia tests for stack pointers? */
filhdr
.a_text
= ctob(u
.u_tsize
);
filhdr
.a_data
= ctob(u
.u_dsize
);
stksiz
= ctob(u
.u_ssize
);
switch (filhdr
.a_magic
) {
datmap
.e1
= filhdr
.a_text
+filhdr
.a_data
;
datmap
.f2
= ctob(UPAGES
) + datmap
.e1
;
datmap
.b1
= round(filhdr
.a_text
, PAGSIZ
);
datmap
.e1
= datmap
.b1
+ filhdr
.a_data
;
datmap
.f2
= ctob(UPAGES
) + filhdr
.a_data
;
datmap
.f1
= ctob(UPAGES
);
datmap
.b2
= MAXSTOR
- stksiz
;
#if defined(hp300) && defined(NEWVM)
long addr
= vtophys(masterpcbb
);
lseek(fcor
, (off_t
)addr
, L_SET
);
lseek(fcor
, (off_t
)masterpcbb
, L_SET
);
read(fcor
, &pcb
, sizeof (struct pcb
));
pcb
.pcb_p0lr
&= ~AST_CLR
;
#if defined(hp300) && defined(NEWVM)
printf("current u-area %X\n", masterpcbb
);
printf("p0br %X p0lr %X p1br %X p1lr %X\n",
pcb
.pcb_p0br
, pcb
.pcb_p0lr
, pcb
.pcb_p1br
, pcb
.pcb_p1lr
);
caddr_t intstack
, eintstack
;
struct frame
*getframe();
struct frame
*checkintstack();
* Find the current stack frame when debugging the kernel.
* If we're looking at a crash dump and this was not a ``clean''
* crash, then we must search the interrupt stack carefully
* looking for a valid frame.
char *panicstr
, buf
[256];
register struct frame
*fp
;
if (lookup("_panicstr") == 0)
lseek(fcor
, (off_t
)KVTOPH(cursym
->n_value
), L_SET
);
read(fcor
, &panicstr
, sizeof (panicstr
));
lseek(fcor
, (off_t
)KVTOPH((off_t
)panicstr
), L_SET
);
read(fcor
, buf
, sizeof (buf
));
for (cp
= buf
; cp
< &buf
[sizeof (buf
)] && *cp
; cp
++)
if (!isascii(*cp
) || (!isprint(*cp
) && !isspace(*cp
)))
printf("panic: %s\n", buf
);
* After a panic, look at the top of the rpb stack to
* find a stack frame. If this was a clean crash,
* i.e. one which left the interrupt and kernel stacks
* in a reasonable state, then we should find a pointer
* to the proper stack frame here (at location scb-4).
* If we don't find a reasonable frame here, then we
* must search down through the interrupt stack.
intstack
= lookup("_intstack")->n_value
;
#define NISP 3 /* from locore.s */
eintstack
= intstack
+ NISP
*NBPG
;
rpb
= lookup("_rpb")->n_value
;
scb
= lookup("_scb")->n_value
;
ustack
= cursym
->n_value
+ (int)&((struct user
*)0)->u_stack
[0];
eustack
= cursym
->n_value
+ ctob(UPAGES
);
physrw(fcor
, KVTOPH((int)scb
- sizeof (caddr_t
)), &addr
, 1);
fp
= getframe(fcor
, addr
);
/* search kernel stack? */
printf("can't locate stack frame\n");
/* probably shouldn't clobber pcb, but for now this is easy */
pcb
.pcb_pc
= fp
->fr_savpc
;
pcb
.pcb_ap
= addr
+ sizeof (struct frame
) + fp
->fr_spa
;
for (mask
= fp
->fr_mask
; mask
; mask
>>= 1)
pcb
.pcb_ap
+= sizeof (caddr_t
);
* Search interrupt stack for a valid frame.
off_t off
= vtophys(intstack
);
if (off
== -1 || lseek(fcor
, off
, L_SET
) != off
||
read(fcor
, stack
, sizeof (stack
)) != sizeof (stack
))
return ((struct frame
*)0);
addr
-= sizeof (caddr_t
);
fp
= (struct frame
*)&stack
[addr
- intstack
];
} while (addr
>= intstack
+ sizeof (struct frame
) &&
return (addr
< intstack
+sizeof (struct frame
) ? (struct frame
*)0 : fp
);
* Get a stack frame and verify it looks like
* something which might be on a kernel stack.
static struct frame frame
;
if (!kstackaddr(fp
) || (off
= vtophys(fp
)) == -1)
return ((struct frame
*)0);
if (lseek(fcor
, off
, L_SET
) != off
||
read(fcor
, &frame
, sizeof (frame
)) != sizeof (frame
))
return ((struct frame
*)0);
return ((struct frame
*)0);
* Check a call frame to see if it's ok as
register struct frame
*fp
;
if (fp
->fr_handler
!= 0 || fp
->fr_s
== 0)
if (!kstackaddr(fp
->fr_savap
) || !kstackaddr(fp
->fr_savfp
))
return (within(fp
->fr_savpc
, txtmap
.b1
, txtmap
.e1
));
* Check if an address is in one of the kernel's stacks:
* interrupt stack, rpb stack (during restart sequence),
return (within(addr
, intstack
, eintstack
) ||
within(addr
, rpb
+ sizeof (struct rpb
), scb
) ||
within(addr
, ustack
, eustack
));
char *panicstr
, buf
[256];
if (lookup("_panicstr") == 0)
lseek(fcor
, (off_t
)KVTOPH(cursym
->n_value
), L_SET
);
read(fcor
, &panicstr
, sizeof (panicstr
));
lseek(fcor
, (off_t
)KVTOPH((off_t
)panicstr
), L_SET
);
read(fcor
, buf
, sizeof (buf
));
for (cp
= buf
; cp
< &buf
[sizeof (buf
)] && *cp
; cp
++)
if (!isascii(*cp
) || (!isprint(*cp
) && !isspace(*cp
)))
printf("panic: %s\n", buf
);
/* dumpsys() will save the pcb for us */
return (addr
>= kernudot
&& addr
< kernudot
+ ctob(UPAGES
));
add your own code to locate the kernel stack
return (open(f
, wtflag
));
fsym
= open(filnam
, wtflag
);
if (fsym
< 0 && xargc
> cnt
) {
printf("cannot open `%s'\n", filnam
);
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
;