* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)stab.c 5.3 (Berkeley) 1/3/88";
* Symbolic debugging info interface for the f77 compiler.
* Here we generate pseudo-ops that cause the assembler to put
* symbolic debugging information into the object file.
* University of Utah CS Dept modification history:
* Revision 5.3 86/01/10 17:12:58 donn
* Add junk to handle PARAMETER variables.
* Revision 5.2 86/01/10 13:51:31 donn
* Changes to produce correct stab information for logical and logical*2 types
* (from Jerry Berkman) plus changes for dummy procedures.
* Revision 5.1 85/08/10 03:50:06 donn
* Revision 1.2 85/02/02 01:30:09 donn
* Don't put the 'program' name into the file; it only confuses dbx, sigh.
typedef enum { false, true } Boolean
;
static char asmline
[128];
prstab(s
, code
, type
, loc
)
locout
= (loc
== nil
) ? "0" : loc
;
sprintf(asmline
, "\t.stabn\t0x%x,0,0x%x,%s\n", code
, type
, locout
);
sprintf(asmline
, "\t.stabs\t\"%s\",0x%x,0,0x%x,%s\n", s
, code
, type
,
sprintf(asmline
,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s
, N_SO
);
sprintf(asmline
,"\t.stabd\t0x%x,0,%d\n", N_SLINE
, lineno
);
* Generate information for an entry point
public entrystab(p
,class)
register struct Entrypoint
*p
;
et
=writestabtype(TYSUBR
);
sprintf(asmline
, "\t.stabs\t\"MAIN:F%2d\",0x%x,0,0,L%d\n",
case CLBLOCK
: /* May need to something with block data LATER */
if( (q
=p
->enamep
) == nil
) fatal("entrystab has no nameblock");
sprintf(asmline
, "\t.stabs\t\"%s:F", varstr(VL
,q
->varname
));
/* when insufficient information is around assume TYSUBR; enddcl
if(q
->vtype
== TYUNKNOWN
|| (q
->vtype
== TYCHAR
&& q
->vleng
== nil
) ){
sprintf(asmline
+len
, "%2d", writestabtype(TYSUBR
));
len
+= strlen(asmline
+len
);
sprintf(asmline
+len
, "\",0x%x,0,0,L%d\n",N_FUN
,p
->entrylabel
);
* Generate information for a symbol table (name block ) entry.
char *varname
, *classname
;
varname
= varstr(VL
, p
->varname
);
case CLPARAM
: /* parameter (constant) */
if ((ep
= ((struct Paramblock
*) p
)->paramval
) &&
switch(ep
->constblock
.vtype
) {
sprintf(buf
, "c=i%d", ep
->constblock
.constant
.ci
);
sprintf(buf
, "c=r%f", ep
->constblock
.constant
.cd
[0]);
case CLVAR
: /* variable */
if(p
->vstg
== STGARG
) classname
= "v";
case CLPROC
: /* external or function or subroutine */
case CLMAIN
: /* main program */
case CLENTRY
: /* secondary entry point */
case CLBLOCK
: /* block data name*/
ignore
= true; /* these are put out by entrystab */
sprintf(asmline
, "\t.stabs\t\"%s:%s", varname
, classname
);
len
+= strlen(asmline
+len
);
if (p
->vclass
== CLPARAM
) {
/* these have zero storage class for some reason */
sprintf(asmline
+len
, "\",0x%x,0,0,0\n", N_LSYM
);
"\",0x%x,0,0,0 /* don't know how to calc loc for stg %d*/ \n",
sprintf(asmline
+len
,"\",0x%x,0,0,%d \n",
N_PSYM
,p
->vardesc
.varno
+ ARGOFFSET
);
sprintf(asmline
+len
, "\",0x%x,0,0,%d\n",
sprintf(asmline
+len
, "\",0x%x,0,0,v.%d\n",
(p
->inlcomm
? N_LCSYM
: N_STSYM
),
sprintf(asmline
+len
, "\",0x%x,0,0,%s + %d \n",
(p
->inlcomm
? N_LCSYM
: N_STSYM
) ,
memname(STGEQUIV
,p
->vardesc
.varno
),(p
->voffset
)) ;
sprintf(asmline
+len
, "\",0x%x,0,0,-%d \n",
static typenum
[NTYPES
+1]; /* has the given type already been defined ?*/
private writestabtype(type
)
static char *typename
[NTYPES
+1] = {
"unknown", "addr", "integer*2", "integer", "real", "double precision",
"complex", "double complex", "logical", "char", "void", "error", "logical*2" };
static int typerange
[NTYPES
+1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
/* compare with typesize[] in init.c */
static int typebounds
[2] [NTYPES
+1] ={
/* "unknown", "addr","integer*2", "integer", "real", "double precision", */
{ 0 , 0 , -32768, -2147483648, 4, 8,
/* "complex", "d-complex", "logical", "char", "void", "error", "logical*2" */
/* "unknown", "addr","integer*2", "integer", "real", "double precision", */
{ 0 , -1, 32767, 2147483647, 0, 0,
/* "complex", "d-complex", "logical", "char", "void", "error", "logical*2" */
if (type
< 0 || type
> NTYPES
)
badtype("writestabtype",type
);
/* substitute "logical*2" for "logical" when "-i2" compiler flag used */
if (type
== TYLOGICAL
&& tylogical
== TYSHORT
)
if (typenum
[type
]) return(typenum
[type
]);
sprintf(asmline
, "\t.stabs\t\"%s:t%d=r%d;%ld;%ld;\",0x%x,0,0,0 \n",
typename
[type
], type
, typerange
[type
], typebounds
[0][type
],
typebounds
[1][type
], N_GSYM
) ;
if (p
->vclass
== CLPROC
&& p
->vstg
== STGARG
)
if (t
< TYADDR
|| t
> TYSUBR
)
dclerr("can't get dbx basetype information",p
);
if (p
->vtype
== TYCHAR
|| p
->vdim
!= nil
)
return(writestabtype(t
));
* Generate debugging information for the given type of the given symbol.
if (p
->tag
!= TNAME
) badtag("addtypeinfo",p
->tag
);
if (p
->vclass
== CLPARAM
)
if(p
->vdim
!= (struct Dimblock
*) ENULL
) {
for (i
= p
->vdim
->ndim
-1; i
>=0 ; --i
) {
if(p
->vdim
->dims
[i
].lbaddr
== ENULL
) {
sprintf(lb
,"%d", p
->vdim
->dims
[i
].lb
->constblock
.constant
.ci
);
sprintf(lb
,"T%d", p
->vdim
->dims
[i
].lbaddr
->addrblock
.memoffset
->constblock
.constant
.ci
);
if(p
->vdim
->dims
[i
].ubaddr
== ENULL
) {
sprintf(ub
,"%d",p
->vdim
->dims
[i
].ub
->constblock
.constant
.ci
);
sprintf(ub
,"T%d",p
->vdim
->dims
[i
].ubaddr
->addrblock
.memoffset
->constblock
.constant
.ci
);
sprintf(asmline
+len
, "ar%d;%s;%s;", TYINT
, lb
, ub
);
len
+= strlen(asmline
+len
);
if (p
->vtype
== TYCHAR
) {
/* character type always an array(1:?) */
fatalstr("missing length in addtypeinfo for character variable %s", varstr(p
->varname
));
if (ISCONST(p
->vleng
)) sprintf(ub
,"%d",p
->vleng
->constblock
.constant
.ci
);
else sprintf(ub
,"A%d",p
->vleng
->addrblock
.memno
+ ARGOFFSET
);
sprintf(asmline
+len
,"ar%d;1;%s;", TYINT
, ub
);
len
+= strlen(asmline
+len
);
sprintf(asmline
+len
, "%d",tnum
);