1 /* Copyright (c) 1980 Regents of the University of California */ 2 3 #ifndef lint 4 static char sccsid[] = "@(#)stab.c 2.1 02/08/84"; 5 #endif 6 7 /* 8 * procedures to put out sdb symbol table information. 9 * and stabs for separate compilation type checking. 10 * these use the new .stabs, .stabn, and .stabd directives 11 */ 12 13 #include "whoami.h" 14 #ifdef PC 15 /* and the rest of the file */ 16 # include "0.h" 17 # include "objfmt.h" 18 # include "yy.h" 19 # include <stab.h> 20 21 /* 22 * additional symbol definition for <stab.h> 23 * that is used by the separate compilation facility -- 24 * eventually, <stab.h> should be updated to include this 25 */ 26 27 # include "pstab.h" 28 # include "pc.h" 29 30 /* 31 * absolute value: line numbers are negative if error recovery. 32 */ 33 #define ABS( x ) ( x < 0 ? -x : x ) 34 long checksum(); 35 36 /* 37 * global variables 38 */ 39 /*ARGSUSED*/ 40 stabgvar( name , type , offset , length , line ) 41 char *name; 42 int type; 43 int offset; 44 int length; 45 int line; 46 { 47 48 /* 49 * for separate compilation 50 */ 51 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 52 , (int) name , N_PC , N_PGVAR , ABS( line ) ); 53 /* 54 * for sdb 55 */ 56 if ( ! opt('g') ) { 57 return; 58 } 59 putprintf( " .stabs \"" , 1 ); 60 putprintf( NAMEFORMAT , 1 , (int) name ); 61 putprintf( "\",0x%x,0,0x%x,0" , 0 , N_GSYM , type ); 62 putprintf( " .stabs \"" , 1 ); 63 putprintf( NAMEFORMAT , 1 , (int) name ); 64 putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 65 } 66 67 /* 68 * local variables 69 */ 70 /*ARGSUSED*/ 71 stablvar( name , type , level , offset , length ) 72 char *name; 73 int type; 74 int level; 75 int offset; 76 int length; 77 { 78 79 if ( ! opt('g') ) { 80 return; 81 } 82 putprintf( " .stabs \"" , 1 ); 83 putprintf( NAMEFORMAT , 1 , (int) name ); 84 putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_LSYM , type , -offset ); 85 putprintf( " .stabs \"" , 1 ); 86 putprintf( NAMEFORMAT , 1 , (int) name ); 87 putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 88 } 89 90 91 /* 92 * parameters 93 */ 94 stabparam( name , type , offset , length ) 95 char *name; 96 int type; 97 int offset; 98 int length; 99 { 100 101 if ( ! opt('g') ) { 102 return; 103 } 104 putprintf( " .stabs \"" , 1 ); 105 putprintf( NAMEFORMAT , 1 , (int) name ); 106 putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_PSYM , type , offset ); 107 putprintf( " .stabs \"" , 1 ); 108 putprintf( NAMEFORMAT , 1 , (int) name ); 109 putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length ); 110 } 111 112 /* 113 * fields 114 */ 115 116 /* 117 * left brackets 118 */ 119 stablbrac( level ) 120 int level; 121 { 122 123 if ( ! opt('g') ) { 124 return; 125 } 126 putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_LBRAC , level ); 127 } 128 129 /* 130 * right brackets 131 */ 132 stabrbrac( level ) 133 int level; 134 { 135 136 if ( ! opt('g') ) { 137 return; 138 } 139 putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_RBRAC , level ); 140 } 141 142 /* 143 * functions 144 */ 145 stabfunc( name , typeclass , line , level ) 146 char *name; 147 int typeclass; 148 int line; 149 long level; 150 { 151 char extname[ BUFSIZ ]; 152 153 /* 154 * for separate compilation 155 */ 156 if ( level == 1 ) { 157 if ( typeclass == FUNC ) { 158 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 159 , (int) name , N_PC , N_PGFUNC , ABS( line ) ); 160 } else if ( typeclass == PROC ) { 161 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 162 , (int) name , N_PC , N_PGPROC , ABS( line ) ); 163 } 164 } 165 /* 166 * for sdb 167 */ 168 if ( ! opt('g') ) { 169 return; 170 } 171 putprintf( " .stabs \"" , 1 ); 172 putprintf( NAMEFORMAT , 1 , (int) name ); 173 sextname( extname , name , (int) level ); 174 putprintf( "\",0x%x,0,0x%x,%s" , 0 , N_FUN , line , (int) extname ); 175 } 176 177 /* 178 * source line numbers 179 */ 180 stabline( line ) 181 int line; 182 { 183 if ( ! opt('g') ) { 184 return; 185 } 186 putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_SLINE , ABS( line ) ); 187 } 188 189 /* 190 * source files 191 */ 192 stabsource(filename) 193 char *filename; 194 { 195 int label; 196 197 /* 198 * for separate compilation 199 */ 200 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, 201 (int) filename, N_PC, N_PSO, N_FLAGCHECKSUM); 202 /* 203 * for sdb 204 */ 205 if ( ! opt('g') ) { 206 return; 207 } 208 label = (int) getlab(); 209 putprintf( " .stabs \"" , 1 ); 210 putprintf( NAMEFORMAT , 1 , (int) filename ); 211 putprintf( "\",0x%x,0,0," , 1 , N_SO ); 212 putprintf( PREFIXFORMAT , 0 , (int) LLABELPREFIX , label ); 213 putprintf( PREFIXFORMAT , 1 , (int) LLABELPREFIX , label ); 214 putprintf( ":" , 0 ); 215 } 216 217 /* 218 * included files get one or more of these: 219 * one as they are entered by a #include, 220 * and one every time they are returned to from nested #includes. 221 */ 222 stabinclude(filename, firsttime) 223 char *filename; 224 bool firsttime; 225 { 226 int label; 227 long check; 228 229 /* 230 * for separate compilation 231 */ 232 if (firsttime) { 233 check = checksum(filename); 234 } else { 235 check = N_FLAGCHECKSUM; 236 } 237 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0, 238 (int) filename, N_PC, N_PSOL, check); 239 /* 240 * for sdb 241 */ 242 if ( ! opt('g') ) { 243 return; 244 } 245 label = (int) getlab(); 246 putprintf( NAMEFORMAT , 1 , (int) filename ); 247 putprintf( "\",0x%x,0,0," , 1 , N_SOL ); 248 putprintf( PREFIXFORMAT , 0 , (int) LLABELPREFIX , label ); 249 putprintf( PREFIXFORMAT , 1 , (int) LLABELPREFIX , label ); 250 putprintf( ":" , 0 ); 251 } 252 253 /* 254 * anyone know a good checksum for ascii files? 255 * this does a rotate-left and then exclusive-or's in the character. 256 * also, it avoids returning checksums of 0. 257 * The rotate is implemented by shifting and adding back the 258 * sign bit when negative. 259 */ 260 long 261 checksum(filename) 262 char *filename; 263 { 264 FILE *filep; 265 register int input; 266 register long check; 267 268 filep = fopen(filename, "r"); 269 if (filep == NULL) { 270 perror(filename); 271 pexit(DIED); 272 } 273 check = 0; 274 while ((input = getc(filep)) != EOF) { 275 if (check < 0) { 276 check <<= 1; 277 check += 1; 278 } else { 279 check <<= 1; 280 } 281 check ^= input; 282 } 283 (void) fclose(filep); 284 if ((unsigned) check <= N_FLAGCHECKSUM) { 285 return N_FLAGCHECKSUM + 1; 286 } else { 287 return check; 288 } 289 } 290 291 /* 292 * global Pascal symbols : 293 * labels, types, constants, and external procedure and function names: 294 * These are used by the separate compilation facility 295 * to be able to check for disjoint header files. 296 */ 297 298 /* 299 * global labels 300 */ 301 stabglabel( label , line ) 302 char *label; 303 int line; 304 { 305 306 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 307 , (int) label , N_PC , N_PGLABEL , ABS( line ) ); 308 } 309 310 /* 311 * global constants 312 */ 313 stabgconst( const , line ) 314 char *const; 315 int line; 316 { 317 318 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 319 , (int) const , N_PC , N_PGCONST , ABS( line ) ); 320 } 321 322 /* 323 * global types 324 */ 325 stabgtype( type , line ) 326 char *type; 327 int line; 328 { 329 330 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 331 , (int) type , N_PC , N_PGTYPE , ABS( line ) ); 332 } 333 334 335 /* 336 * external functions and procedures 337 */ 338 stabefunc( name , typeclass , line ) 339 char *name; 340 int typeclass; 341 int line; 342 { 343 int type; 344 345 if ( typeclass == FUNC ) { 346 type = N_PEFUNC; 347 } else if ( typeclass == PROC ) { 348 type = N_PEPROC; 349 } else { 350 return; 351 } 352 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0 353 , (int) name , N_PC , type , ABS( line ) ); 354 } 355 356 #endif PC 357