lint (by thien)
[unix-history] / usr / src / usr.bin / pascal / src / stab.c
/* Copyright (c) 1980 Regents of the University of California */
#ifndef lint
static char sccsid[] = "@(#)stab.c 1.8.1.1 %G%";
#endif
/*
* procedures to put out sdb symbol table information.
* and stabs for separate compilation type checking.
* these use the new .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"
/*
* absolute value: line numbers are negative if error recovery.
*/
#define ABS( x ) ( x < 0 ? -x : x )
/*
* global variables
*/
/*ARGSUSED*/
stabgvar( name , type , offset , length , line )
char *name;
int type;
int offset;
int length;
int line;
{
/*
* for separate compilation
*/
putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
, (int) name , N_PC , N_PGVAR , ABS( line ) );
/*
* for sdb
*/
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*/
stablvar( 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 );
}
/*
* parameters
*/
stabparam( 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
*/
stablbrac( level )
int level;
{
if ( ! opt('g') ) {
return;
}
putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_LBRAC , level );
}
/*
* right brackets
*/
stabrbrac( level )
int level;
{
if ( ! opt('g') ) {
return;
}
putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_RBRAC , level );
}
/*
* functions
*/
stabfunc( name , typeclass , line , level )
char *name;
int typeclass;
int line;
long level;
{
char extname[ BUFSIZ ];
/*
* for separate compilation
*/
if ( level == 1 ) {
if ( typeclass == FUNC ) {
putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
, (int) name , N_PC , N_PGFUNC , ABS( line ) );
} else if ( typeclass == PROC ) {
putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
, (int) name , N_PC , N_PGPROC , ABS( line ) );
}
}
/*
* 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
*/
stabsource(filename)
char *filename;
{
int label;
/*
* for separate compilation
*/
putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0,
filename, N_PC, N_PSO, N_FLAGCHECKSUM);
/*
* for sdb
*/
if ( ! opt('g') ) {
return;
}
label = 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 );
}
/*
* 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,
filename, N_PC, N_PSOL, check);
/*
* for sdb
*/
if ( ! opt('g') ) {
return;
}
label = 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.
*/
long
checksum(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;
}
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 )
char *label;
int line;
{
putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
, (int) label , N_PC , N_PGLABEL , ABS( line ) );
}
/*
* global constants
*/
stabgconst( const , line )
char *const;
int line;
{
putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
, (int) const , N_PC , N_PGCONST , ABS( line ) );
}
/*
* global types
*/
stabgtype( type , line )
char *type;
int line;
{
putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
, (int) type , N_PC , N_PGTYPE , ABS( line ) );
}
/*
* external functions and procedures
*/
stabefunc( name , typeclass , line )
char *name;
int typeclass;
int line;
{
int type;
if ( typeclass == FUNC ) {
type = N_PEFUNC;
} else if ( typeclass == PROC ) {
type = N_PEPROC;
} else {
return;
}
putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
, (int) name , N_PC , type , ABS( line ) );
}
#endif PC