1826Speter /* Copyright (c) 1980 Regents of the University of California */ 2772Speter 3*14128Speter static char sccsid[] = "@(#)stab.c 1.9 07/26/83"; 4826Speter 5772Speter /* 6826Speter * procedures to put out sdb symbol table information. 7826Speter * and stabs for separate compilation type checking. 8826Speter * these use the new .stabs, .stabn, and .stabd directives 9772Speter */ 10772Speter 11772Speter #include "whoami.h" 12772Speter #ifdef PC 13772Speter /* and the rest of the file */ 14772Speter # include "0.h" 1510649Speter # include "objfmt.h" 16*14128Speter # include "yy.h" 17772Speter # include <stab.h> 18772Speter 19842Speter /* 20842Speter * additional symbol definition for <stab.h> 21842Speter * that is used by the separate compilation facility -- 22842Speter * eventually, <stab.h> should be updated to include this 23842Speter */ 24772Speter 25842Speter # include "pstab.h" 26772Speter # include "pc.h" 27772Speter 28772Speter /* 29826Speter * absolute value: line numbers are negative if error recovery. 30826Speter */ 31826Speter #define ABS( x ) ( x < 0 ? -x : x ) 32826Speter 33826Speter /* 342164Speter * global variables 35772Speter */ 362164Speter stabgvar( name , type , offset , length , line ) 37772Speter char *name; 38772Speter int type; 39772Speter int offset; 40772Speter int length; 41826Speter int line; 42772Speter { 43772Speter 44826Speter /* 45826Speter * for separate compilation 46826Speter */ 472164Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 482164Speter , name , N_PC , N_PGVAR , ABS( line ) ); 49826Speter /* 50826Speter * for sdb 51826Speter */ 52772Speter if ( ! opt('g') ) { 53772Speter return; 54772Speter } 55772Speter putprintf( " .stabs \"" , 1 ); 56772Speter putprintf( NAMEFORMAT , 1 , name ); 572164Speter putprintf( "\",0x%x,0,0x%x,0" , 0 , N_GSYM , type ); 582164Speter putprintf( " .stabs \"" , 1 ); 592164Speter putprintf( NAMEFORMAT , 1 , name ); 602164Speter putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 612164Speter } 622164Speter 632164Speter /* 642164Speter * local variables 652164Speter */ 662164Speter stablvar( name , type , level , offset , length ) 672164Speter char *name; 682164Speter int type; 692164Speter int level; 702164Speter int offset; 712164Speter int length; 722164Speter { 732164Speter 742164Speter if ( ! opt('g') ) { 752164Speter return; 76772Speter } 77772Speter putprintf( " .stabs \"" , 1 ); 78772Speter putprintf( NAMEFORMAT , 1 , name ); 792164Speter putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_LSYM , type , -offset ); 802164Speter putprintf( " .stabs \"" , 1 ); 812164Speter putprintf( NAMEFORMAT , 1 , name ); 82826Speter putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 83772Speter } 84772Speter 85772Speter 86772Speter /* 87772Speter * parameters 88772Speter */ 89772Speter stabparam( name , type , offset , length ) 90772Speter char *name; 91772Speter int type; 92772Speter int offset; 93772Speter int length; 94772Speter { 95772Speter 96772Speter if ( ! opt('g') ) { 97772Speter return; 98772Speter } 99772Speter putprintf( " .stabs \"" , 1 ); 100772Speter putprintf( NAMEFORMAT , 1 , name ); 101826Speter putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_PSYM , type , offset ); 102772Speter putprintf( " .stabs \"" , 1 ); 103772Speter putprintf( NAMEFORMAT , 1 , name ); 104826Speter putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 105772Speter } 106772Speter 107772Speter /* 108772Speter * fields 109772Speter */ 110772Speter stabfield( name , type , offset , length ) 111772Speter char *name; 112772Speter int type; 113772Speter int offset; 114772Speter int length; 115772Speter { 116772Speter 117772Speter if ( ! opt('g') ) { 118772Speter return; 119772Speter } 120772Speter putprintf( " .stabs \"" , 1 ); 121772Speter putprintf( NAMEFORMAT , 1 , name ); 122826Speter putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_SSYM , type , offset ); 123772Speter putprintf( " .stabs \"" , 1 ); 124772Speter putprintf( NAMEFORMAT , 1 , name ); 125826Speter putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 126772Speter } 127772Speter 128772Speter /* 129772Speter * left brackets 130772Speter */ 131772Speter stablbrac( level ) 132772Speter int level; 133772Speter { 134772Speter 135772Speter if ( ! opt('g') ) { 136772Speter return; 137772Speter } 138826Speter putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_LBRAC , level ); 139772Speter } 140772Speter 141772Speter /* 142772Speter * right brackets 143772Speter */ 144772Speter stabrbrac( level ) 145772Speter int level; 146772Speter { 147772Speter 148772Speter if ( ! opt('g') ) { 149772Speter return; 150772Speter } 151826Speter putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_RBRAC , level ); 152772Speter } 153772Speter 154772Speter /* 155772Speter * functions 156772Speter */ 1577925Smckusick stabfunc( name , typeclass , line , level ) 158772Speter char *name; 1597925Smckusick int typeclass; 160772Speter int line; 161772Speter long level; 162772Speter { 163826Speter int type; 164826Speter long i; 1653365Speter char extname[ BUFSIZ ]; 166772Speter 167826Speter /* 168826Speter * for separate compilation 169826Speter */ 170826Speter if ( level == 1 ) { 1717925Smckusick if ( typeclass == FUNC ) { 172842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 173842Speter , name , N_PC , N_PGFUNC , ABS( line ) ); 1747925Smckusick } else if ( typeclass == PROC ) { 175842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 176842Speter , name , N_PC , N_PGPROC , ABS( line ) ); 177826Speter } 178772Speter } 179826Speter /* 180826Speter * for sdb 181826Speter */ 182772Speter if ( ! opt('g') ) { 183772Speter return; 184772Speter } 185772Speter putprintf( " .stabs \"" , 1 ); 186772Speter putprintf( NAMEFORMAT , 1 , name ); 1873365Speter sextname( extname , name , level ); 1883365Speter putprintf( "\",0x%x,0,0x%x,%s" , 0 , N_FUN , line , extname ); 189772Speter } 190772Speter 191772Speter /* 192772Speter * source line numbers 193772Speter */ 194772Speter stabline( line ) 195772Speter int line; 196772Speter { 197772Speter if ( ! opt('g') ) { 198772Speter return; 199772Speter } 200826Speter putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_SLINE , ABS( line ) ); 201772Speter } 202772Speter 203772Speter /* 204772Speter * source files 205772Speter */ 206*14128Speter stabsource(filename) 207772Speter char *filename; 208*14128Speter { 209*14128Speter int label; 210*14128Speter 211*14128Speter /* 212*14128Speter * for separate compilation 213*14128Speter */ 214*14128Speter putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, 215*14128Speter filename, N_PC, N_PSO, N_FLAGCHECKSUM); 216*14128Speter /* 217*14128Speter * for sdb 218*14128Speter */ 219*14128Speter if ( ! opt('g') ) { 220*14128Speter return; 221772Speter } 222*14128Speter label = getlab(); 223*14128Speter putprintf( " .stabs \"" , 1 ); 224*14128Speter putprintf( NAMEFORMAT , 1 , filename ); 225*14128Speter putprintf( "\",0x%x,0,0," , 1 , N_SO ); 226*14128Speter putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label ); 227*14128Speter putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label ); 228*14128Speter putprintf( ":" , 0 ); 229*14128Speter } 230772Speter 231772Speter /* 232772Speter * included files get one or more of these: 233772Speter * one as they are entered by a #include, 234*14128Speter * and one every time they are returned to from nested #includes. 235772Speter */ 236*14128Speter stabinclude(filename, firsttime) 237772Speter char *filename; 238*14128Speter bool firsttime; 239*14128Speter { 240*14128Speter int label; 241*14128Speter long check; 242*14128Speter 243*14128Speter /* 244*14128Speter * for separate compilation 245*14128Speter */ 246*14128Speter if (firsttime) { 247*14128Speter check = checksum(filename); 248*14128Speter } else { 249*14128Speter check = N_FLAGCHECKSUM; 250*14128Speter } 251*14128Speter putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, 252*14128Speter filename, N_PC, N_PSOL, check); 253*14128Speter /* 254*14128Speter * for sdb 255*14128Speter */ 256*14128Speter if ( ! opt('g') ) { 257*14128Speter return; 258*14128Speter } 259*14128Speter label = getlab(); 260*14128Speter putprintf( " .stabs \"" , 1 ); 261*14128Speter putprintf( NAMEFORMAT , 1 , filename ); 262*14128Speter putprintf( "\",0x%x,0,0," , 1 , N_SOL ); 263*14128Speter putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label ); 264*14128Speter putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label ); 265*14128Speter putprintf( ":" , 0 ); 266*14128Speter } 267*14128Speter 268*14128Speter /* 269*14128Speter * anyone know a good checksum for ascii files? 270*14128Speter * this does a rotate-left and then exclusive-or's in the character. 271*14128Speter * also, it avoids returning checksums of 0. 272*14128Speter * The rotate is implemented by shifting and adding back the 273*14128Speter * sign bit when negative. 274*14128Speter */ 275*14128Speter long 276*14128Speter checksum(filename) 277*14128Speter char *filename; 278*14128Speter { 279*14128Speter FILE *filep; 280*14128Speter register int input; 281*14128Speter register long check; 282*14128Speter 283*14128Speter filep = fopen(filename, "r"); 284*14128Speter if (filep == NULL) { 285*14128Speter perror(filename); 286*14128Speter pexit(DIED); 287*14128Speter } 288*14128Speter check = 0; 289*14128Speter while ((input = getc(filep)) != EOF) { 290*14128Speter if (check < 0) { 291*14128Speter check <<= 1; 292*14128Speter check += 1; 293*14128Speter } else { 294*14128Speter check <<= 1; 295772Speter } 296*14128Speter check ^= input; 297772Speter } 298*14128Speter fclose(filep); 299*14128Speter if ((unsigned) check <= N_FLAGCHECKSUM) { 300*14128Speter return N_FLAGCHECKSUM + 1; 301*14128Speter } else { 302*14128Speter return check; 303*14128Speter } 304*14128Speter } 305772Speter 306772Speter /* 307772Speter * global Pascal symbols : 308772Speter * labels, types, constants, and external procedure and function names: 309772Speter * These are used by the separate compilation facility 310772Speter * to be able to check for disjoint header files. 311772Speter */ 312772Speter 313826Speter /* 314826Speter * global labels 315826Speter */ 316842Speter stabglabel( label , line ) 317826Speter char *label; 318826Speter int line; 319772Speter { 320772Speter 321842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 322842Speter , label , N_PC , N_PGLABEL , ABS( line ) ); 323772Speter } 324772Speter 325826Speter /* 326826Speter * global constants 327826Speter */ 328842Speter stabgconst( const , line ) 329842Speter char *const; 330826Speter int line; 331772Speter { 332772Speter 333842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 334842Speter , const , N_PC , N_PGCONST , ABS( line ) ); 335772Speter } 336772Speter 337826Speter /* 338826Speter * global types 339826Speter */ 340842Speter stabgtype( type , line ) 341842Speter char *type; 342826Speter int line; 343772Speter { 344772Speter 345842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 346842Speter , type , N_PC , N_PGTYPE , ABS( line ) ); 347772Speter } 348772Speter 349772Speter 350826Speter /* 351826Speter * external functions and procedures 352826Speter */ 3537925Smckusick stabefunc( name , typeclass , line ) 354826Speter char *name; 3557925Smckusick int typeclass; 356826Speter int line; 357772Speter { 358826Speter int type; 359772Speter 3607925Smckusick if ( typeclass == FUNC ) { 361842Speter type = N_PEFUNC; 3627925Smckusick } else if ( typeclass == PROC ) { 363842Speter type = N_PEPROC; 364826Speter } else { 365826Speter return; 366772Speter } 367842Speter putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 368842Speter , name , N_PC , type , ABS( line ) ); 369772Speter } 370772Speter 371772Speter #endif PC 372