📄 stab.c
字号:
/*- * Copyright (c) 1980, 1993 * 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[] = "@(#)stab.c 8.1 (Berkeley) 6/6/93";#endif /* not lint */ /* * Procedures to put out symbol table information * and stabs for separate compilation type checking. * These use the .stabs, .stabn, and .stabd directives. */#include "whoami.h"#ifdef PC /* and the rest of the file */# include "0.h"# include "objfmt.h"# include "yy.h"# include <stab.h> /* * additional symbol definition for <stab.h> * that is used by the separate compilation facility -- * eventually, <stab.h> should be updated to include this */# include "pstab.h"# include "pc.h"#define private staticint oldway = 0; /* * absolute value: line numbers are negative if error recovery. */#define ABS( x ) ( x < 0 ? -x : x )long checksum();/* * Generate information about variables. */stabgvar (p, length, line)struct nl *p;int length, line;{ putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, p->symbol, N_PC, N_PGVAR, ABS(line) ); if (oldway != 0) { oldstabgvar(p->symbol, p2type(p->type), 0, length, line); } else if (opt('g')) { putprintf("\t.stabs\t\"%s:G", 1, p->symbol); gentype(p->type); putprintf("\",0x%x,0,0x%x,0", 0, N_GSYM, length); }}stablvar (p, offset, length)struct nl *p;int offset, length;{ int level; level = (p->nl_block & 037); if (oldway != 0) { oldstablvar(p->symbol, p2type(p->type), level, offset, length); } else if (opt('g')) { putprintf("\t.stabs\t\"%s:", 1, p->symbol); gentype(p->type); putprintf("\",0x%x,0,0x%x,0x%x", 0, N_LSYM, length, offset); }} /* * global variables *//*ARGSUSED*/oldstabgvar( name , type , offset , length , line ) char *name; int type; int offset; int length; int line; { if ( ! opt('g') ) { return; } putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , (int) name ); putprintf( "\",0x%x,0,0x%x,0" , 0 , N_GSYM , type ); putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , (int) name ); putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );} /* * local variables *//*ARGSUSED*/oldstablvar( name , type , level , offset , length ) char *name; int type; int level; int offset; int length; { if ( ! opt('g') ) { return; } putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , (int) name ); putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_LSYM , type , -offset ); putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , (int) name ); putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );}stabparam (p, offset, length)struct nl *p;int offset, length;{ if (oldway != 0) { oldstabparam(p->symbol, p2type(p->type), offset, length); } else if (opt('g')) { putprintf("\t.stabs\t\"%s:", 1, p->symbol); if (p->class == REF) { putprintf("v", 1); } else { putprintf("p", 1); } gentype((p->class == FPROC || p->class ==FFUNC) ? p : p->type); putprintf("\",0x%x,0,0x%x,0x%x", 0, N_PSYM, length, offset); }} /* * parameters */oldstabparam( name , type , offset , length ) char *name; int type; int offset; int length; { if ( ! opt('g') ) { return; } putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , (int) name ); putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_PSYM , type , offset ); putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , (int) name ); putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); } /* * fields */ /* * left brackets * (dbx handles module-2 without these, so we won't use them either) */stablbrac( level ) int level; { if ( ! opt('g') || oldway == 0 ) { return; } putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_LBRAC , level ); } /* * right brackets */stabrbrac( level ) int level; { if ( ! opt('g') || oldway == 0 ) { return; } putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_RBRAC , level ); }stabfunc (p, name, line, level)struct nl *p;char *name;int line, level;{ char extname[BUFSIZ],nestspec[BUFSIZ]; if ( level == 1 ) { if (p->class == FUNC) { putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 , name , N_PC , N_PGFUNC , ABS( line ) ); } else if (p->class == PROC) { putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 , name , N_PC , N_PGPROC , ABS( line ) ); } } if (oldway != 0) { oldstabfunc(name, p->class, line, level); } else if (opt('g')) { putprintf("\t.stabs\t\"%s:", 1, name); if (p->class == FUNC) { putprintf("F", 1); gentype(p->type); putprintf(",", 1); } else { putprintf("P,", 1); } sextname(extname, name, level); /* set extname to entry label */ putprintf("%s,", 1, &(extname[1])); /* remove initial underbar */ snestspec(nestspec, level); putprintf("%s\",0x%x,0,0,%s", 0, nestspec, N_FUN, extname); }} /* * construct the colon-separated static nesting string into a * caller-supplied buffer */private snestspec(buffer, level) char buffer[]; int level;{ char *starthere; int i; if (level <= 1) { buffer[0] = '\0'; } else { starthere = &buffer[0]; for ( i = 1 ; i < level ; i++ ) { sprintf(starthere, "%s:", enclosing[i]); starthere += strlen(enclosing[i]) + 1; } *--starthere = '\0'; /* remove last colon */ if (starthere >= &buffer[BUFSIZ-1]) { panic("snestspec"); } }} /* * functions */oldstabfunc( name , typeclass , line , level ) char *name; int typeclass; int line; long level; { char extname[ BUFSIZ ]; /* * for sdb */ if ( ! opt('g') ) { return; } putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , (int) name ); sextname( extname , name , (int) level ); putprintf( "\",0x%x,0,0x%x,%s" , 0 , N_FUN , line , (int) extname ); } /* * source line numbers */stabline( line ) int line; { if ( ! opt('g') ) { return; } putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_SLINE , ABS( line ) ); } /* * source files get none or more of these: * one as they are entered, * and one every time they are returned to from nested #includes */stabsource(filename, firsttime) char *filename; bool firsttime;{ int label; /* * for separate compilation */ putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, (int) filename, N_PC, N_PSO, N_FLAGCHECKSUM); /* * for debugger */ if ( ! opt('g') ) { return; } if (oldway != 0) { label = (int) getlab(); putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , filename ); putprintf( "\",0x%x,0,0," , 1 , N_SO ); putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label ); putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label ); putprintf( ":" , 0 ); } else { if (firsttime) { putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , filename ); putprintf( "\",0x%x,0,0,0" , 0 , N_SO ); } }} /* * included files get one or more of these: * one as they are entered by a #include, * and one every time they are returned to from nested #includes. */stabinclude(filename, firsttime) char *filename; bool firsttime;{ int label; long check; /* * for separate compilation */ if (firsttime) { check = checksum(filename); } else { check = N_FLAGCHECKSUM; } putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, (int) filename, N_PC, N_PSOL, check); /* * for sdb */ if ( ! opt('g') ) { return; } if (oldway != 0) { label = (int) getlab(); putprintf( " .stabs \"" , 1 ); putprintf( NAMEFORMAT , 1 , filename ); putprintf( "\",0x%x,0,0," , 1 , N_SOL ); putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label ); putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label ); putprintf( ":" , 0 ); }} /* * anyone know a good checksum for ascii files? * this does a rotate-left and then exclusive-or's in the character. * also, it avoids returning checksums of 0. * The rotate is implemented by shifting and adding back the * sign bit when negative. */longchecksum(filename) char *filename;{ FILE *filep; register int input; register long check; filep = fopen(filename, "r"); if (filep == NULL) { perror(filename); pexit(DIED); } check = 0; while ((input = getc(filep)) != EOF) { if (check < 0) { check <<= 1; check += 1; } else { check <<= 1; } check ^= input; } (void) fclose(filep); if ((unsigned) check <= N_FLAGCHECKSUM) { return N_FLAGCHECKSUM + 1; } else { return check; }}/* * global Pascal symbols : * labels, types, constants, and external procedure and function names: * These are used by the separate compilation facility * to be able to check for disjoint header files. */ /* * global labels */stabglabel( label , line )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -