📄 stabstring.c
字号:
/* @(#)stabstring.c 4.1 Ultrix 7/3/90 *//************************************************************************ * * * Copyright (c) 1986, 1988 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 * * * * 010 - Added code to publicRoutine to set start address for * * FORTRAN functions. Subroutines were working off the * * text symbol already. * * (jlr, October 21, 1987; change rediscovered May 3, 1988) * * * * 009 - Fixed up entersym() to nuke the trailing '_' from all * * symbols for FORTRAN/C mixed programs. Previously, * * those symbols with symbolic info (after ':') weren't * * being fixed. (I thought I did this earlier...) * * (jlr, May 6, 1988) * * * * 008 - Jacked up NTYPES from 1000 to 10000. Needed for vcc * * compiled programs, especially. * * (Jon Reeves, April 21, 1988) * * * * 007 - Merged in 4.3 changes. * * (vjh, April 29, 1986) * * * * 006 - Added minimal support for constants (issues warning), and * * added support for jsb routines. T_JSB is a new addition * * to the grammar. * * (vjh, August 9, 1985) * * * * 005 - Added a new routine mkdstsym(), that handles DST records * * that cannot map to a stab entry. * * Also fixed a bug: added call to getType() under EXTVAR * * case in entersym(). Type information still needs to be * * entered in the type table, even if the symbol has been * * seen before. * * (vjh, June 26, 1985) * * * * 004 - In constype(), under T_FUNCVAR, call findlanguage() * * to determine current language. Used to do a string * * compare of ".c" against call to language_name(). * * (vjh, June 22, 1985) * * * * 003 - Wrote makeRVariable macro. Added new type REGDISP, for * * register indirection/displacement. * * (vjh, June 22, 1985) * * * * 002 - Assume that any function encountered before the loader * * namelist has source information, so set funcv.src to * * be true in both publicRoutine() and privateRoutine(). * * (vjh, May 30, 1985) * * * * 001 - Modified case EXTFUNCTION to fix a FORTRAN bug (this fix * * should actually go into the compiler). f77 outputs more * * than one N_FUN stab for a function, so have to check to * * see if the debugger has already allocated one of the * * current name; if not, still call newSym. * * (Victoria Holt, May 2, 1985) * * * ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)stabstring.c 4.1 ULTRIX 7/3/90";#endif not lint/* * String information interpretation * * The string part of a stab entry is broken up into name and type information. */#include "defs.h"#include "stabstring.h"#include "object.h"#include "main.h"#include "symbols.h"#include "names.h"#include "languages.h"#include "tree.h"#include <a.out.h>#include <ctype.h>#ifndef public#endif/* * Special characters in symbol table information. */#define CONSTNAME 'c'#define TYPENAME 't'#define TAGNAME 'T'#define MODULEBEGIN 'm'#define EXTPROCEDURE 'P'#define PRIVPROCEDURE 'Q'#define INTPROCEDURE 'I'#define EXTFUNCTION 'F'#define PRIVFUNCTION 'f'#define INTFUNCTION 'J'#define ENTRYPOINT 'E'#define EXTVAR 'G'#define MODULEVAR 'S'#define OWNVAR 'V'#define REGVAR 'r'#define REGDISP 'R'#define VALUEPARAM 'p'#define VARIABLEPARAM 'v'#define LOCALVAR /* default *//* * Type information special characters. */#define T_SUBRANGE 'r'#define T_ARRAY 'a'#define T_OLDOPENARRAY 'A'#define T_OPENARRAY 'O'#define T_DYNARRAY 'D'#define T_SUBARRAY 'E'#define T_RECORD 's'#define T_UNION 'u'#define T_ENUM 'e'#define T_PTR '*'#define T_JSB 'j'#define T_FUNCVAR 'f'#define T_PROCVAR 'p'#define T_IMPORTED 'i'#define T_SET 'S'#define T_OPAQUE 'o'#define T_FILE 'd'/* * Table of types indexed by per-file unique identification number. */#define NTYPES 10000private Symbol typetable[NTYPES];public initTypeTable (){ bzero(typetable, sizeof(typetable)); (*language_op(curlang, L_MODINIT))(typetable);}/* * Put an nlist entry into the symbol table. * If it's already there just add the associated information. * * Type information is encoded in the name following a ":". */private Symbol constype();private Char *curchar;#define skipchar(ptr, ch) \{ \ if (*ptr != ch) { \ panic("expected char '%c', found '%s'", ch, ptr); \ } \ ++ptr; \}#define optchar(ptr, ch) \{ \ if (*ptr == ch) { \ ++ptr; \ } \}#define chkcont(ptr) \{ \ if (*ptr == '?') { \ ptr = getcont(); \ } \}#define newSym(s, n) \{ \ s = insert(n); \ s->level = curblock->level + 1; \ s->language = curlang; \ s->block = curblock; \}#define makeVariable(s, n, off) \{ \ newSym(s, n); \ s->class = VAR; \ s->symvalue.offset = off; \ getType(s); \}#define makeRVariable(s, n, r, indir, disp) \{ \ newSym(s, n); \ s->class = VAR; \ s->symvalue.raddr.reg = r; \ s->symvalue.raddr.indirect = indir; \ s->symvalue.raddr.displacement = disp; \ s->level = -(s->level); \ getType(s); \}#define makeParameter(s, n, cl, off) \{ \ newSym(s, n); \ s->class = cl; \ s->symvalue.offset = off; \ curparam->chain = s; \ curparam = s; \ getType(s); \}public entersym (name, np)String name;struct nlist *np;{ Symbol s, t; char *p; register Name n; char c; p = index(name, ':'); *p = '\0'; if (strip_ && (*(p-1) == '_')) *(p-1) = '\0'; c = *(p+1); n = identname(name, true); chkUnnamedBlock(); curchar = p + 2; switch (c) { case CONSTNAME: newSym(s, n); constName(s); break; case TYPENAME: newSym(s, n); typeName(s); break; case TAGNAME: s = symbol_alloc(); s->name = n; s->level = curblock->level + 1; s->language = curlang; s->block = curblock; tagName(s); break; case MODULEBEGIN: publicRoutine(&s, n, MODULE, np->n_value, false); curmodule = s; break; case EXTPROCEDURE: publicRoutine(&s, n, PROC, np->n_value, false); break; case PRIVPROCEDURE: privateRoutine(&s, n, PROC, np->n_value); break; case INTPROCEDURE: publicRoutine(&s, n, PROC, np->n_value, true); break; case ENTRYPOINT: case EXTFUNCTION: publicRoutine(&s, n, FUNC, np->n_value, false); break; case PRIVFUNCTION: privateRoutine(&s, n, FUNC, np->n_value); break; case INTFUNCTION: publicRoutine(&s, n, FUNC, np->n_value, true); break; case EXTVAR: extVar(&s, n, np->n_value); break; case MODULEVAR: if (curblock->class != MODULE) { exitblock(); } makeVariable(s, n, np->n_value); s->level = program->level; s->block = curmodule; getExtRef(s); break; case OWNVAR: makeVariable(s, n, np->n_value); ownVariable(s, np->n_value); getExtRef(s); break; case REGVAR: makeRVariable(s, n, np->n_value, false, 0); break; case REGDISP: makeRVariable(s, n, np->n_desc, ((Boolean) np->n_other), np->n_value); break; case VALUEPARAM: makeParameter(s, n, VAR, np->n_value); break; case VARIABLEPARAM: makeParameter(s, n, REF, np->n_value); break; default: /* local variable */ --curchar; makeVariable(s, n, np->n_value); break; } if (tracesyms) { printdecl(s); fflush(stdout); }}/* * Enter a named constant. */private constName (s)Symbol s;{ integer i; double d; char *p, buf[1000]; s->class = CONST; skipchar(curchar, '='); p = curchar; ++curchar; switch (*p) { case 'b': s->type = t_boolean; s->symvalue.constval = build(O_LCON, getint()); break; case 'c': s->type = t_char; s->symvalue.constval = build(O_LCON, getint()); break; case 'i': s->type = t_int; s->symvalue.constval = build(O_LCON, getint()); break; case 'r': sscanf(curchar, "%lf", &d); while (*curchar != '\0' and *curchar != ';') { ++curchar; } --curchar; s->type = t_real; s->symvalue.constval = build(O_FCON, d); break; case 's': p = &buf[0]; skipchar(curchar, '\''); while (*curchar != '\'') { *p = *curchar; ++p; ++curchar; } *p = '\0'; s->symvalue.constval = build(O_SCON, strdup(buf)); s->type = s->symvalue.constval->nodetype; break; case 'e': getType(s); skipchar(curchar, ','); s->symvalue.constval = build(O_LCON, getint()); break; case 'S': getType(s); skipchar(curchar, ','); i = getint(); /* set size */ skipchar(curchar, ','); i = getint(); /* number of bits in constant */ s->symvalue.constval = build(O_LCON, 0); break; default: s->type = t_int; s->symvalue.constval = build(O_LCON, 0); printf("[internal error: unknown constant type '%c']", *p); break; } s->symvalue.constval->nodetype = s->type;}/* * Enter a type name. */private typeName (s)Symbol s;{ register integer i; s->class = TYPE; s->language = curlang; s->block = curblock; s->level = curblock->level + 1; i = getint(); if (i == 0) { panic("bad input on type \"%s\" at \"%s\"", symname(s), curchar); } else if (i >= NTYPES) { panic("too many types in file \"%s\"", curfilename()); } /* * A hack for C typedefs that don't create new types, * e.g. typedef unsigned int Hashvalue; * or typedef struct blah BLAH; */ if (*curchar != '=') { s->type = typetable[i]; if (s->type == nil) { s->type = symbol_alloc(); typetable[i] = s->type; } } else { if (typetable[i] != nil) { typetable[i]->language = curlang; typetable[i]->class = TYPE; typetable[i]->type = s; } else { typetable[i] = s; } skipchar(curchar, '='); getType(s); }}/* * Enter a tag name. */private tagName (s)Symbol s;{ register integer i; s->class = TAG; i = getint(); if (i == 0) { panic("bad input on tag \"%s\" at \"%s\"", symname(s), curchar); } else if (i >= NTYPES) { panic("too many types in file \"%s\"", curfilename()); } if (typetable[i] != nil) { typetable[i]->language = curlang; typetable[i]->class = TYPE; typetable[i]->type = s; } else { typetable[i] = s; } skipchar(curchar, '='); getType(s);}/* * Setup a symbol entry for a public procedure or function. * * If it contains nested procedures, then it may already be defined * in the current block as a MODULE. */private publicRoutine (s, n, class, addr, internal)Symbol *s;Name n;Symclass class;Address addr;Boolean internal;{ Symbol nt, t; newSym(nt, n); if (internal) { markInternal(nt); } nt->symvalue.funcv.inline = false; nt->symvalue.funcv.beginaddr = addr; newfunc(nt, codeloc(nt)); findbeginning(nt); enterRoutine(nt, class); find(t, n) where t != nt and t->class == MODULE and t->block == nt->block endfind(t); if (t == nil) { t = nt; } else { t->language = nt->language; t->class = nt->class; t->type = nt->type; t->chain = nt->chain; t->symvalue = nt->symvalue; nt->class = EXTREF; nt->symvalue.extref = t; delete(nt); curparam = t; changeBlock(t); } if (t->block == program) { t->level = program->level; } else if (t->class == MODULE) { t->level = t->block->level; } else if (t->block->class == MODULE) { t->level = t->block->block->level; } else { t->level = t->block->level + 1; } *s = t;}/* * Setup a symbol entry for a private procedure or function. */private privateRoutine (s, n, class, addr)Symbol *s;Name n;Symclass class;Address addr;{ Symbol t; boolean isnew; find(t, n) where t->level == curmodule->level and t->class == class endfind(t); if (t == nil) { isnew = true; t = insert(n); } else { isnew = false; } t->language = curlang; enterRoutine(t, class); if (isnew) { t->symvalue.funcv.inline = false; t->symvalue.funcv.beginaddr = addr; newfunc(t, codeloc(t)); findbeginning(t); } *s = t;}/* * Set up for beginning a new procedure, function, or module. Make note * if it is a jsb-routine. If it's a function, read the type. * * If the next character is a ",", then read the name of the enclosing block. * Otherwise assume the previous function, if any, is over, and the current * routine is at the same level. */private enterRoutine (s, class)Symbol s;Symclass class;{ s->class = class; if (*curchar == T_JSB) { mark_jsb(s); ++curchar; } if (class == FUNC) { getType(s); } if (s->class != MODULE) { getExtRef(s); } else if (*curchar == ',') { ++curchar; } if (*curchar != '\0') { exitblock(); enterNestedBlock(s); } else { if (curblock->class == FUNC or curblock->class == PROC) { exitblock(); } if (class == MODULE) { exitblock(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -