📄 object.c
字号:
/*#@(#)object.c 4.1 Ultrix 7/17/90*//* Copyright (c) 1982 Regents of the University of California */static char sccsid[] = "@(#)object.c 1.14 10/22/83";static char rcsid[] = "$Header: object.c,v 1.4 84/03/27 10:22:25 linton Exp $";/* * Object code interface, mainly for extraction of symbolic information. */#include "defs.h"#include "object.h"#include "stabstring.h"#include "main.h"#include "symbols.h"#include "names.h"#include "languages.h"#include "mappings.h"#include "lists.h"#include <a.out.h>#include <stab.h>#include <ctype.h>#ifndef publicstruct { unsigned int stringsize; /* size of the dumped string table */ unsigned int nsyms; /* number of symbols */ unsigned int nfiles; /* number of files */ unsigned int nlines; /* number of lines */} nlhdr;#include "languages.h"#include "symbols.h"#endif#ifndef N_MOD2# define N_MOD2 0x50#endifpublic String objname = "a.out";public integer objsize;public Language curlang;public Symbol curmodule;public Symbol curparam;public Symbol curcomm;public Symbol commchain;private char *stringtab;private struct nlist *curnp;private Boolean warned;private Boolean strip_ = false;private Filetab *filep;private Linetab *linep, *prevlinep;public String curfilename (){ return ((filep-1)->filename);}/* * Blocks are figured out on the fly while reading the symbol table. */#define MAXBLKDEPTH 25public Symbol curblock;private Symbol blkstack[MAXBLKDEPTH];private integer curlevel;private integer bnum, nesting;private Address addrstk[MAXBLKDEPTH];public pushBlock (b)Symbol b;{ if (curlevel >= MAXBLKDEPTH) { fatal("nesting depth too large (%d)", curlevel); } blkstack[curlevel] = curblock; ++curlevel; curblock = b; if (traceblocks) { printf("entering block %s\n", symname(b)); }}public enterblock (b)Symbol b;{ if (curblock == nil) { b->level = 1; } else { b->level = curblock->level + 1; } b->block = curblock; pushBlock(b);}public exitblock (){ if (curblock->class == FUNC or curblock->class == PROC) { if (prevlinep != linep) { curblock->symvalue.funcv.src = true; } } if (curlevel <= 0) { panic("nesting depth underflow (%d)", curlevel); } --curlevel; if (traceblocks) { printf("exiting block %s\n", symname(curblock)); } curblock = blkstack[curlevel];}/* * Enter a source line or file name reference into the appropriate table. * Expanded inline to reduce procedure calls. * * private enterline (linenumber, address) * Lineno linenumber; * Address address; * ... */#define enterline(linenumber, address) \{ \ register Linetab *lp; \ \ lp = linep - 1; \ if (linenumber != lp->line) { \ if (address != lp->addr) { \ ++lp; \ } \ lp->line = linenumber; \ lp->addr = address; \ linep = lp + 1; \ } \}/* * Read in the namelist from the obj file. * * Reads and seeks are used instead of fread's and fseek's * for efficiency sake; there's a lot of data being read here. */public readobj (file)String file;{ Fileid f; struct exec hdr; struct nlist nlist; f = open(file, 0); if (f < 0) { fatal("can't open %s", file); } read(f, &hdr, sizeof(hdr)); objsize = hdr.a_text; nlhdr.nsyms = hdr.a_syms / sizeof(nlist); nlhdr.nfiles = nlhdr.nsyms; nlhdr.nlines = nlhdr.nsyms; if (nlhdr.nsyms > 0) { lseek(f, (long) N_STROFF(hdr), 0); read(f, &(nlhdr.stringsize), sizeof(nlhdr.stringsize)); nlhdr.stringsize -= 4; stringtab = newarr(char, nlhdr.stringsize); read(f, stringtab, nlhdr.stringsize); allocmaps(nlhdr.nfiles, nlhdr.nlines); lseek(f, (long) N_SYMOFF(hdr), 0); readsyms(f); ordfunctab(); setnlines(); setnfiles(); } close(f);}/* * Read in symbols from object file. */private readsyms (f)Fileid f;{ struct nlist *namelist; register struct nlist *np, *ub; register String name; register Boolean afterlg; integer index; char *lastchar; initsyms(); namelist = newarr(struct nlist, nlhdr.nsyms); read(f, namelist, nlhdr.nsyms * sizeof(struct nlist)); afterlg = false; ub = &namelist[nlhdr.nsyms]; curnp = &namelist[0]; np = curnp; while (np < ub) { index = np->n_un.n_strx; if (index != 0) { name = &stringtab[index - 4]; /* * If the program contains any .f files a trailing _ is stripped * from the name on the assumption it was added by the compiler. * This only affects names that follow the sdb N_SO entry with * the .f name. */ if (strip_ and name[0] != '\0' ) { lastchar = &name[strlen(name) - 1]; if (*lastchar == '_') { *lastchar = '\0'; } } } else { name = nil; } /* * Assumptions: * not an N_STAB ==> name != nil * name[0] == '-' ==> name == "-lg" * name[0] != '_' ==> filename or invisible * * The "-lg" signals the beginning of global loader symbols. * */ if ((np->n_type&N_STAB) != 0) { enter_nl(name, np); } else if (name[0] == '-') { afterlg = true; if (curblock->class != PROG) { exitblock(); if (curblock->class != PROG) { exitblock(); } } enterline(0, (linep-1)->addr + 1); } else if (afterlg) { if (name[0] == '_') { check_global(&name[1], np); } } else if (name[0] == '_') { check_local(&name[1], np); } else if ((np->n_type&N_TEXT) == N_TEXT) { check_filename(name); } ++curnp; np = curnp; } if (not afterlg) { fatal("not linked for debugging, use \"cc -g ...\""); } dispose(namelist);}/* * Get a continuation entry from the name list. * Return the beginning of the name. */public String getcont (){ register integer index; register String name; ++curnp; index = curnp->n_un.n_strx; if (index == 0) { panic("continuation followed by empty stab"); } name = &stringtab[index - 4]; return name;}/* * Initialize symbol information. */private initsyms (){ curblock = nil; curlevel = 0; nesting = 0; program = insert(identname("", true)); program->class = PROG; program->symvalue.funcv.beginaddr = 0; program->symvalue.funcv.inline = false; newfunc(program, codeloc(program)); findbeginning(program); enterblock(program); curmodule = program; t_boolean = maketype("$boolean", 0L, 1L); t_int = maketype("$integer", 0x80000000L, 0x7fffffffL); t_char = maketype("$char", 0L, 255L); t_real = maketype("$real", 8L, 0L); t_nil = maketype("$nil", 0L, 0L); t_open = maketype("integer", 0L, -1L);}/* * Free all the object file information that's being stored. */public objfree (){ symbol_free(); keywords_free(); names_free(); dispose(stringtab); clrfunctab();}/* * Enter a namelist entry. */private enter_nl (name, np)String name;register struct nlist *np;{ register Symbol s; register Name n; s = nil; switch (np->n_type) { /* * Build a symbol for the FORTRAN common area. All GSYMS that follow * will be chained in a list with the head kept in common.offset, and * the tail in common.chain. */ case N_BCOMM: if (curcomm) { curcomm->symvalue.common.chain = commchain; } n = identname(name, true); curcomm = lookup(n); if (curcomm == nil) { curcomm = insert(n); curcomm->class = COMMON; curcomm->block = curblock; curcomm->level = program->level; curcomm->symvalue.common.chain = nil; } commchain = curcomm->symvalue.common.chain; break; case N_ECOMM: if (curcomm) { curcomm->symvalue.common.chain = commchain; curcomm = nil; } break; case N_LBRAC: ++nesting; addrstk[nesting] = (linep - 1)->addr; break; case N_RBRAC: --nesting; if (addrstk[nesting] == NOADDR) { exitblock(); newfunc(curblock, (linep - 1)->addr); addrstk[nesting] = (linep - 1)->addr; } break; case N_SLINE: enterline((Lineno) np->n_desc, (Address) np->n_value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -