📄 object.c
字号:
break; /* * Source files. */ case N_SO: n = identname(name, true); enterSourceModule(n, (Address) np->n_value); break; /* * Textually included files. */ case N_SOL: enterfile(name, (Address) np->n_value); break; /* * These symbols are assumed to have non-nil names. */ case N_GSYM: case N_FUN: case N_STSYM: case N_LCSYM: case N_RSYM: case N_PSYM: case N_LSYM: case N_SSYM: case N_LENG: if (index(name, ':') == nil) { if (not warned) { warned = true; warning("old style symbol information found in \"%s\"", curfilename()); } } else { entersym(name, np); } break; case N_PC: case N_MOD2: break; default: printf("warning: stab entry unrecognized: "); if (name != nil) { printf("name %s,", name); } printf("ntype %2x, desc %x, value %x'\n", np->n_type, np->n_desc, np->n_value); break; }}/* * Try to find the symbol that is referred to by the given name. * Since it's an external, we may want to follow a level of indirection. */private Symbol findsym (n)Name n;{ register Symbol r, s; find(s, n) where s->level == program->level and (s->class == EXTREF or s->class == VAR or s->class == PROC or s->class == FUNC) endfind(s); if (s != nil and s->class == EXTREF) { r = s->symvalue.extref; delete(s); } else { r = s; } return r;}/* * Check to see if a global _name is already in the symbol table, * if not then insert it. */private check_global (name, np)String name;register struct nlist *np;{ register Name n; register Symbol t, u; if (not streq(name, "end")) { n = identname(name, true); if ((np->n_type&N_TYPE) == N_TEXT) { t = findsym(n); if (t == nil) { t = insert(n); t->language = findlanguage(".s"); t->class = FUNC; t->type = t_int; t->block = curblock; t->level = program->level; t->symvalue.funcv.src = false; t->symvalue.funcv.inline = false; } if (t->class == VAR) { t->symvalue.offset = np->n_value; } else { t->symvalue.funcv.beginaddr = np->n_value; newfunc(t, codeloc(t)); findbeginning(t); } } else if ((np->n_type&N_TYPE) == N_BSS) { find(t, n) where t->class == COMMON endfind(t); if (t != nil) { u = (Symbol) t->symvalue.common.offset; while (u != nil) { u->symvalue.offset = u->symvalue.common.offset+np->n_value; u = u->symvalue.common.chain; } } else { check_var(np, n); } } else { check_var(np, n); } }}/* * Check to see if a namelist entry refers to a variable. * If not, create a variable for the entry. In any case, * set the offset of the variable according to the value field * in the entry. */private check_var (np, n)struct nlist *np;register Name n;{ register Symbol t; t = findsym(n); if (t == nil) { t = insert(n); t->language = findlanguage(".s"); t->class = VAR; t->type = t_int; t->level = program->level; t->block = curblock; } t->symvalue.offset = np->n_value;}/* * Check to see if a local _name is known in the current scope. * If not then enter it. */private check_local (name, np)String name;register struct nlist *np;{ register Name n; register Symbol t, cur; n = identname(name, true); cur = ((np->n_type&N_TYPE) == N_TEXT) ? curmodule : curblock; find(t, n) where t->block == cur endfind(t); if (t == nil) { t = insert(n); t->language = findlanguage(".s"); t->type = t_int; t->block = cur; t->level = cur->level; if ((np->n_type&N_TYPE) == N_TEXT) { t->class = FUNC; t->symvalue.funcv.src = false; t->symvalue.funcv.inline = false; t->symvalue.funcv.beginaddr = np->n_value; newfunc(t, codeloc(t)); findbeginning(t); } else { t->class = VAR; t->symvalue.offset = np->n_value; } }}/* * Check to see if a symbol corresponds to a object file name. * For some reason these are listed as in the text segment. */private check_filename (name)String name;{ register String mname; register integer i; register Symbol s; mname = strdup(name); i = strlen(mname) - 2; if (i >= 0 and mname[i] == '.' and mname[i+1] == 'o') { mname[i] = '\0'; --i; while (mname[i] != '/' and i >= 0) { --i; } s = insert(identname(&mname[i+1], true)); s->language = findlanguage(".s"); s->class = MODULE; s->symvalue.funcv.beginaddr = 0; findbeginning(s); if (curblock->class != PROG) { exitblock(); if (curblock->class != PROG) { exitblock(); } } enterblock(s); curmodule = s; }}/* * Check to see if a symbol is about to be defined within an unnamed block. * If this happens, we create a procedure for the unnamed block, make it * "inline" so that tracebacks don't associate an activation record with it, * and enter it into the function table so that it will be detected * by "whatblock". */public chkUnnamedBlock (){ register Symbol s; static int bnum = 0; char buf[100]; Address startaddr; if (nesting > 0 and addrstk[nesting] != NOADDR) { startaddr = (linep - 1)->addr; ++bnum; sprintf(buf, "$b%d", bnum); s = insert(identname(buf, false)); s->language = curlang; s->class = PROC; s->symvalue.funcv.src = false; s->symvalue.funcv.inline = true; s->symvalue.funcv.beginaddr = startaddr; enterblock(s); newfunc(s, startaddr); addrstk[nesting] = NOADDR; }}/* * Compilation unit. C associates scope with filenames * so we treat them as "modules". The filename without * the suffix is used for the module name. * * Because there is no explicit "end-of-block" mark in * the object file, we must exit blocks for the current * procedure and module. */private enterSourceModule (n, addr)Name n;Address addr;{ register Symbol s; Name nn; String mname, suffix; mname = strdup(ident(n)); if (rindex(mname, '/') != nil) { mname = rindex(mname, '/') + 1; } suffix = rindex(mname, '.'); curlang = findlanguage(suffix); if (curlang == findlanguage(".f")) { strip_ = true; } if (suffix != nil) { *suffix = '\0'; } if (not (*language_op(curlang, L_HASMODULES))()) { if (curblock->class != PROG) { exitblock(); if (curblock->class != PROG) { exitblock(); } } nn = identname(mname, true); if (curmodule == nil or curmodule->name != nn) { s = insert(nn); s->class = MODULE; s->symvalue.funcv.beginaddr = 0; findbeginning(s); } else { s = curmodule; } s->language = curlang; enterblock(s); curmodule = s; } if (program->language == nil) { program->language = curlang; } warned = false; enterfile(ident(n), addr); initTypeTable();}/* * Allocate file and line tables and initialize indices. */private allocmaps (nf, nl)integer nf, nl;{ if (filetab != nil) { dispose(filetab); } if (linetab != nil) { dispose(linetab); } filetab = newarr(Filetab, nf); linetab = newarr(Linetab, nl); filep = filetab; linep = linetab;}/* * Add a file to the file table. * * If the new address is the same as the previous file address * this routine used to not enter the file, but this caused some * problems so it has been removed. It's not clear that this in * turn may not also cause a problem. */private enterfile (filename, addr)String filename;Address addr;{ filep->addr = addr; filep->filename = filename; filep->lineindex = linep - linetab; ++filep;}/* * Since we only estimated the number of lines (and it was a poor * estimation) and since we need to know the exact number of lines * to do a binary search, we set it when we're done. */private setnlines (){ nlhdr.nlines = linep - linetab;}/* * Similarly for nfiles ... */private setnfiles (){ nlhdr.nfiles = filep - filetab; setsource(filetab[0].filename);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -