📄 stab.c
字号:
char *label; int line; { putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 , (int) label , N_PC , N_PGLABEL , ABS( line ) ); } /* * global constants */stabgconst( constant , line ) char *constant; int line; { putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 , (int) constant , N_PC , N_PGCONST , ABS( line ) ); }/* * Generate symbolic information about a constant. */stabconst (c)struct nl *c;{ if (opt('g') && oldway == 0) { putprintf("\t.stabs\t\"%s:c=", 1, c->symbol); if (c->type == nl + TSTR) { putprintf("s'%s'", 1, c->ptr[0]); } else if (c->type == nl + T1CHAR) { putprintf("c%d", 1, c->range[0]); } else if (isa(c->type, "i")) { putprintf("i%d", 1, c->range[0]); } else if (isa(c->type, "d")) { putprintf("r%g", 1, c->real); } else { putprintf("e", 1); gentype(c->type); putprintf(",%d", 1, c->range[0]); } putprintf("\",0x%x,0,0x%x,0x%x", 0, N_LSYM, 0, 0); }}stabgtype (name, type, line)char *name;struct nl *type;int line;{ putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0, name, N_PC , N_PGTYPE, ABS(line) ); if (oldway == 0) { stabltype(name, type); }}stabltype (name, type)char *name;struct nl *type;{ if (opt('g')) { putprintf("\t.stabs\t\"%s:t", 1, name); gentype(type); putprintf("\",0x%x,0,0,0", 0, N_LSYM); }} /* * external functions and procedures */ stabefunc( name , typeclass , line ) char *name; int typeclass; int line; { int type; if ( typeclass == FUNC ) { type = N_PEFUNC; } else if ( typeclass == PROC ) { type = N_PEPROC; } else { return; } putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 , (int) name , N_PC , type , ABS( line ) ); }/* * Generate type information encoded as a string for dbx. * The fwdptrnum field is used only when the type is a pointer * to a type that isn't known when it was entered. When the * type field is filled for some such tptr, fixfwdtype should * be called to output an equivalencing type definition. */typedef struct TypeDesc *TypeDesc;struct TypeDesc { struct nl *tptr; int tnum; int fwdptrnum; TypeDesc chain;};#define TABLESIZE 2003#define typehash(t) ( ( ((int) t) >> 2 ) % TABLESIZE )private int tcount = 1;private TypeDesc typetable[TABLESIZE];private TypeDesc tdlookup (t)struct nl *t;{ register TypeDesc td; td = typetable[typehash(t)]; while (td != NIL && td->tptr != t) { td = td->chain; } return td;}private int typelookup (t)struct nl *t;{ register TypeDesc td; int r; td = tdlookup(t); if (td == NIL) { r = 0; } else { r = td->tnum; } return r;}private int entertype (type)struct nl *type;{ register TypeDesc td; register int i; td = (TypeDesc) malloc(sizeof(struct TypeDesc)); td->tptr = type; td->tnum = tcount; td->fwdptrnum = 0; ++tcount; i = typehash(type); td->chain = typetable[i]; typetable[i] = td; return td->tnum;}/* * The in_types table currently contains "boolean", "char", "integer", * "real" and "_nil". (See nl.c for definition.) * The lookup call below will give the TYPE class nl entry for these * types. In each case except _nil, the type field of that entry is a RANGE * class nl entry for the type. Sometimes other symbol table entries * point to the TYPE entry (e.g., when there is a range over the base type), * and other entries point to the RANGE entry (e.g., for a variable of the * given type). We don't really want to distinguish between these uses * in dbx, and since it appears that the RANGE entries are not reused if * a range happens to coincide, we will give the two the same identifying * dbx type number. */private inittypes(){ int i; extern char *in_types[]; struct nl *p; for (i = 0; in_types[i] != NIL; i++) { p = lookup(in_types[i]); if (p != NIL) { entertype(p); if (p->type != NIL) { --tcount; /* see comment above */ entertype(p->type); } } }}static genarray (t)struct nl *t;{ register struct nl *p; for (p = t->chain; p != NIL; p = p->chain) { putprintf("a", 1); gentype(p); putprintf(";", 1); } gentype(t->type);}/* * Really we should walk through ptr[NL_FIELDLIST] for the fields, * and then do the variant tag and fields separately, but dbx * doesn't support this yet. * So, since all the fields of all the variants are on the chain, * we walk through that. Except that this gives the fields in the * reverse order, so we want to print in reverse order. */static genrecord (t)struct nl *t;{ putprintf("s%d", 1, t->value[NL_OFFS]); if (t->chain != NIL) { genrecfield(t->chain, 1); } putprintf(";", 1);}static genrecfield (t, n)struct nl *t;int n;{ if (t->chain != NULL) { genrecfield(t->chain, n + 1); if (n % 2 == 0) { gencontinue(); } } putprintf("%s:", 1, t->symbol); gentype(t->type); putprintf(",%d,%d;", 1, 8*t->value[NL_OFFS], 8*lwidth(t->type));}static genvarnt (t)struct nl *t;{ genrecord(t);}static genptr (t)struct nl *t;{ register TypeDesc td; putprintf("*", 1); if (t->type != NIL) { gentype(t->type); } else { /* * unresolved forward pointer: use tcount to represent what is * begin pointed to, to be defined later */ td = tdlookup(t); if (td == NIL) { panic("nil ptr in stab.genptr"); } td->fwdptrnum = tcount; putprintf("%d", 1, tcount); ++tcount; }}/* * The type t is a pointer which has just had its type field filled. * We need to generate a type stab saying that the number saved * in t's fwdptrnum is the same as the t->type's number */fixfwdtype (t)struct nl *t;{ register TypeDesc td; if (opt('g') && oldway == 0) { td = tdlookup(t); if (td != NIL) { putprintf("\t.stabs\t\":t%d=", 1, td->fwdptrnum); gentype(t->type); putprintf("\",0x%x,0,0,0", 0, N_LSYM); } }}static genenum (t)struct nl *t;{ register struct nl *e; register int i; putprintf("e", 1); i = 1; e = t->chain; while (e != NULL) { if (i > 2) { gencontinue(); i = 0; } putprintf("%s:%d,", 1, e->symbol, e->range[0]); e = e->chain; ++i; } putprintf(";", 1);}static genset (t)struct nl *t;{ putprintf("S", 1); gentype(t->type);}static genrange (t)struct nl *t;{ putprintf("r", 1); gentype(t->type); putprintf(";%d;%d", 1, t->range[0], t->range[1]);}static genfparam (t)struct nl *t;{ struct nl *p; int count; if (t->type != NULL) { putprintf("f", 1); gentype(t->type); putprintf(",", 1); } else { putprintf("p", 1); } count = 0; for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) { ++count; } putprintf("%d;", 1, count); for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) { gentype(p->type); putprintf(",%d;", 1, p->class); }}static genfile (t)struct nl *t;{ putprintf("d", 1); gentype(t->type);}static gentype (t)struct nl *t;{ int id; if (tcount == 1) { inittypes(); } id = typelookup(t); if (id != 0) { putprintf("%d", 1, id); } else if (t->class == SCAL && t->chain == NULL) { id = typelookup(t->type); if (id != 0) { putprintf("%d", 1, id); } else { genenum(t->type); } } else { id = entertype(t); putprintf("%d=", 1, id); switch (t->class) { case TYPE: gentype(t->type); break; case ARRAY: genarray(t); break; case RECORD: genrecord(t); break; case VARNT: genvarnt(t); break; case REF: gentype(t->type); break; case PTR: genptr(t); break; case SET: genset(t); break; case RANGE: genrange(t); break; case SCAL: genenum(t); break; case FPROC: case FFUNC: genfparam(t); break; case FILET: case PTRFILE: genfile(t); break; default: /* This shouldn't happen */ /* Rather than bomb outright, let debugging go on */ warning(); error("Bad type class found in stab"); putprintf("1", 1, t->class); break; } }}/* * Continue stab information in a namelist new entry. This is necessary * to avoid overflowing putprintf's buffer. */static gencontinue (){ putprintf("?\",0x%x,0,0,0", 0, N_LSYM); putprintf("\t.stabs\t\"", 1);}#endif PC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -