1826Speter /* Copyright (c) 1980 Regents of the University of California */ 2772Speter 315942Smckusick #ifndef lint 4*15952Smckusick static char sccsid[] = "@(#)stab.c 1.10 02/06/84"; 515942Smckusick #endif 6826Speter 7772Speter /* 8826Speter * procedures to put out sdb symbol table information. 9826Speter * and stabs for separate compilation type checking. 10826Speter * these use the new .stabs, .stabn, and .stabd directives 11772Speter */ 12772Speter 13772Speter #include "whoami.h" 14772Speter #ifdef PC 15772Speter /* and the rest of the file */ 16772Speter # include "0.h" 1710649Speter # include "objfmt.h" 18*15952Smckusick # include "yy.h" 19772Speter # include <stab.h> 20772Speter 21842Speter /* 22842Speter * additional symbol definition for <stab.h> 23842Speter * that is used by the separate compilation facility -- 24842Speter * eventually, <stab.h> should be updated to include this 25842Speter */ 26772Speter 27842Speter # include "pstab.h" 28772Speter # include "pc.h" 29772Speter 30772Speter /* 31826Speter * absolute value: line numbers are negative if error recovery. 32826Speter */ 33826Speter #define ABS( x ) ( x < 0 ? -x : x ) 34826Speter 35826Speter /* 362164Speter * global variables 37772Speter */ 3815942Smckusick /*ARGSUSED*/ 392164Speter stabgvar( name , type , offset , length , line ) 40772Speter char *name; 41772Speter int type; 42772Speter int offset; 43772Speter int length; 44826Speter int line; 45772Speter { 46772Speter 47826Speter /* 48826Speter * for separate compilation 49826Speter */ 502164Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 5115942Smckusick , (int) name , N_PC , N_PGVAR , ABS( line ) ); 52826Speter /* 53826Speter * for sdb 54826Speter */ 55772Speter if ( ! opt('g') ) { 56772Speter return; 57772Speter } 58772Speter putprintf( " .stabs \"" , 1 ); 5915942Smckusick putprintf( NAMEFORMAT , 1 , (int) name ); 602164Speter putprintf( "\",0x%x,0,0x%x,0" , 0 , N_GSYM , type ); 612164Speter putprintf( " .stabs \"" , 1 ); 6215942Smckusick putprintf( NAMEFORMAT , 1 , (int) name ); 632164Speter putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 642164Speter } 652164Speter 662164Speter /* 672164Speter * local variables 682164Speter */ 6915942Smckusick /*ARGSUSED*/ 702164Speter stablvar( name , type , level , offset , length ) 712164Speter char *name; 722164Speter int type; 732164Speter int level; 742164Speter int offset; 752164Speter int length; 762164Speter { 772164Speter 782164Speter if ( ! opt('g') ) { 792164Speter return; 80772Speter } 81772Speter putprintf( " .stabs \"" , 1 ); 8215942Smckusick putprintf( NAMEFORMAT , 1 , (int) name ); 832164Speter putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_LSYM , type , -offset ); 842164Speter putprintf( " .stabs \"" , 1 ); 8515942Smckusick putprintf( NAMEFORMAT , 1 , (int) name ); 86826Speter putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 87772Speter } 88772Speter 89772Speter 90772Speter /* 91772Speter * parameters 92772Speter */ 93772Speter stabparam( name , type , offset , length ) 94772Speter char *name; 95772Speter int type; 96772Speter int offset; 97772Speter int length; 98772Speter { 99772Speter 100772Speter if ( ! opt('g') ) { 101772Speter return; 102772Speter } 103772Speter putprintf( " .stabs \"" , 1 ); 10415942Smckusick putprintf( NAMEFORMAT , 1 , (int) name ); 105826Speter putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_PSYM , type , offset ); 106772Speter putprintf( " .stabs \"" , 1 ); 10715942Smckusick putprintf( NAMEFORMAT , 1 , (int) name ); 108826Speter putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 109772Speter } 110772Speter 111772Speter /* 112772Speter * fields 113772Speter */ 114772Speter 115772Speter /* 116772Speter * left brackets 117772Speter */ 118772Speter stablbrac( level ) 119772Speter int level; 120772Speter { 121772Speter 122772Speter if ( ! opt('g') ) { 123772Speter return; 124772Speter } 125826Speter putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_LBRAC , level ); 126772Speter } 127772Speter 128772Speter /* 129772Speter * right brackets 130772Speter */ 131772Speter stabrbrac( level ) 132772Speter int level; 133772Speter { 134772Speter 135772Speter if ( ! opt('g') ) { 136772Speter return; 137772Speter } 138826Speter putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_RBRAC , level ); 139772Speter } 140772Speter 141772Speter /* 142772Speter * functions 143772Speter */ 1447925Smckusick stabfunc( name , typeclass , line , level ) 145772Speter char *name; 1467925Smckusick int typeclass; 147772Speter int line; 148772Speter long level; 149772Speter { 1503365Speter char extname[ BUFSIZ ]; 151772Speter 152826Speter /* 153826Speter * for separate compilation 154826Speter */ 155826Speter if ( level == 1 ) { 1567925Smckusick if ( typeclass == FUNC ) { 157842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 15815942Smckusick , (int) name , N_PC , N_PGFUNC , ABS( line ) ); 1597925Smckusick } else if ( typeclass == PROC ) { 160842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 16115942Smckusick , (int) name , N_PC , N_PGPROC , ABS( line ) ); 162826Speter } 163772Speter } 164826Speter /* 165826Speter * for sdb 166826Speter */ 167772Speter if ( ! opt('g') ) { 168772Speter return; 169772Speter } 170772Speter putprintf( " .stabs \"" , 1 ); 17115942Smckusick putprintf( NAMEFORMAT , 1 , (int) name ); 17215942Smckusick sextname( extname , name , (int) level ); 17315942Smckusick putprintf( "\",0x%x,0,0x%x,%s" , 0 , N_FUN , line , (int) extname ); 174772Speter } 175772Speter 176772Speter /* 177772Speter * source line numbers 178772Speter */ 179772Speter stabline( line ) 180772Speter int line; 181772Speter { 182772Speter if ( ! opt('g') ) { 183772Speter return; 184772Speter } 185826Speter putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_SLINE , ABS( line ) ); 186772Speter } 187772Speter 188772Speter /* 189772Speter * source files 190772Speter */ 191*15952Smckusick stabsource(filename) 192772Speter char *filename; 193*15952Smckusick { 194*15952Smckusick int label; 195*15952Smckusick 196*15952Smckusick /* 197*15952Smckusick * for separate compilation 198*15952Smckusick */ 199*15952Smckusick putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, 200*15952Smckusick (int) filename, N_PC, N_PSO, N_FLAGCHECKSUM); 201*15952Smckusick /* 202*15952Smckusick * for sdb 203*15952Smckusick */ 204*15952Smckusick if ( ! opt('g') ) { 205*15952Smckusick return; 206772Speter } 207*15952Smckusick label = (int) getlab(); 208*15952Smckusick putprintf( " .stabs \"" , 1 ); 209*15952Smckusick putprintf( NAMEFORMAT , 1 , (int) filename ); 210*15952Smckusick putprintf( "\",0x%x,0,0," , 1 , N_SO ); 211*15952Smckusick putprintf( PREFIXFORMAT , 0 , (int) LLABELPREFIX , label ); 212*15952Smckusick putprintf( PREFIXFORMAT , 1 , (int) LLABELPREFIX , label ); 213*15952Smckusick putprintf( ":" , 0 ); 214*15952Smckusick } 215772Speter 216772Speter /* 217772Speter * included files get one or more of these: 218772Speter * one as they are entered by a #include, 219*15952Smckusick * and one every time they are returned to from nested #includes. 220772Speter */ 221*15952Smckusick stabinclude(filename, firsttime) 222772Speter char *filename; 223*15952Smckusick bool firsttime; 224*15952Smckusick { 225*15952Smckusick int label; 226*15952Smckusick long check; 227*15952Smckusick 228*15952Smckusick /* 229*15952Smckusick * for separate compilation 230*15952Smckusick */ 231*15952Smckusick if (firsttime) { 232*15952Smckusick check = checksum(filename); 233*15952Smckusick } else { 234*15952Smckusick check = N_FLAGCHECKSUM; 235*15952Smckusick } 236*15952Smckusick putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, 237*15952Smckusick (int) filename, N_PC, N_PSOL, check); 238*15952Smckusick /* 239*15952Smckusick * for sdb 240*15952Smckusick */ 241*15952Smckusick if ( ! opt('g') ) { 242*15952Smckusick return; 243*15952Smckusick } 244*15952Smckusick label = (int) getlab(); 245*15952Smckusick putprintf( NAMEFORMAT , 1 , (int) filename ); 246*15952Smckusick putprintf( "\",0x%x,0,0," , 1 , N_SOL ); 247*15952Smckusick putprintf( PREFIXFORMAT , 0 , (int) LLABELPREFIX , label ); 248*15952Smckusick putprintf( PREFIXFORMAT , 1 , (int) LLABELPREFIX , label ); 249*15952Smckusick putprintf( ":" , 0 ); 250*15952Smckusick } 251*15952Smckusick 252*15952Smckusick /* 253*15952Smckusick * anyone know a good checksum for ascii files? 254*15952Smckusick * this does a rotate-left and then exclusive-or's in the character. 255*15952Smckusick * also, it avoids returning checksums of 0. 256*15952Smckusick * The rotate is implemented by shifting and adding back the 257*15952Smckusick * sign bit when negative. 258*15952Smckusick */ 259*15952Smckusick long 260*15952Smckusick checksum(filename) 261*15952Smckusick char *filename; 262*15952Smckusick { 263*15952Smckusick FILE *filep; 264*15952Smckusick register int input; 265*15952Smckusick register long check; 266*15952Smckusick 267*15952Smckusick filep = fopen(filename, "r"); 268*15952Smckusick if (filep == NULL) { 269*15952Smckusick perror(filename); 270*15952Smckusick pexit(DIED); 271*15952Smckusick } 272*15952Smckusick check = 0; 273*15952Smckusick while ((input = getc(filep)) != EOF) { 274*15952Smckusick if (check < 0) { 275*15952Smckusick check <<= 1; 276*15952Smckusick check += 1; 277*15952Smckusick } else { 278*15952Smckusick check <<= 1; 27915942Smckusick } 280*15952Smckusick check ^= input; 28114128Speter } 282*15952Smckusick fclose(filep); 283*15952Smckusick if ((unsigned) check <= N_FLAGCHECKSUM) { 284*15952Smckusick return N_FLAGCHECKSUM + 1; 285*15952Smckusick } else { 286*15952Smckusick return check; 287*15952Smckusick } 288*15952Smckusick } 28914128Speter 290772Speter /* 291772Speter * global Pascal symbols : 292772Speter * labels, types, constants, and external procedure and function names: 293772Speter * These are used by the separate compilation facility 294772Speter * to be able to check for disjoint header files. 295772Speter */ 296772Speter 297826Speter /* 298826Speter * global labels 299826Speter */ 300842Speter stabglabel( label , line ) 301826Speter char *label; 302826Speter int line; 303772Speter { 304772Speter 305842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 30615942Smckusick , (int) label , N_PC , N_PGLABEL , ABS( line ) ); 307772Speter } 308772Speter 309826Speter /* 310826Speter * global constants 311826Speter */ 312842Speter stabgconst( const , line ) 313842Speter char *const; 314826Speter int line; 315772Speter { 316772Speter 317842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 31815942Smckusick , (int) const , N_PC , N_PGCONST , ABS( line ) ); 319772Speter } 320772Speter 321826Speter /* 322826Speter * global types 323826Speter */ 324842Speter stabgtype( type , line ) 325842Speter char *type; 326826Speter int line; 327772Speter { 328772Speter 329842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 33015942Smckusick , (int) type , N_PC , N_PGTYPE , ABS( line ) ); 331772Speter } 332772Speter 333772Speter 334826Speter /* 335826Speter * external functions and procedures 336826Speter */ 3377925Smckusick stabefunc( name , typeclass , line ) 338826Speter char *name; 3397925Smckusick int typeclass; 340826Speter int line; 341772Speter { 342826Speter int type; 343772Speter 3447925Smckusick if ( typeclass == FUNC ) { 345842Speter type = N_PEFUNC; 3467925Smckusick } else if ( typeclass == PROC ) { 347842Speter type = N_PEPROC; 348826Speter } else { 349826Speter return; 350772Speter } 351842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 35215942Smckusick , (int) name , N_PC , type , ABS( line ) ); 353772Speter } 354772Speter 355772Speter #endif PC 356