📄 stabstring.c
字号:
/*#@(#)stabstring.c 4.1 Ultrix 7/17/90*//* * String information interpretation * * The string part of a stab entry is broken up into name and type information. */static char rcsid[] = "$Header: stabstring.c,v 1.4 84/03/27 10:24:04 linton Exp $";#include "defs.h"#include "stabstring.h"#include "object.h"#include "main.h"#include "symbols.h"#include "names.h"#include "languages.h"#include <a.out.h>#include <ctype.h>#ifndef public#endif/* * Special characters in symbol table information. */#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 EXTVAR 'G'#define MODULEVAR 'S'#define OWNVAR 'V'#define REGVAR 'r'#define VALUEPARAM 'p'#define VARIABLEPARAM 'v'#define LOCALVAR /* default *//* * Type information special characters. */#define T_SUBRANGE 'r'#define T_ARRAY 'a'#define T_OPENARRAY 'A'#define T_RECORD 's'#define T_UNION 'u'#define T_ENUM 'e'#define T_PTR '*'#define T_FUNCVAR 'f'#define T_PROCVAR 'p'#define T_IMPORTED 'i'#define T_SET 'S'#define T_OPAQUE 'o'/* * Table of types indexed by per-file unique identification number. */#define NTYPES 1000private 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 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; char *p; register Name n; char c; p = index(name, ':'); *p = '\0'; c = *(p+1); n = identname(name, true); chkUnnamedBlock(); curchar = p + 2; switch (c) { case TYPENAME: newSym(s, n); typeName(s); break; case TAGNAME: newSym(s, n); tagName(s); break; case MODULEBEGIN: newSym(s, n); publicRoutine(s, MODULE, np->n_value); curmodule = s; break; case EXTPROCEDURE: newSym(s, n); publicRoutine(s, PROC, np->n_value); break; case PRIVPROCEDURE: privateRoutine(&s, n, PROC, np->n_value); break; case INTPROCEDURE: newSym(s, n); markInternal(s); publicRoutine(s, PROC, np->n_value); break; case EXTFUNCTION: newSym(s, n); publicRoutine(s, FUNC, np->n_value); break; case PRIVFUNCTION: privateRoutine(&s, n, FUNC, np->n_value); break; case INTFUNCTION: newSym(s, n); markInternal(s); publicRoutine(s, FUNC, np->n_value); break; case EXTVAR: find(s, n) where s->level == program->level and s->class == VAR endfind(s); if (s == nil) { makeVariable(s, n, np->n_value); s->level = program->level; s->block = program; getExtRef(s); } 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: makeVariable(s, n, np->n_value); s->level = -(s->level); 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 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. */private publicRoutine (s, class, addr)Symbol s;Symclass class;Address addr;{ enterRoutine(s, class); s->level = program->level;}/* * 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.src = false; 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. * If it's a function, then 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 (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(); } enterblock(s); } curparam = s;}/* * Check to see if the stab string contains the name of the external * reference. If so, we create a symbol with that name and class EXTREF, and * connect it to the given symbol. This link is created so that when * we see the linker symbol we can resolve it to the given symbol. */private getExtRef (s)Symbol s;{ char *p; Name n; Symbol t; if (*curchar == ',' and *(curchar + 1) != '\0') { p = index(curchar + 1, ','); *curchar = '\0'; if (p != nil) { *p = '\0'; n = identname(curchar + 1, false); curchar = p + 1; } else { n = identname(curchar + 1, true); } t = insert(n); t->language = s->language; t->class = EXTREF; t->block = program; t->level = program->level; t->symvalue.extref = s; }}/* * Find a block with the given identifier in the given outer block. * If not there, then create it. */private Symbol findBlock (id, m)String id;Symbol m;{ Name n; Symbol s; n = identname(id, true); find(s, n) where s->block == m and isblock(s) endfind(s); if (s == nil) { s = insert(n); s->block = m; s->language = curlang; s->class = MODULE; s->level = m->level + 1; } return s;}/* * Enter a nested block. * The block within which it is nested is described * by "module{:module}[:proc]". */private enterNestedBlock (b)Symbol b;{ register char *p, *q; Symbol m, s;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -