* Symbolic debugging info interface.
* Here we generate pseudo-ops that cause the assembler to put
* symbolic debugging information into the object file.
static char *sccsid
="@(#)stab.c 1.7 (Berkeley) %G%";
#define bytes(bits) ((bits) / SZCHAR)
#define bsize(p) bytes(dimtab[p->sizoff]) /* size in bytes of a symbol */
* Flag for producing either sdb or dbx symbol information.
* Generate debugging info for a parameter.
* The offset isn't known when it is first entered into the symbol table
* since the types are read later.
printf("\t.stabs\t\"%s:p", p
->sname
);
printf("\",0x%x,0,%d,%d\n", N_PSYM
, bsize(p
), bytes(argoff
));
* Determine if the given symbol is a global array with dimension 0,
* which only makes sense if it's dimension is to be given later.
* We therefore currently do not generate symbol information for
#define isglobal(class) ( \
class == EXTDEF or class == EXTERN or class == STATIC \
private Boolean
zero_length_array(p
)
register struct symtab
*p
;
if (not isglobal(p
->sclass
)) {
b
= (Boolean
) (ISARY(t
) and dimtab
[p
->dimoff
] == 0);
* Generate debugging info for a given symbol.
register struct symtab
*p
;
static Boolean firsttime
= true;
} else if (gdebug
and not zero_length_array(sym
)) {
offset
= bytes(p
->offset
);
* Locals are the default class.
} else if (p
->slevel
<= 1) {
entertype(p
->stype
, NILINDEX
, FORWARD
, dimtab
[p
->sizoff
+ 3]);
if ((p
->sclass
&FIELD
) == 0) {
printf("/* no info for %s (%d) */\n", p
->sname
, p
->sclass
);
printf("\t.stabs\t\"%s:%s", p
->sname
, classname
);
* Since type names are lost in the travels and because C has
* structural type equivalence we keep a table of type words that
* we've already seen. The first time we see a type, it is assigned
* (inline) a number and future references just list that number.
* Structures, unions, enums, and arrays must be handled carefully
* since not all the necessary information is in the type word.
typedef struct Typeid
*Typeid
;
private int t_int
, t_char
;
private Typeid typetable
[TABLESIZE
];
* Look for the given type word in the type table.
private Typeid
typelookup(type
, arrindex
, strindex
, strtag
)
t
= typetable
[type mod TABLESIZE
];
strindex
== t
->tstruct
and strtag
== t
->tstrtag
) {
if (arrindex
== NILINDEX
) {
while (ISARY(tword
) and dimtab
[i1
] == dimtab
[i2
]) {
* Enter a type word and associated symtab indices into the type table.
private int entertype(type
, arrindex
, strindex
, strtag
)
t
= (Typeid
) malloc(sizeof(struct Typeid
));
* Change the information associated with a type table entry.
* Since I'm lazy this just creates a new entry with the number
private reentertype(typeid, type
, arrindex
, strindex
, strtag
)
t
= (Typeid
) malloc(sizeof(struct Typeid
));
* Initialize type table with predefined types.
#define builtintype(type) entertype(type, NILINDEX, NILINDEX, NILINDEX)
t_int
= builtintype(INT
);
t_char
= builtintype(CHAR
);
maketype("int", t_int
, t_int
, 0x80000000L
, 0x7fffffffL
);
maketype("char", t_char
, t_char
, 0L, 127L);
maketype("long", builtintype(LONG
), t_int
, 0x80000000L
, 0x7fffffffL
);
maketype("short", builtintype(SHORT
), t_int
, 0xffff8000L
, 0x7fffL
);
maketype("unsigned char", builtintype(UCHAR
), t_int
, 0L, 255L);
maketype("unsigned short", builtintype(USHORT
), t_int
, 0L, 0xffffL
);
maketype("unsigned long", builtintype(ULONG
), t_int
, 0L, 0xffffffffL
);
maketype("unsigned int", builtintype(UNSIGNED
), t_int
, 0L, 0xffffffffL
);
maketype("float", builtintype(FLOAT
), t_int
, 4L, 0L);
maketype("double", builtintype(DOUBLE
), t_int
, 8L, 0L);
printf("\t.stabs\t\"void:t%d=%d", t
, t
);
printf("\t.stabs\t\"???:t%d=%d", t
, t_int
);
* Generate info for a new range type.
private maketype(name
, tnum
, eqtnum
, lower
, upper
)
printf("\t.stabs\t\"%s:t%d=r%d;%d;%d;", name
, tnum
, eqtnum
, lower
, upper
);
* Generate debugging information for the given type of the given symbol.
register struct symtab
*p
;
register TWORD basictype
;
int i
, arrindex
, strindex
, strtag
;
if (basictype
== STRTY
or basictype
== UNIONTY
or basictype
== ENUMTY
) {
strindex
= dimtab
[p
->sizoff
+ 1];
strtag
= dimtab
[p
->sizoff
+ 3];
typeid = typelookup(t
, arrindex
, strindex
, strtag
);
while (t
!= basictype
and typeid == nil
) {
printf("%d=", entertype(t
, i
, strindex
, strtag
));
printf("ar%d;0;%d;", t_int
, dimtab
[i
++] - 1);
typeid = typelookup(t
, NILINDEX
, strindex
, strtag
);
typeid = typelookup(t
, i
, strindex
, strtag
);
if (strindex
== FORWARD
) {
typeid = typelookup(t
, NILINDEX
, FORWARD
, dimtab
[p
->sizoff
+ 3]);
cerror("unbelievable forward reference");
printf("%d", typeid->tnum
);
genstruct(t
, NILINDEX
, strindex
, p
->sname
, bsize(p
));
printf("%d", typeid->tnum
);
* Generate type information for structures, unions, and enumerations.
private genstruct(t
, structid
, index
, name
, size
)
register struct symtab
*field
;
if (structid
== NILINDEX
) {
id
= entertype(t
, NILINDEX
, index
, NILINDEX
);
printf("%d=%c%d", id
, t
== STRTY
? 's' : 'u', size
);
while (dimtab
[i
] != -1) {
field
= &stab
[dimtab
[i
]];
printf("%s:", field
->sname
);
if (field
->sclass
> FIELD
) {
printf(",%d,%d;", field
->offset
, field
->sclass
- FIELD
);
printf(",%d,%d;", field
->offset
,
tsize(field
->stype
, field
->dimoff
, field
->sizoff
));
while (dimtab
[i
] != -1) {
field
= &stab
[dimtab
[i
]];
printf("%s:%d,", field
->sname
, field
->offset
);
cerror("couldn't find basic type %d for %s\n", t
, name
);
* Generate offset and size info.
register struct symtab
*p
;
printf("\",0x%x,0,0,0\n", N_LSYM
);
printf("\",0x%x,0,%d,_%s\n", N_FUN
, bsize(p
), p
->sname
);
printf("\",0x%x,0,%d,0\n", N_GSYM
, bsize(p
));
printf("\",0x%x,0,%d,_%s\n", N_FUN
, bsize(p
), p
->sname
);
} else if (p
->slevel
> 1) {
printf("\",0x%x,0,%d,L%d\n", N_LCSYM
, bsize(p
), p
->offset
);
printf("\",0x%x,0,%d,_%s\n", N_LCSYM
, bsize(p
), p
->sname
);
printf("\",0x%x,0,%d,%d\n", N_RSYM
, bsize(p
), p
->offset
);
printf("\",0x%x,0,%d,%d\n", N_PSYM
, bsize(p
), bytes(argoff
));
printf("\",0x%x,0,%d,%d\n", N_LSYM
, bsize(p
), bytes(p
->offset
));
* Generate information for a newly-defined structure.
outstruct(szindex
, paramindex
)
register struct symtab
*p
;
register int i
, t
, strindex
;
strindex
= dimtab
[p
->sizoff
+ 1];
typeid = typelookup(p
->stype
, NILINDEX
, FORWARD
, i
);
reentertype(typeid, p
->stype
, NILINDEX
, strindex
, NILINDEX
);
printf("\t.stabs\t\"%s:T", p
->sname
);
genstruct(p
->stype
, t
, strindex
, p
->sname
, bsize(p
));
/* locctr(PROG); /* .stabs must appear in .text for c2 */
printf("\t.stabs\t\"%.8s\",", name
);
printf("\t.stabs\t\"%s\",", name
);
if (c
= name
[i
]) printf("'%c,", c
);
old_pstabdot(type
, value
);
/* locctr(PROG); /* .stabs must appear in .text for c2 */
printf("0%o,0,0%o\n",type
, value
);
while ( *cq
) if ( *cp
++ != *cq
++ ) goto neq
;
if ( *cp
== '\0' ) goto eq
;
neq
: for (i
=0; i
<100; i
++)
for ( cp
= ititle
+1; *(cp
-1); cp
+= 8 ) {
if (gdebug
) printf("0,0,LL%d\n", labelno
);
if (gdebug
) printf("0,0,LL%d\n", labelno
);
printf("LL%d:\n", labelno
++);
eq
: if (lineno
== lastlineno
) return;
pstabdot(N_SLINE
, lineno
);
pstab(NULLNAME
, N_SLINE
);
printf("0,%d,LL%d\n", lineno
, labelno
);
printf("LL%d:\n", labelno
++);
pstabdot(N_LBRAC
, level
);
pstab(NULLNAME
, N_LBRAC
);
printf("0,%d,LL%d\n", level
, labelno
);
printf("LL%d:\n", labelno
++);
pstabdot(N_RBRAC
, level
);
pstab(NULLNAME
, N_RBRAC
);
printf("0,%d,LL%d\n", level
, labelno
);
printf("LL%d:\n", labelno
++);
register struct symtab
*p
;
p
= &stab
[lookup(sname
, 0)];
printf("\t.stabs\t\"%s:", p
->sname
);
putchar((p
->sclass
== STATIC
) ? 'f' : 'F');
* Old way of doing things.
old_pstab(p
->sname
, N_PSYM
);
if (gdebug
) printf("0,%d,%d\n", p
->stype
, argoff
/SZCHAR
);
old_pstab(pname
, N_LSYM
);
printf("0,%d,%d\n", ptype
, (-poffset
)/SZCHAR
);
old_pstab(pname
, N_GSYM
);
printf("0,%d,0\n", ptype
);
/* stabLCSYM is 1 during nidcl so we can get stab type right */
old_pstab(pname
, stabLCSYM
? N_LCSYM
: N_STSYM
);
old_pstab(pname
, N_STSYM
);
printf("0,%d,L%d\n", ptype
, poffset
);
printf("0,%d,%s\n", ptype
, exname(pname
));
old_pstab(pname
, N_RSYM
);
printf("0,%d,%d\n", ptype
, poffset
);
old_pstab(pname
, N_SSYM
);
printf("0,%d,%d\n", ptype
, poffset
/SZCHAR
);
/* parameter stab entries are processed in dclargs() */
if (ddebug
) printf(" No .stab for %.8s\n", pname
);
if (ddebug
) printf(" No .stab for %s\n", pname
);
private old_pstab(name
, type
)
/* locctr(PROG); /* .stabs must appear in .text for c2 */
printf("\t.stabs\t\"%.8s\", ", name
);
printf("\t.stabs\t\"%s\", ", name
);
if (c
= name
[i
]) printf("'%c,", c
);
private old_pstabdot(type
, value
)
/* locctr(PROG); /* .stabs must appear in .text for c2 */
printf("0%o,0,0%o\n",type
, value
);
register struct symtab
*p
; {
if ((s
= dimtab
[p
->sizoff
]/SZCHAR
) > 1) {
old_pstab(p
->sname
, N_LENG
);
while ( *cq
) if ( *cp
++ != *cq
++ ) goto neq
;
if ( *cp
== '\0' ) goto eq
;
neq
: for (i
=0; i
<100; i
++)
for ( cp
= ititle
+1; *(cp
-1); cp
+= 8 ) {
if (gdebug
) printf("0,0,LL%d\n", labelno
);
old_pstab(ititle
+1, N_SOL
);
if (gdebug
) printf("0,0,LL%d\n", labelno
);
printf("LL%d:\n", labelno
++);
eq
: if (lineno
== lastlineno
) return;
old_pstabdot(N_SLINE
, lineno
);
old_pstab(NULLNAME
, N_SLINE
);
printf("0,%d,LL%d\n", lineno
, labelno
);
printf("LL%d:\n", labelno
++);
private old_plcstab(level
) {
old_pstabdot(N_LBRAC
, level
);
old_pstab(NULLNAME
, N_LBRAC
);
printf("0,%d,LL%d\n", level
, labelno
);
printf("LL%d:\n", labelno
++);
private old_prcstab(level
) {
pstabdot(N_RBRAC
, level
);
pstab(NULLNAME
, N_RBRAC
);
printf("0,%d,LL%d\n", level
, labelno
);
printf("LL%d:\n", labelno
++);
private old_pfstab(sname
)
printf("0,%d,_%.7s\n", lineno
, sname
);
printf("0,%d,_%s\n", lineno
, sname
);