/* initialize file and procedure tables */
register struct proct
*procp
;
register struct filet
*filep
;
filep
= files
= badfile
= (struct filet
*) sbrk(sizeof filep
[0]);
procp
= procs
= badproc
= (struct proct
*) sbrk(sizeof procp
[0]);
if (bread(&sbuf
, &stentry
, sizeof stentry
) <
class = stentry
.n_type
& STABMASK
;
switch (class & STABMASK
) {
p
= sbrk(FILEINCR
*sizeof filep
[0]);
q
= p
+ FILEINCR
*sizeof filep
[0];
while (p
> (char *) procs
)
FILEINCR
*sizeof filep
[0]);
FILEINCR
*sizeof filep
[0]);
badproc
= (struct proct
*)
FILEINCR
*sizeof filep
[0]);
filep
->faddr
= stentry
.n_value
;
filep
->lineflag
= (class == N_SOL
);
filep
->stf_offset
= soffset
;
for (i
=0; i
<8; i
++) *p
++ = stentry
.n_name
[i
];
if (*(p
-1) == '\0') break;
if (bread(&sbuf
, &stentry
, sizeof stentry
)
error("Bad N_SO entry (1)");
if ((stentry
.n_type
& STABMASK
) !=
error("Bad N_SO entry (2)");
soffset
+= sizeof stentry
;
for (p
=fp
; *q
; *p
++ = *q
++) ;
if (stat(filework
, &stbuf
) == -1)
printf("Warning: `%s' not found\n",
else if (stbuf
.st_mtime
> symtime
)
printf("Warning: `%s' newer than `%s'\n",
if (stentry
.n_name
[0] != '_') break;
if (sbrk(PROCINCR
*sizeof procp
[0]) < 0) {
procp
->pname
[i
] = stentry
.n_name
[i
];
procp
->paddr
= stentry
.n_value
;
procp
->st_offset
= soffset
;
procp
->sfptr
= (class != N_TEXT
) ? filep
- 1 : badfile
;
procp
->lineno
= (class != N_TEXT
) ? stentry
.n_desc
: 0;
procp
->entrypt
= (class & STABMASK
) == N_ENTRY
;
if (stentry
.n_type
& N_EXT
&& !extstart
) {
soffset
+= sizeof stentry
;
qsort(procs
, procp
-procs
, sizeof procs
[0], compar
);
badproc
->st_offset
= soffset
;
badproc
->sfptr
= procp
->sfptr
= badfile
;
badproc
->pname
[0] = badfile
->sfilename
[0]=
procp
->pname
[0] = filep
->sfilename
[0] = '\0';
/* returns current procedure from state (curfile, fline) */
addr
= getaddr("", fline
);
if (addr
== -1) return(badproc
);
return(adrtoprocp(addr
));
/* returns procedure s, uses curproc() if s == NULL */
register struct proct
*p
;
if (s
[0] == '\0') return(curproc());
for(p
=procs
; p
->pname
[0]; p
++)
if (eqstr(p
->pname
, s
)) return(p
);
if (debug
) printf("%s(): unknown name\n", s
);
/* returns file s containing filename */
register struct filet
*f
;
for (f
=files
; f
->sfilename
[0]; f
++) {
if (eqstr(f
->sfilename
, s
)) {
for( ; f
->lineflag
; f
--) ;
if (f
< files
) error("Bad file array");
* looks up variable matching pat starting at offset in a.out, searching
* backwards, ignoring nested blocks to beginning to procedure.
* Returns its offset and symbol table entries decoded in sl_*
* If comblk == "*" then match both within and outside common blocks,
* if comblk == "" then match only outside common blocks,
* else match only within comblk.
slookup(pat
, poffset
, stelt
)
long poffset
; char *pat
; {
slooknext(pat
, poffset
, stelt
, "*");
int clevel
, level
, fnameflag
, comfound
, incomm
;
clevel
= level
= fnameflag
= comfound
= incomm
= 0;
slooknext(pat
, poffset
, stelt
, comblk
)
long poffset
; char *pat
, *comblk
; {
offset
= poffset
+ sizeof stentry
;
if (debug
) printf("slookup(%s,%d)\n",pat
,offset
);
blseek(&sbuf
, offset
, 0);
offset
-= sizeof stentry
;
if (offset
< ststart
) break;
if (bread(&sbuf
, &stentry
+1, -sizeof stentry
)
class = stentry
.n_type
& STABMASK
;
switch (class & STABMASK
) {
for (q
= &stentry
.n_name
[7]; q
>=stentry
.n_name
; q
--) {
if (eqpat(comblk
, stentry
.n_name
))
procp
= findproc(stentry
.n_name
);
for (p
=procs
; p
->pname
[0]; p
++) {
p
->st_offset
> procp
->st_offset
&&
blseek(&sbuf
, offset
, 0);
if (level
<= 0 && eqpat(pat
, stentry
.n_name
) &&
stentry
.n_name
[0] && class & STABTYPES
&&
(comblk
[0] == '\0' && incomm
== 0) ||
(stelt
== (class == N_SSYM
))) {
sl_size
= stentry
.n_value
;
offset
-= sizeof stentry
;
sl_class
= stentry
.n_type
& STABMASK
;
sl_type
= stentry
.n_desc
;
sl_addr
= stentry
.n_value
;
for (i
=0; i
<8; i
++) sl_name
[i
] =
if (clevel
!= 0) docomm(offset
);
return(offset
- sizeof stentry
);
* Look up global variable matching pat
* Return its offset and symbol table entries decoded in sl_*
globallookup(pat
, filestart
, stelt
)
char *pat
; long filestart
; {
if (debug
) printf("globallookup(%s,%d)\n", pat
,filestart
);
blseek(&sbuf
, filestart
, 0);
offset
= filestart
- sizeof stentry
;
if (bread(&sbuf
, &stentry
, sizeof stentry
) <
sizeof stentry
) return(-1);
offset
+= sizeof stentry
;
} while ((stentry
.n_type
& STABMASK
) == N_SO
);
class = stentry
.n_type
& STABMASK
;
switch (class & STABMASK
) {
if (eqpat(pat
, stentry
.n_name
)
&& stentry
.n_name
[0] && class & STABTYPES
) {
sl_class
= stentry
.n_type
& STABMASK
;
if (sl_class
!= N_GSYM
&& sl_class
!= N_SSYM
&&
sl_class
!= N_STSYM
) goto g1
;
if (stelt
!= (sl_class
== N_SSYM
)) goto g1
;
sl_type
= stentry
.n_desc
;
sl_addr
= stentry
.n_value
;
for (i
=0; i
<8; i
++) sl_name
[i
] = stentry
.n_name
[i
];
if (clevel
!= 0) docomm(offset
);
g1
: if (bread(&sbuf
, &stentry
, sizeof stentry
) < sizeof stentry
)
offset
+= sizeof stentry
;
g2
: bread(&sbuf
, &stentry
, sizeof stentry
);
if (((stentry
.n_type
& STABMASK
) == N_LENG
) &&
(eqpat(sl_name
, stentry
.n_name
)))
sl_size
= stentry
.n_value
;
if (sl_class
== N_GSYM
&& (clevel
== 0)) {
blseek(&sbuf
, extstart
, 0);
if (bread(&sbuf
, &stentry
, sizeof stentry
)
if (stentry
.n_name
[0] != '_') continue;
if (eqpatr(sl_name
, stentry
.n_name
+1, 1)) {
sl_addr
= stentry
.n_value
;
return(offset
+ sizeof stentry
);
/* core address to procedure (pointer to proc array) */
register struct proct
*procp
, *lastproc
;
for (procp
=procs
; procp
->pname
[0]; procp
++) {
if (procp
->paddr
> addr
) break;
/* core address to file (pointer to file array) */
register struct filet
*filep
;
for (filep
=files
; filep
->sfilename
[0]; filep
++) {
if (filep
->faddr
> addr
) break;
return (filep
!= files
? filep
-1 : badfile
);
/* core address to linenumber */
lineno
= lastoffset
= -1;
offset
= adrtoproc(addr
)->st_offset
;
blseek(&sbuf
, offset
, 0);
if (bread(&sbuf
, &stentry
, sizeof stentry
)
if (stentry
.n_type
== N_SLINE
) {
if (stentry
.n_value
> addr
) break;
offset
+= sizeof stentry
;
/* address to a.out offset */
* Set (curfile, lineno) from core image.
* Returns 1 if there is a core image, 0 otherwise.
* Print the current line iff verbose is set.
register struct proct
*procp
;
dot
= *(ADDR
*) (((ADDR
) &u
) + PC
);
printf("No core image\n");
if ((procp
->sfptr
) != badfile
) {
finit(adrtofilep(procp
->paddr
)->sfilename
);
printf("%.8s:", procp
->pname
);
if (procp
->pname
[0] == '_')
printf("%.7s: address 0x%x\n", procp
->pname
+1, dot
);
printf("%.8s: address %d\n", procp
->pname
, dot
);
procp
= findproc("MAIN_");
if ((procp
->pname
[0] != 'M') || (procp
->sfptr
== badfile
)) {
procp
= findproc("main");
if ((procp
->pname
[0] != 'm') || (procp
->sfptr
== badfile
)) {
printf("main not compiled with debug flag\n");
finit(procp
->sfptr
->sfilename
);
if (a
->paddr
== b
->paddr
) {
if (a
->pname
[0] == '_') return(-1);
if (b
->pname
[0] == '_') return(1);
return(a
->paddr
< b
->paddr
? -1 : 1);
/* gets offset of file or procedure named s */
register struct filet
*f
;
register struct proct
*p
;
return(f
->sfilename
[0] ? f
->stf_offset
: -1);
return(p
->pname
[0] ? p
->st_offset
: -1);
/* returns s if its a filename, its file otherwise */
register struct proct
*p
;
return(adrtofilep(p
->paddr
)->sfilename
);
/* line number to address, starting at offset in a.out */
/* assumes that offset is within file */
lntoaddr(lineno
, offset
, file
)
long offset
; char *file
; {
register int i
, ignore
= 0;
register int bestln
=BIGNUM
;
blseek(&sbuf
, offset
, 0);
if (bread(&sbuf
, &stentry
, sizeof stentry
) <
sizeof stentry
) return(-1);
} while ((stentry
.n_type
& STABMASK
) == N_SO
);
switch(stentry
.n_type
& STABMASK
) {
if (stentry
.n_desc
== lineno
)
if (stentry
.n_desc
> lineno
&&
stentry
.n_desc
< bestln
) {
bestaddr
= stentry
.n_value
;
if (*p
!= stentry
.n_name
[i
]) goto neq
;
if (stentry
.n_name
[7] == '\0')
if (bread(&sbuf
, &stentry
, sizeof stentry
)
error("Bad N_SO entry (1)");
if ((stentry
.n_type
& STABMASK
) !=
error("Bad N_SO entry (2)");
if (bread(&sbuf
, &stentry
, sizeof stentry
) < sizeof stentry
)
ret
: return(bestln
== BIGNUM
? -1 : bestaddr
);
/* gets address of proc:number */
s
= proc
[0] ? proc
: curfile
;
offset
= nametooffset(s
);
if (debug
) printf("getaddr() computed offset %d", offset
);
if (addr
!= -1) addr
+= 2; /* MACHINE DEPENDENT */
if (debug
) printf(" extaddr computed %d\n", addr
);
addr
= lntoaddr(integ
, offset
, s
);
addr
= findproc(proc
)->paddr
+ 2; /* MACHINE DEPENDENT */
addr
= lntoaddr(adrtolineno(addr
)+1, offset
, f
);
if (debug
) printf(" and addr %d\n", addr
);
if (addr
== -1) return(-1);
/* returns address of external */
blseek(&sbuf
, extstart
, 0);
if (bread(&sbuf
, &stentry
, sizeof stentry
) < sizeof stentry
)
if (stentry
.n_name
[0] == '_' &&
eqpatr(name
, stentry
.n_name
+1, 1))
/* find enclosing common blocks and fix up addresses */
if (bread(&sbuf
, &stentry
, sizeof stentry
) < sizeof stentry
) {
error("Bad common block");
if ((stentry
.n_type
& STABMASK
) == N_ECOMM
) {
sl_addr
+= extaddr(stentry
.n_name
);
blseek(&sbuf
, offset
, 0);
if ((stentry
.n_type
& STABMASK
) == N_ECOML
) {
sl_addr
+= stentry
.n_value
;
blseek(&sbuf
, offset
, 0);
/* determine if class is that of a variable */
char pctypes
[] = {N_GSYM
, N_STSYM
, N_LCSYM
, N_RSYM
, N_SSYM
, N_LSYM
,
for (p
=pctypes
; *p
; p
++) {