1 /* 2 * Symbolic debugging info interface. 3 * 4 * Here we generate pseudo-ops that cause the assembler to put 5 * symbolic debugging information into the object file. 6 */ 7 8 static char *sccsid ="@(#)stab.c 1.3 (Berkeley) 12/24/82"; 9 10 #include "mfile1" 11 12 #include <sys/types.h> 13 #include <a.out.h> 14 #include <stab.h> 15 16 #define private static 17 #define and && 18 #define or || 19 #define not ! 20 #define div / 21 #define mod % 22 #define nil 0 23 24 #define bytes(bits) ((bits) / SZCHAR) 25 #define bsize(p) bytes(dimtab[p->sizoff]) /* size in bytes of a symbol */ 26 27 #define NILINDEX -1 28 #define FORWARD -2 29 30 typedef enum { false, true } Boolean; 31 32 extern int ddebug; 33 extern int gdebug; 34 extern char *malloc(); 35 36 int stabLCSYM; 37 38 /* 39 * Flag for producing either sdb or dbx symbol information. 40 */ 41 int oldway = false; 42 43 /* 44 * Generate debugging info for a parameter. 45 * The offset isn't known when it is first entered into the symbol table 46 * since the types are read later. 47 */ 48 49 fixarg(p) 50 struct symtab *p; 51 { 52 if (oldway) { 53 old_fixarg(p); 54 } else if (gdebug) { 55 printf("\t.stabs\t\"%s:p", p->sname); 56 gentype(p); 57 printf("\",0x%x,0,%d,%d\n", N_PSYM, bsize(p), bytes(argoff)); 58 } 59 } 60 61 /* 62 * Generate debugging info for a given symbol. 63 */ 64 65 outstab(sym) 66 struct symtab *sym; 67 { 68 register struct symtab *p; 69 char *classname; 70 int offset; 71 Boolean ignore; 72 static Boolean firsttime = true; 73 74 if (oldway) { 75 old_outstab(sym); 76 } else if (gdebug) { 77 if (firsttime) { 78 firsttime = false; 79 inittypes(); 80 } 81 ignore = false; 82 p = sym; 83 offset = bytes(p->offset); 84 switch (p->sclass) { 85 case REGISTER: 86 classname = "r"; 87 offset = p->offset; 88 break; 89 90 /* 91 * Locals are the default class. 92 */ 93 case AUTO: 94 classname = ""; 95 break; 96 97 case STATIC: 98 if (ISFTN(p->stype)) { 99 ignore = true; 100 } else if (p->slevel <= 1) { 101 classname = "S"; 102 } else { 103 classname = "V"; 104 } 105 break; 106 107 case EXTDEF: 108 case EXTERN: 109 if (ISFTN(p->stype)) { 110 ignore = true; 111 } else { 112 classname = "G"; 113 } 114 break; 115 116 case TYPEDEF: 117 classname = "t"; 118 break; 119 120 case PARAM: 121 case MOS: 122 case MOU: 123 case MOE: 124 ignore = true; 125 break; 126 127 case ENAME: 128 case UNAME: 129 case STNAME: 130 entertype(p->stype, NILINDEX, FORWARD, dimtab[p->sizoff + 3]); 131 ignore = true; 132 break; 133 134 default: 135 if ((p->sclass&FIELD) == 0) { 136 printf("/* no info for %s (%d) */\n", p->sname, p->sclass); 137 } 138 ignore = true; 139 break; 140 } 141 if (not ignore) { 142 printf("\t.stabs\t\"%s:%s", p->sname, classname); 143 gentype(p); 144 geninfo(p); 145 } 146 } 147 } 148 149 /* 150 * Since type names are lost in the travels and because C has 151 * structural type equivalence we keep a table of type words that 152 * we've already seen. The first time we see a type, it is assigned 153 * (inline) a number and future references just list that number. 154 * Structures, unions, enums, and arrays must be handled carefully 155 * since not all the necessary information is in the type word. 156 */ 157 158 typedef struct Typeid *Typeid; 159 160 struct Typeid { 161 TWORD tword; 162 int tarray; 163 int tstruct; 164 int tstrtag; 165 int tnum; 166 Typeid chain; 167 }; 168 169 #define TABLESIZE 2003 170 171 private int tcount = 1; 172 private int t_int, t_char; 173 private Typeid typetable[TABLESIZE]; 174 175 /* 176 * Look for the given type word in the type table. 177 */ 178 179 private Typeid typelookup(type, arrindex, strindex, strtag) 180 TWORD type; 181 int arrindex; 182 int strindex; 183 int strtag; 184 { 185 register TWORD tword; 186 register int i1, i2; 187 Typeid t; 188 189 t = typetable[type mod TABLESIZE]; 190 while (t != nil) { 191 if (t->tword == type and 192 strindex == t->tstruct and strtag == t->tstrtag) { 193 if (arrindex == NILINDEX) { 194 break; 195 } else { 196 tword = type >> TSHIFT; 197 i1 = arrindex; 198 i2 = t->tarray; 199 while (ISARY(tword) and dimtab[i1] == dimtab[i2]) { 200 ++i1; 201 ++i2; 202 tword >>= TSHIFT; 203 } 204 if (!ISARY(tword)) { 205 break; 206 } 207 } 208 } 209 t = t->chain; 210 } 211 return t; 212 } 213 214 /* 215 * Enter a type word and associated symtab indices into the type table. 216 */ 217 218 private int entertype(type, arrindex, strindex, strtag) 219 TWORD type; 220 int arrindex; 221 int strindex; 222 int strtag; 223 { 224 register Typeid t; 225 register int i; 226 227 t = (Typeid) malloc(sizeof(struct Typeid)); 228 t->tword = type; 229 t->tarray = arrindex; 230 t->tstruct = strindex; 231 t->tstrtag = strtag; 232 t->tnum = tcount; 233 ++tcount; 234 i = type mod TABLESIZE; 235 t->chain = typetable[i]; 236 typetable[i] = t; 237 return t->tnum; 238 } 239 240 /* 241 * Change the information associated with a type table entry. 242 * Since I'm lazy this just creates a new entry with the number 243 * as the old one. 244 */ 245 246 private reentertype(typeid, type, arrindex, strindex, strtag) 247 Typeid typeid; 248 TWORD type; 249 int arrindex; 250 int strindex; 251 int strtag; 252 { 253 register Typeid t; 254 register int i; 255 256 t = (Typeid) malloc(sizeof(struct Typeid)); 257 t->tword = type; 258 t->tarray = arrindex; 259 t->tstruct = strindex; 260 t->tstrtag = strtag; 261 t->tnum = typeid->tnum; 262 i = type mod TABLESIZE; 263 t->chain = typetable[i]; 264 typetable[i] = t; 265 } 266 267 /* 268 * Initialize type table with predefined types. 269 */ 270 271 #define builtintype(type) entertype(type, NILINDEX, NILINDEX, NILINDEX) 272 273 private inittypes() 274 { 275 int t; 276 277 t_int = builtintype(INT); 278 t_char = builtintype(CHAR); 279 maketype("int", t_int, t_int, 0x80000000L, 0x7fffffffL); 280 maketype("char", t_char, t_char, 0L, 127L); 281 maketype("long", builtintype(LONG), t_int, 0x80000000L, 0x7fffffffL); 282 maketype("short", builtintype(SHORT), t_int, 0xffff8000L, 0x7fffL); 283 maketype("unsigned char", builtintype(UCHAR), t_int, 0L, 255L); 284 maketype("unsigned short", builtintype(USHORT), t_int, 0L, 0xffffL); 285 maketype("unsigned long", builtintype(ULONG), t_int, 0L, 0xffffffffL); 286 maketype("unsigned int", builtintype(UNSIGNED), t_int, 0L, 0xffffffffL); 287 maketype("float", builtintype(FLOAT), t_int, 4L, 0L); 288 maketype("double", builtintype(DOUBLE), t_int, 8L, 0L); 289 t = builtintype(UNDEF); 290 printf("\t.stabs\t\"void:t%d=%d", t, t); 291 geninfo(nil); 292 } 293 294 /* 295 * Generate info for a new range type. 296 */ 297 298 private maketype(name, tnum, eqtnum, lower, upper) 299 char *name; 300 int tnum, eqtnum; 301 long lower, upper; 302 { 303 printf("\t.stabs\t\"%s:t%d=r%d;%d;%d;", name, tnum, eqtnum, lower, upper); 304 geninfo(nil); 305 } 306 307 /* 308 * Generate debugging information for the given type of the given symbol. 309 */ 310 311 private gentype(sym) 312 struct symtab *sym; 313 { 314 register struct symtab *p; 315 register TWORD t; 316 register TWORD basictype; 317 register Typeid typeid; 318 int i, arrindex, strindex, strtag; 319 320 p = sym; 321 t = p->stype; 322 if (ISFTN(t)) { 323 t = DECREF(t); 324 } 325 basictype = BTYPE(t); 326 if (ISARY(t)) { 327 arrindex = p->dimoff; 328 } else { 329 arrindex = NILINDEX; 330 } 331 if (basictype == STRTY or basictype == UNIONTY or basictype == ENUMTY) { 332 strindex = dimtab[p->sizoff + 1]; 333 if (strindex == -1) { 334 strindex = FORWARD; 335 strtag = dimtab[p->sizoff + 3]; 336 } else { 337 strtag = NILINDEX; 338 } 339 } else { 340 strindex = NILINDEX; 341 strtag = NILINDEX; 342 } 343 i = arrindex; 344 typeid = typelookup(t, arrindex, strindex, strtag); 345 while (t != basictype and typeid == nil) { 346 printf("%d=", entertype(t, i, strindex, strtag)); 347 switch (t&TMASK) { 348 case PTR: 349 printf("*"); 350 break; 351 352 case FTN: 353 printf("f"); 354 break; 355 356 case ARY: 357 printf("ar%d;0;%d;", t_int, dimtab[i++] - 1); 358 break; 359 } 360 t = DECREF(t); 361 if (t == basictype) { 362 typeid = typelookup(t, NILINDEX, strindex, strtag); 363 } else { 364 typeid = typelookup(t, i, strindex, strtag); 365 } 366 } 367 if (typeid == nil) { 368 if (strindex == FORWARD) { 369 typeid = typelookup(t, NILINDEX, FORWARD, dimtab[p->sizoff + 3]); 370 if (typeid == nil) { 371 cerror("unbelievable forward reference"); 372 } 373 printf("%d", typeid->tnum); 374 } else { 375 genstruct(t, NILINDEX, strindex, p->sname, bsize(p)); 376 } 377 } else { 378 printf("%d", typeid->tnum); 379 } 380 } 381 382 /* 383 * Generate type information for structures, unions, and enumerations. 384 */ 385 386 private genstruct(t, structid, index, name, size) 387 TWORD t; 388 int structid; 389 int index; 390 char *name; 391 int size; 392 { 393 register int i; 394 register struct symtab *field; 395 int id; 396 397 if (structid == NILINDEX) { 398 id = entertype(t, NILINDEX, index, NILINDEX); 399 } else { 400 id = structid; 401 } 402 switch (t) { 403 case STRTY: 404 case UNIONTY: 405 printf("%d=%c%d", id, t == STRTY ? 's' : 'u', size); 406 i = index; 407 while (dimtab[i] != -1) { 408 field = &stab[dimtab[i]]; 409 printf("%s:", field->sname); 410 gentype(field); 411 if (field->sclass > FIELD) { 412 printf(",%d,%d;", field->offset, field->sclass - FIELD); 413 } else { 414 printf(",%d,%d;", field->offset, 415 tsize(field->stype, field->dimoff, field->sizoff)); 416 } 417 ++i; 418 } 419 putchar(';'); 420 break; 421 422 case ENUMTY: 423 printf("%d=e", id); 424 i = index; 425 while (dimtab[i] != -1) { 426 field = &stab[dimtab[i]]; 427 printf("%s:%d,", field->sname, field->offset); 428 i++; 429 } 430 break; 431 432 default: 433 cerror("couldn't find basic type %d for %s\n", t, name); 434 break; 435 } 436 } 437 438 /* 439 * Generate offset and size info. 440 */ 441 442 private geninfo(p) 443 register struct symtab *p; 444 { 445 if (p == nil) { 446 printf("\",0x%x,0,0,0\n", N_LSYM); 447 } else { 448 switch (p->sclass) { 449 case EXTERN: 450 case EXTDEF: 451 if (ISFTN(p->stype)) { 452 printf("\",0x%x,0,%d,_%s\n", N_FUN, bsize(p), p->sname); 453 } else { 454 printf("\",0x%x,0,%d,_%s\n", N_GSYM, bsize(p), p->sname); 455 } 456 break; 457 458 case STATIC: 459 if (ISFTN(p->stype)) { 460 printf("\",0x%x,0,%d,_%s\n", N_FUN, bsize(p), p->sname); 461 } else if (p->slevel > 1) { 462 printf("\",0x%x,0,%d,L%d\n", N_STSYM, bsize(p), p->offset); 463 } else { 464 printf("\",0x%x,0,%d,_%s\n", N_LCSYM, bsize(p), p->sname); 465 } 466 break; 467 468 case REGISTER: 469 printf("\",0x%x,0,%d,%d\n", N_RSYM, bsize(p), p->offset); 470 break; 471 472 case PARAM: 473 printf("\",0x%x,0,%d,%d\n", N_PSYM, bsize(p), bytes(argoff)); 474 break; 475 476 default: 477 printf("\",0x%x,0,%d,%d\n", N_LSYM, bsize(p), bytes(p->offset)); 478 break; 479 } 480 } 481 } 482 483 /* 484 * Generate information for a newly-defined structure. 485 */ 486 487 outstruct(szindex, paramindex) 488 int szindex, paramindex; 489 { 490 register Typeid typeid; 491 register struct symtab *p; 492 register int i, t, strindex; 493 494 if (oldway) { 495 /* do nothing */; 496 } else if (gdebug) { 497 i = dimtab[szindex + 3]; 498 p = &stab[i]; 499 if (p->sname != nil) { 500 strindex = dimtab[p->sizoff + 1]; 501 typeid = typelookup(p->stype, NILINDEX, FORWARD, i); 502 if (typeid == nil) { 503 t = 0; 504 } else { 505 t = typeid->tnum; 506 reentertype(typeid, p->stype, NILINDEX, strindex, NILINDEX); 507 } 508 printf("\t.stabs\t\"%s:T", p->sname); 509 genstruct(p->stype, t, strindex, p->sname, bsize(p)); 510 geninfo(p); 511 } 512 } 513 } 514 515 pstab(name, type) 516 char *name; 517 int type; 518 { 519 register int i; 520 register char c; 521 522 if (!gdebug) { 523 return; 524 } else if (oldway) { 525 old_pstab(name, type); 526 return; 527 } 528 /* locctr(PROG); /* .stabs must appear in .text for c2 */ 529 #ifdef ASSTRINGS 530 if ( name[0] == '\0') 531 printf("\t.stabn\t"); 532 else 533 #ifndef FLEXNAMES 534 printf("\t.stabs\t\"%.8s\",", name); 535 #else 536 printf("\t.stabs\t\"%s\",", name); 537 #endif 538 #else 539 printf(" .stab "); 540 for(i=0; i<8; i++) 541 if (c = name[i]) printf("'%c,", c); 542 else printf("0,"); 543 #endif 544 printf("0%o,", type); 545 } 546 547 #ifdef STABDOT 548 pstabdot(type, value) 549 int type; 550 int value; 551 { 552 if ( ! gdebug) { 553 return; 554 } else if (oldway) { 555 old_pstabdot(type, value); 556 return; 557 } 558 /* locctr(PROG); /* .stabs must appear in .text for c2 */ 559 printf("\t.stabd\t"); 560 printf("0%o,0,0%o\n",type, value); 561 } 562 #endif 563 564 extern char NULLNAME[8]; 565 extern int labelno; 566 extern int fdefflag; 567 568 psline() 569 { 570 static int lastlineno; 571 register char *cp, *cq; 572 register int i; 573 574 if (!gdebug) { 575 return; 576 } else if (oldway) { 577 old_psline(); 578 return; 579 } 580 581 cq = ititle; 582 cp = ftitle; 583 584 while ( *cq ) if ( *cp++ != *cq++ ) goto neq; 585 if ( *cp == '\0' ) goto eq; 586 587 neq: for (i=0; i<100; i++) 588 ititle[i] = '\0'; 589 cp = ftitle; 590 cq = ititle; 591 while ( *cp ) 592 *cq++ = *cp++; 593 *cq = '\0'; 594 *--cq = '\0'; 595 #ifndef FLEXNAMES 596 for ( cp = ititle+1; *(cp-1); cp += 8 ) { 597 pstab(cp, N_SOL); 598 if (gdebug) printf("0,0,LL%d\n", labelno); 599 } 600 #else 601 pstab(ititle+1, N_SOL); 602 if (gdebug) printf("0,0,LL%d\n", labelno); 603 #endif 604 *cq = '"'; 605 printf("LL%d:\n", labelno++); 606 607 eq: if (lineno == lastlineno) return; 608 lastlineno = lineno; 609 610 if (fdefflag) { 611 #ifdef STABDOT 612 pstabdot(N_SLINE, lineno); 613 #else 614 pstab(NULLNAME, N_SLINE); 615 printf("0,%d,LL%d\n", lineno, labelno); 616 printf("LL%d:\n", labelno++); 617 #endif 618 } 619 } 620 621 plcstab(level) 622 int level; 623 { 624 if (!gdebug) { 625 return; 626 } else if (oldway) { 627 old_plcstab(level); 628 return; 629 } 630 #ifdef STABDOT 631 pstabdot(N_LBRAC, level); 632 #else 633 pstab(NULLNAME, N_LBRAC); 634 printf("0,%d,LL%d\n", level, labelno); 635 printf("LL%d:\n", labelno++); 636 #endif 637 } 638 639 prcstab(level) 640 int level; 641 { 642 if (!gdebug) { 643 return; 644 } else if (oldway) { 645 old_prcstab(level); 646 return; 647 } 648 #ifdef STABDOT 649 pstabdot(N_RBRAC, level); 650 #else 651 pstab(NULLNAME, N_RBRAC); 652 printf("0,%d,LL%d\n", level, labelno); 653 printf("LL%d:\n", labelno++); 654 #endif 655 } 656 657 pfstab(sname) 658 char *sname; 659 { 660 register struct symtab *p; 661 662 if (gdebug) { 663 if (oldway) { 664 old_pfstab(sname); 665 } else { 666 p = &stab[lookup(sname, 0)]; 667 printf("\t.stabs\t\"%s:", p->sname); 668 putchar((p->sclass == STATIC) ? 'f' : 'F'); 669 gentype(p); 670 geninfo(p); 671 } 672 } 673 } 674 675 /* 676 * Old way of doing things. 677 */ 678 679 private old_fixarg(p) 680 struct symtab *p; { 681 if (gdebug) { 682 old_pstab(p->sname, N_PSYM); 683 if (gdebug) printf("0,%d,%d\n", p->stype, argoff/SZCHAR); 684 old_poffs(p); 685 } 686 } 687 688 private old_outstab(p) 689 struct symtab *p; { 690 register TWORD ptype; 691 register char *pname; 692 register char pclass; 693 register int poffset; 694 695 if (!gdebug) return; 696 697 ptype = p->stype; 698 pname = p->sname; 699 pclass = p->sclass; 700 poffset = p->offset; 701 702 if (ISFTN(ptype)) { 703 return; 704 } 705 706 switch (pclass) { 707 708 case AUTO: 709 old_pstab(pname, N_LSYM); 710 printf("0,%d,%d\n", ptype, (-poffset)/SZCHAR); 711 old_poffs(p); 712 return; 713 714 case EXTDEF: 715 case EXTERN: 716 old_pstab(pname, N_GSYM); 717 printf("0,%d,0\n", ptype); 718 old_poffs(p); 719 return; 720 721 case STATIC: 722 #ifdef LCOMM 723 /* stabLCSYM is 1 during nidcl so we can get stab type right */ 724 old_pstab(pname, stabLCSYM ? N_LCSYM : N_STSYM); 725 #else 726 old_pstab(pname, N_STSYM); 727 #endif 728 if (p->slevel > 1) { 729 printf("0,%d,L%d\n", ptype, poffset); 730 } else { 731 printf("0,%d,%s\n", ptype, exname(pname)); 732 } 733 old_poffs(p); 734 return; 735 736 case REGISTER: 737 old_pstab(pname, N_RSYM); 738 printf("0,%d,%d\n", ptype, poffset); 739 old_poffs(p); 740 return; 741 742 case MOS: 743 case MOU: 744 old_pstab(pname, N_SSYM); 745 printf("0,%d,%d\n", ptype, poffset/SZCHAR); 746 old_poffs(p); 747 return; 748 749 case PARAM: 750 /* parameter stab entries are processed in dclargs() */ 751 return; 752 753 default: 754 #ifndef FLEXNAMES 755 if (ddebug) printf(" No .stab for %.8s\n", pname); 756 #else 757 if (ddebug) printf(" No .stab for %s\n", pname); 758 #endif 759 760 } 761 } 762 763 private old_pstab(name, type) 764 char *name; 765 int type; { 766 register int i; 767 register char c; 768 if (!gdebug) return; 769 /* locctr(PROG); /* .stabs must appear in .text for c2 */ 770 #ifdef ASSTRINGS 771 if ( name[0] == '\0') 772 printf("\t.stabn\t"); 773 else 774 #ifndef FLEXNAMES 775 printf("\t.stabs\t\"%.8s\", ", name); 776 #else 777 printf("\t.stabs\t\"%s\", ", name); 778 #endif 779 #else 780 printf(" .stab "); 781 for(i=0; i<8; i++) 782 if (c = name[i]) printf("'%c,", c); 783 else printf("0,"); 784 #endif 785 printf("0%o,", type); 786 } 787 788 #ifdef STABDOT 789 private old_pstabdot(type, value) 790 int type; 791 int value; 792 { 793 if ( ! gdebug) return; 794 /* locctr(PROG); /* .stabs must appear in .text for c2 */ 795 printf("\t.stabd\t"); 796 printf("0%o,0,0%o\n",type, value); 797 } 798 #endif 799 800 private old_poffs(p) 801 register struct symtab *p; { 802 int s; 803 if (!gdebug) return; 804 if ((s = dimtab[p->sizoff]/SZCHAR) > 1) { 805 old_pstab(p->sname, N_LENG); 806 printf("1,0,%d\n", s); 807 } 808 } 809 810 private old_psline() { 811 static int lastlineno; 812 register char *cp, *cq; 813 register int i; 814 815 if (!gdebug) return; 816 817 cq = ititle; 818 cp = ftitle; 819 820 while ( *cq ) if ( *cp++ != *cq++ ) goto neq; 821 if ( *cp == '\0' ) goto eq; 822 823 neq: for (i=0; i<100; i++) 824 ititle[i] = '\0'; 825 cp = ftitle; 826 cq = ititle; 827 while ( *cp ) 828 *cq++ = *cp++; 829 *cq = '\0'; 830 *--cq = '\0'; 831 #ifndef FLEXNAMES 832 for ( cp = ititle+1; *(cp-1); cp += 8 ) { 833 old_pstab(cp, N_SOL); 834 if (gdebug) printf("0,0,LL%d\n", labelno); 835 } 836 #else 837 old_pstab(ititle+1, N_SOL); 838 if (gdebug) printf("0,0,LL%d\n", labelno); 839 #endif 840 *cq = '"'; 841 printf("LL%d:\n", labelno++); 842 843 eq: if (lineno == lastlineno) return; 844 lastlineno = lineno; 845 846 if (fdefflag) { 847 #ifdef STABDOT 848 old_pstabdot(N_SLINE, lineno); 849 #else 850 old_pstab(NULLNAME, N_SLINE); 851 printf("0,%d,LL%d\n", lineno, labelno); 852 printf("LL%d:\n", labelno++); 853 #endif 854 } 855 } 856 857 private old_plcstab(level) { 858 if (!gdebug) return; 859 #ifdef STABDOT 860 old_pstabdot(N_LBRAC, level); 861 #else 862 old_pstab(NULLNAME, N_LBRAC); 863 printf("0,%d,LL%d\n", level, labelno); 864 printf("LL%d:\n", labelno++); 865 #endif 866 } 867 868 private old_prcstab(level) { 869 if (!gdebug) return; 870 #ifdef STABDOT 871 pstabdot(N_RBRAC, level); 872 #else 873 pstab(NULLNAME, N_RBRAC); 874 printf("0,%d,LL%d\n", level, labelno); 875 printf("LL%d:\n", labelno++); 876 #endif 877 } 878 879 private old_pfstab(sname) 880 char *sname; { 881 if (!gdebug) return; 882 pstab(sname, N_FUN); 883 #ifndef FLEXNAMES 884 printf("0,%d,_%.7s\n", lineno, sname); 885 #else 886 printf("0,%d,_%s\n", lineno, sname); 887 #endif 888 } 889