⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 object.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/*@(#)object.c	4.3  Ultrix  12/6/90*//************************************************************************ *									* *			Copyright (c) 1986 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				* *									* *	016 - Updated all calls to findlanguage() to call with		* *	      LanguageName constant, rather than with a filename	* *	      suffix.							* *	      (Bob Neff, February 27, 1990)					* *									* *  015	- Added support for vectors.							* *		  (L Miller, 18JAN90)									* *									* *	014 - Change "use" so that a user can access source code in a * *		  logical fashion (i.e. specifiy the dir where the source * *		  code lives). Care was taken so that dbx will still work * *		  the same as before.									  * *	      (Lee R. Miller Jan 9, 1990)							  * *									* *	013 - Make "strip_" externally visible for stabstring.c so	* *	      C symbols within FORTRAN programs can be found.		* *	      (Jon Reeves, July 14, 1987)				* *									* *	012 - Fix for spr ICA-02533.  Was losing the address of	LCSYM	* *	      stab entries.  Change to checkvar().			* *	      (vjh, Nov. 11, 1986)					* *									* *	011 - 4.3 changes to check_global(), combined with the lack of	* *	      underscores on global VAX/FORTRAN symbol names, proved	* *	      to be a serious problem.  Additionally, VAX/FORTRAN	* *	      is indicating the wrong number of functions in the N_NSYM * *	      record.  Added changes to make all this stuff "work"	* *	      again.  Also added vmsFileConvert() for Bliss.		* *	      (vjh, July 16, 1986)					* *									* *	010 - Merged in 4.3 changes.					* *	      (vjh, April 29, 1986)					* *									* *	009 - Changed check_global() so that address calculation for	* *	      functions is only done for functions not already seen.	* *	      (vjh, Dec. 23, 1985)					* *									* *	008 - Added case for N_NOMAP in enter_nl().  Takes into account * *	      a DST record that will not map to a stab entry.		* *	      (vjh, June 26, 1985)					* *									* *	007 - enterSourceModule() checks for a LanguageName in n_other.	* *	      If not found, then the file extension is still used to	* *	      determine the language of the source file.		* *	      (vjh, June 22, 1985)					* *									* *	006 - Check for table overflow - function, source line, and	* *	      source file tables.					* *	      (vjh, June 22, 1985)					* *									* *	005 - Added dynamically allocated function table, and routine	* *	      newfunc().  Added code to handle new N_NSYMS stab entry.	* *	      (vjh, June 16, 1985)					* *									* *	004 - Assume that any function encountered before loader	* *	      namelist has source information.  This way, there are	* *	      fewer restrictions on the placement of N_SLINE entries	* *	      in the symbol table (for the FORTRAN port).  Also, speeds * *	      things up a bit (removed linep/prevlinep comparison in	* *	      exitblock macro).						* *	      (vjh, May 30, 1985)					* *									* *	003 - Assign curcomm->language so that fortran_printdecl()	* *	      can print the declared type of named common.  Used	* *	      to cause an internal error from a nil pointer.		* *	      (vjh, May 8, 1985)					* *									* *	002 - Fixed bug:  dbx would coredump if the name of a		* *	      FORTRAN common block was the same as a source file	* *	      name that was linked into the program.			* *	      (vjh, April 10, 1985)					* *									* *	001 - Added N_FNAME to case statement in enter_nl().		* *	      (Victoria Holt, April 5, 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 = "@(#)object.c	2.1	ULTRIX	4/24/89";#endif not lint/* * 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>#include <sys/param.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"#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;public Boolean strip_ = false;private Filetab *filep;private Linetab *linep;public String curfilename (){    return ((filep-1)->filename);}/* * Blocks are figured out on the fly while reading the symbol table. */#define MAXBLKDEPTH 100public Symbol curblock;private Symbol blkstack[MAXBLKDEPTH];private integer curlevel;private integer bnum, nesting;private Address addrstk[MAXBLKDEPTH];#define isfunc(s) \    (s->class == FUNC || s->class == PROC)public pushBlock (b)Symbol b;{    if (curlevel >= MAXBLKDEPTH) {	fatal("nesting depth too large (%d)", curlevel);    }    blkstack[curlevel] = curblock;    ++curlevel;    curblock = b;    if (traceblocks) {	printf("+%d entering block %s\n", curlevel, symname(b));    }}/* * Change the current block with saving the previous one, * since it is assumed that the symbol for the current one is to be deleted. */public changeBlock (b)Symbol b;{    curblock = 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 (curlevel <= 0) {	panic("nesting depth underflow (%d)", curlevel);    }    --curlevel;    if (traceblocks) {	printf("-%d exiting block %s\n", curlevel, 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; \ \    assert(linep); \    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;    register Filetab *ftp;	char *ptr, tmp[MAXPATHLEN];	String dir;	Boolean needed;    f = open(file, 0);    if (f < 0) {	fatal("can't open %s", file);    }    read(f, &hdr, sizeof(hdr));    if (N_BADMAG(hdr)) {	objsize = 0;	nlhdr.nsyms = 0;	nlhdr.nfiles = 0;	nlhdr.nlines = 0;    } else {	objsize = hdr.a_text;	nlhdr.nsyms = hdr.a_syms / sizeof(nlist);	nlhdr.nfiles = nlhdr.nsyms;	nlhdr.nlines = nlhdr.nsyms;    }	defvar(identname("$symtotal", true), build(O_LCON, 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();    	for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {			if(ptr = (char *)strrchr(ftp->filename, '/')) {				if(ptr != ftp->filename){    				if (rindex(objname, '/') != nil) {						strcpy(tmp, objname);						*(rindex(tmp, '/')) = '\0';						strcat(tmp, "/");						strncat(tmp, ftp->filename, ptr - ftp->filename);    				}					else {						strcpy(tmp, ftp->filename);						*(rindex(tmp, '/')) = '\0';					}					needed = true;					foreach (String, dir, sourcepath)						if(strcmp(tmp, dir) == 0) {							needed = false;							break;						}					endfor					if(needed) {						list_append(list_item(strdup(tmp)), nil, sourcepath);					}					ftp->filename = ++ptr;				}			}		}		setnfiles();    } else {		initsyms();    }    close(f);}/* * Found the beginning of the externals in the object file * (signified by the "-lg" or find an external), close the * block for the last procedure. */private foundglobals (){	while (curblock->class != PROG) 		exitblock();    enterline(0, (linep-1)->addr + 1);}/* * 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;	    foundglobals();	} else if (afterlg) {	    check_global(name, np);	} else if ((np->n_type&N_EXT) == N_EXT) {	    afterlg = true;	    foundglobals();	    check_global(name, 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;    }    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 (){    char *progname;		curblock = nil;    curlevel = 0;    nesting = 0;	if(rindex(objname, '/') != nil) {		progname = rindex(objname, '/') +1;	} else {		progname = objname;	}    program = insert(identname(progname, true));    program->class = PROG;    program->symvalue.funcv.beginaddr = 0;    program->symvalue.funcv.inline = false;    newfunc(program, codeloc(program));    findbeginning(program);    enterblock(program);    curmodule = program;}/* * 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;    char *p;    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); 	    find(curcomm, n) where curcomm->class == COMMON endfind(curcomm);	    if (curcomm == nil) {		curcomm = insert(n);		curcomm->class = COMMON;		curcomm->block = curblock;		curcomm->language = curlang;	/* curlang is fortran */		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);	    break;	/*	 * Source files.	 */	case N_SO:	    vmsFileConvert(name);	    n = identname(name, true);	    enterSourceModule(n, (Address) np->n_value,	        (LanguageName) np->n_other);	    break;	/*	 * Textually included files.	 */	case N_SOL:	    enterfile(name, (Address) np->n_value);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -