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

📄 object.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)object.c	5.5 (Berkeley) 3/5/91";#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>#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));    }}/* * 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 (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));    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;    }    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();    } 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 (){    if (curblock->class != PROG) {	exitblock();	if (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;    boolean afterlg, foundstab;    integer index;    char *lastchar;    initsyms();    namelist = newarr(struct nlist, nlhdr.nsyms);    read(f, namelist, nlhdr.nsyms * sizeof(struct nlist));    afterlg = false;    foundstab = 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) {	    foundstab = true;	    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;    }    if (not foundstab) {	warning("no source compiled with -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) {	name = "";    } else {	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->language = primlang;    program->symvalue.funcv.beginaddr = CODESTART;    program->symvalue.funcv.inlne = 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;    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);	    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;		    printf("warning: old style symbol information ");		    printf("found in \"%s\"\n", 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;    }}/*

⌨️ 快捷键说明

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