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