📄 stab.c
字号:
#ifndef lintstatic char *sccsid ="@(#)stab.c 4.1 (ULTRIX) 7/3/90";#endif/************************************************************************ * * * Copyright (c) 1985, 1987 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * Modification History * * 003 - Fixed array handling in gentype so, for instance, arrays * of pointers would generate proper indexes instead of -1. * (jlr, July 20, 1988) * * 002 - Replaced missing putchar(';') at end of enum types. * Caused "assertion failed" message from dbx. * (Jon Reeves, July 15, 1987) * * Victoria Holt, 26-Feb-86 * 001 Redefined Boolean in mfile1, so took out multiple definition * in this file. * ******************************************************************//* * Symbolic debugging info interface. * * Here we generate pseudo-ops that cause the assembler to put * symbolic debugging information into the object file. */#include "mfile1"#include <sys/types.h>#include <a.out.h>#include <stab.h>#define private static#define and &&#define or ||#define not !#define div /#define mod %#define nil 0#define bytes(bits) ((bits) / SZCHAR)#define bsize(p) bytes(dimtab[p->sizoff]) /* size in bytes of a symbol */#define NILINDEX -1#define FORWARD -2extern int ddebug;extern int gdebug;extern char *malloc();int stabLCSYM;/* * Flag for producing either sdb or dbx symbol information. */Boolean oldway = false;/* * 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. */fixarg(p)struct symtab *p;{ if (oldway) { old_fixarg(p); } else if (gdebug) { printf("\t.stabs\t\"%s:p", p->sname); gentype(p); 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 * such entries. */#define isglobal(class) ( \ class == EXTDEF or class == EXTERN or class == STATIC \)private Boolean zero_length_array(p)register struct symtab *p;{ Boolean b; int t; if (not isglobal(p->sclass)) { b = false; } else { t = p->stype; if (ISFTN(t)) { t = DECREF(t); } b = (Boolean) (ISARY(t) and dimtab[p->dimoff] == 0); } return b;}/* * Generate debugging info for a given symbol. */outstab(sym)struct symtab *sym;{ register struct symtab *p; char *classname; int offset; Boolean ignore; static Boolean firsttime = true; if (oldway) { old_outstab(sym); } else if (gdebug and not zero_length_array(sym)) { if (firsttime) { firsttime = false; inittypes(); } ignore = false; p = sym; offset = bytes(p->offset); switch (p->sclass) { case REGISTER: classname = "r"; offset = p->offset; break; /* * Locals are the default class. */ case AUTO: classname = ""; break; case STATIC: if (ISFTN(p->stype)) { ignore = true; } else if (p->slevel <= 1) { classname = "S"; } else { classname = "V"; } break; case EXTDEF: case EXTERN: if (ISFTN(p->stype)) { ignore = true; } else { classname = "G"; } break; case TYPEDEF: classname = "t"; break; case PARAM: case MOS: case MOU: case MOE: ignore = true; break; case ENAME: case UNAME: case STNAME: entertype(p->stype, NILINDEX, FORWARD, dimtab[p->sizoff + 3]); ignore = true; break; default: if ((p->sclass&FIELD) == 0) { printf("/* no info for %s (%d) */\n", p->sname, p->sclass); } ignore = true; break; } if (not ignore) { printf("\t.stabs\t\"%s:%s", p->sname, classname); gentype(p); geninfo(p); } }}/* * 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;struct Typeid { TWORD tword; int tarray; int tstruct; int tstrtag; int tnum; Typeid chain;};#define TABLESIZE 2003private int tcount = 1;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)TWORD type;int arrindex;int strindex;int strtag;{ register TWORD tword; register int i1, i2; Typeid t; t = typetable[type mod TABLESIZE]; while (t != nil) { if (t->tword == type and strindex == t->tstruct and strtag == t->tstrtag) { if (arrindex == NILINDEX) { break; } else { tword = type; i1 = arrindex; i2 = t->tarray; while (ISARY(tword) and dimtab[i1] == dimtab[i2]) { ++i1; ++i2; tword >>= TSHIFT; } if (!ISARY(tword)) { break; } } } t = t->chain; } return t;}/* * Enter a type word and associated symtab indices into the type table. */private int entertype(type, arrindex, strindex, strtag)TWORD type;int arrindex;int strindex;int strtag;{ register Typeid t; register int i; t = (Typeid) malloc(sizeof(struct Typeid)); t->tword = type; t->tarray = arrindex; t->tstruct = strindex; t->tstrtag = strtag; t->tnum = tcount; ++tcount; i = type mod TABLESIZE; t->chain = typetable[i]; typetable[i] = t; return t->tnum;}/* * Change the information associated with a type table entry. * Since I'm lazy this just creates a new entry with the number * as the old one. */private reentertype(typeid, type, arrindex, strindex, strtag)Typeid typeid;TWORD type;int arrindex;int strindex;int strtag;{ register Typeid t; register int i; t = (Typeid) malloc(sizeof(struct Typeid)); t->tword = type; t->tarray = arrindex; t->tstruct = strindex; t->tstrtag = strtag; t->tnum = typeid->tnum; i = type mod TABLESIZE; t->chain = typetable[i]; typetable[i] = t;}/* * Initialize type table with predefined types. */#define builtintype(type) entertype(type, NILINDEX, NILINDEX, NILINDEX)private inittypes(){ int t; 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); t = builtintype(UNDEF); printf("\t.stabs\t\"void:t%d=%d", t, t); geninfo(nil); t = builtintype(FARG); printf("\t.stabs\t\"???:t%d=%d", t, t_int); geninfo(nil);}/* * Generate info for a new range type. */private maketype(name, tnum, eqtnum, lower, upper)char *name;int tnum, eqtnum;long lower, upper;{ printf("\t.stabs\t\"%s:t%d=r%d;%d;%d;", name, tnum, eqtnum, lower, upper); geninfo(nil);}/* * Generate debugging information for the given type of the given symbol. */private gentype(sym)struct symtab *sym;{ register struct symtab *p; register TWORD t; register TWORD basictype; register Typeid typeid; int i, arrindex, strindex, strtag; p = sym; t = p->stype; if (ISFTN(t)) { t = DECREF(t); } basictype = BTYPE(t); if (ISARY(t)) { arrindex = p->dimoff; } else { arrindex = NILINDEX; } if (basictype == STRTY or basictype == UNIONTY or basictype == ENUMTY) { strindex = dimtab[p->sizoff + 1]; if (strindex == -1) { strindex = FORWARD; strtag = dimtab[p->sizoff + 3]; } else { strtag = NILINDEX; } } else { strindex = NILINDEX; strtag = NILINDEX; } i = arrindex; typeid = typelookup(t, arrindex, strindex, strtag); while (t != basictype and typeid == nil) { printf("%d=", entertype(t, i, strindex, strtag)); switch (t&TMASK) { case PTR: printf("*"); break; case FTN: printf("f"); break; case ARY: printf("ar%d;0;%d;", t_int, dimtab[i++] - 1); break; } t = DECREF(t); if (i == NILINDEX && ISARY(t)) { i = p->dimoff; } if (t == basictype) { typeid = typelookup(t, NILINDEX, strindex, strtag); } else { typeid = typelookup(t, i, strindex, strtag); } } if (typeid == nil) { if (strindex == FORWARD) { typeid = typelookup(t, NILINDEX, FORWARD, dimtab[p->sizoff + 3]); if (typeid == nil) { cerror("unbelievable forward reference"); } printf("%d", typeid->tnum); } else { genstruct(t, NILINDEX, strindex, p->sname, bsize(p)); } } else { printf("%d", typeid->tnum); }}/* * Generate type information for structures, unions, and enumerations. */private genstruct(t, structid, index, name, size)TWORD t;int structid;int index;char *name;int size;{ register int i; register struct symtab *field; int id; if (structid == NILINDEX) { id = entertype(t, NILINDEX, index, NILINDEX); } else { id = structid; } switch (t) { case STRTY: case UNIONTY: printf("%d=%c%d", id, t == STRTY ? 's' : 'u', size); i = index; while (dimtab[i] != -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -