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

📄 object.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Try to find the symbol that is referred to by the given name.  Since it's * an external, we need to follow a level or two of indirection. */private Symbol findsym (n, var_isextref)Name n;boolean *var_isextref;{    register Symbol r, s;    *var_isextref = false;    find(s, n) where	(	    s->level == program->level and (		s->class == EXTREF or s->class == VAR or		s->class == PROC or s->class == FUNC	    )	) or (	    s->block == program and s->class == MODULE	)    endfind(s);    if (s == nil) {	r = nil;    } else if (s->class == EXTREF) {	*var_isextref = true;	r = s->symvalue.extref;	delete(s);	/*	 * Now check for another level of indirection that could come from	 * a forward reference in procedure nesting information.  In this case	 * the symbol has already been deleted.	 */	if (r != nil and r->class == EXTREF) {	    r = r->symvalue.extref;	}/*    } else if (s->class == MODULE) {	s->class = FUNC;	s->level = program->level;	r = s; */    } else {	r = s;    }    return r;}/* * Create a symbol for a text symbol with no source information. * We treat it as an assembly language function. */private Symbol deffunc (n)Name n;{    Symbol f;    f = insert(n);    f->language = findlanguage(".s");    f->class = FUNC;    f->type = t_int;    f->block = curblock;    f->level = program->level;    f->symvalue.funcv.src = false;    f->symvalue.funcv.inlne = false;    if (f->chain != nil) {	panic("chain not nil in deffunc");    }    return f;}/* * Create a symbol for a data or bss symbol with no source information. * We treat it as an assembly language variable. */private Symbol defvar (n)Name n;{    Symbol v;    v = insert(n);    v->language = findlanguage(".s");    v->storage = EXT;    v->class = VAR;    v->type = t_int;    v->level = program->level;    v->block = curblock;    return v;}/* * Update a symbol entry with a text address. */private updateTextSym (s, name, addr)Symbol s;char *name;Address addr;{    if (s->class == VAR) {	s->symvalue.offset = addr;    } else {	s->symvalue.funcv.beginaddr = addr;	if (name[0] == '_') {	    newfunc(s, codeloc(s));	    findbeginning(s);	}    }}/* * Avoid seeing Pascal labels as text symbols. */private boolean PascalLabel (n)Name n;{    boolean b;    register char *p;    b = false;    if (curlang == findlanguage(".p")) {	p = ident(n);	while (*p != '\0') {	    if (*p == '_' and *(p+1) == '$') {		b = true;		break;	    }	    ++p;	}    }    return b;}/* * 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;    char buf[4096];    boolean isextref;    integer count;    if (not streq(name, "_end")) {	if (name[0] == '_') {	    n = identname(&name[1], true);	} else {	    n = identname(name, true);	    if (lookup(n) != nil) {		sprintf(buf, "$%s", name);		n = identname(buf, false);	    }	}	if ((np->n_type&N_TYPE) == N_TEXT) {	    count = 0;	    t = findsym(n, &isextref);	    while (isextref) {		++count;		updateTextSym(t, name, np->n_value);		t = findsym(n, &isextref);	    }	    if (count == 0) {		if (t == nil) {		    if (not PascalLabel(n)) {			t = deffunc(n);			updateTextSym(t, name, np->n_value);			if (tracesyms) {			    printdecl(t);			}		    }		} else {		    if (t->class == MODULE) {			u = t;			t = deffunc(n);			t->block = u;			if (tracesyms) {			    printdecl(t);			}		    }		    updateTextSym(t, name, np->n_value);		}	    }	} else if ((np->n_type&N_TYPE) == N_BSS or (np->n_type&N_TYPE) == N_DATA) {	    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. * * If the external name has been referred to by several other symbols, * we must update each of them. */private check_var (np, n)struct nlist *np;register Name n;{    register Symbol t, u, next;    Symbol conflict;    t = lookup(n);    if (t == nil) {	t = defvar(n);	t->symvalue.offset = np->n_value;	if (tracesyms) {	    printdecl(t);	}    } else {	conflict = nil;	do {	    next = t->next_sym;	    if (t->name == n) {		if (t->class == MODULE and t->block == program) {		    conflict = t;		} else if (t->class == EXTREF and t->level == program->level) {		    u = t->symvalue.extref;		    while (u != nil and u->class == EXTREF) {			u = u->symvalue.extref;		    }		    u->symvalue.offset = np->n_value;		    delete(t);		} else if (t->level == program->level and		    (t->class == VAR or t->class == PROC or t->class == FUNC)		) {		    conflict = nil;		    t->symvalue.offset = np->n_value;		}	    }	    t = next;	} while (t != nil);	if (conflict != nil) {	    u = defvar(n);	    u->block = conflict;	    u->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->storage = EXT;	t->level = cur->level;	if ((np->n_type&N_TYPE) == N_TEXT) {	    t->class = FUNC;	    t->symvalue.funcv.src = false;	    t->symvalue.funcv.inlne = 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;    Name n;    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;	}	n = identname(&mname[i+1], true);	find(s, n) where s->block == program and s->class == MODULE endfind(s);	if (s == nil) {	    s = insert(n);	    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.inlne = 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, '.');    if (suffix > mname && *(suffix-1) == '.') {	/* special hack for C++ */	--suffix;    }    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 + -