1: /*
   2:  * Copyright (c) 1982 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)assyms.c	5.1 (Berkeley) 4/30/85";
   9: #endif not lint
  10: 
  11: #include <stdio.h>
  12: #include <ctype.h>
  13: #include "as.h"
  14: #include "asscan.h"
  15: #include "assyms.h"
  16: 
  17: /*
  18:  *	Managers for chunks of symbols allocated from calloc()
  19:  *	We maintain a linked list of such chunks.
  20:  *
  21:  */
  22: struct  allocbox    *allochead; /*head of chunk list*/
  23: struct  allocbox    *alloctail; /*tail*/
  24: struct  allocbox    *newbox;    /*for creating a new chunk*/
  25: struct  symtab      *nextsym;   /*next symbol free*/
  26: int         symsleft;   /*slots left in current chunk*/
  27: 
  28: struct  symtab      **symptrs;
  29: struct  symtab      **symdelim[NLOC + NLOC +1];
  30: struct  symtab      **symptrub;
  31: /*
  32:  *	Managers for the dynamically extendable hash table
  33:  */
  34: struct  hashdallop  *htab;
  35: 
  36: Iptr    *itab[NINST];   /*maps opcodes to instructions*/
  37: /*
  38:  *	Counts what went into the symbol table, so that the
  39:  *	size of the symbol table can be computed.
  40:  */
  41: int nsyms;      /* total number in the symbol table */
  42: int njxxx;      /* number of jxxx entrys */
  43: int nforgotten; /* number of symbols erroneously entered */
  44: int nlabels;    /* number of label entries */
  45: 
  46: /*
  47:  *	Managers of the symbol literal storage.
  48:  */
  49: struct  strpool     *strplhead = 0;
  50: 
  51: symtabinit()
  52: {
  53:     allochead = 0;
  54:     alloctail = 0;
  55:     nextsym = 0;
  56:     symsleft = 0;
  57:     strpoolalloc();     /* get the first strpool storage area */
  58:     htab = 0;
  59:     htaballoc();        /* get the first part of the hash table */
  60: }
  61: 
  62: /*
  63:  *	Install all known instructions in the symbol table
  64:  */
  65: syminstall()
  66: {
  67:     register    Iptr    ip;
  68:     register    struct  symtab  **hp;
  69:     register    char    *p1, *p2;
  70:     register    int i;
  71: 
  72:     for (i = 0; i < NINST; i++)
  73:         itab[i] = (Iptr*)BADPOINT;
  74: 
  75:     for (ip = (Iptr)instab; FETCHNAME(ip)[0]; ip++) {
  76:         p1 = FETCHNAME(ip);
  77:         p2 = yytext;
  78:         while (*p2++ = *p1++);
  79:         hp = lookup(0);     /* 0 => don't install this*/
  80:         if (*hp==NULL) {
  81:             *hp = (struct symtab *)ip;
  82:             if (   (ip->s_tag!=INSTn)
  83:                 && (ip->s_tag!=INST0)
  84:                 && (ip->s_tag!=0))
  85:                 continue; /* was pseudo-op */
  86:             if (itab[ip->i_eopcode] == (Iptr*)BADPOINT){
  87:                 itab[ip->i_eopcode] =
  88:                     (Iptr*)ClearCalloc(256, sizeof(Iptr));
  89:                 for (i = 0; i < 256; i++)
  90:                     itab[ip->i_eopcode][i] =
  91:                         (Iptr)BADPOINT;
  92:             }
  93:             itab[ip->i_eopcode][ip->i_popcode] = ip;
  94:         }
  95:     }
  96: }   /*end of syminstall*/
  97: 
  98: #define ISLABEL(sp) \
  99:     (   (!savelabels) \
 100:      && (sp->s_tag == LABELID) \
 101:      && (STRPLACE(sp) & STR_CORE) \
 102:      && (FETCHNAME(sp)[0] == 'L'))
 103: /*
 104:  *	Assign final values to symbols,
 105:  *	and overwrite the index field with its relative position in
 106:  *	the symbol table we give to the loader.
 107:  */
 108: extern struct exec hdr;
 109: 
 110: freezesymtab()
 111: {
 112:     register    struct  symtab  *sp;
 113:                 long    bs;
 114:     register    int relpos = 0;
 115:     register    struct  symtab      *ubsp;
 116:     register    struct  allocbox    *allocwalk;
 117: 
 118:     DECLITERATE(allocwalk, sp, ubsp)
 119:     {
 120:         if (sp->s_tag >= IGNOREBOUND)
 121:             continue;       /*totally ignore jxxx entries */
 122:         /*
 123: 		 *	Ignore stabs, but give them a symbol table index
 124: 		 */
 125:         if (sp->s_type & STABFLAG)
 126:             goto assignindex;
 127:         if ((sp->s_type&XTYPE)==XUNDEF)
 128:             sp->s_type = XXTRN+XUNDEF;
 129:         else if ((sp->s_type&XTYPE)==XDATA)
 130:             sp->s_value += usedot[sp->s_index].e_xvalue;
 131:         else if ((sp->s_type&XTYPE)==XTEXT)
 132:             sp->s_value += usedot[sp->s_index].e_xvalue;
 133:         else if ((sp->s_type&XTYPE)==XBSS) {
 134:             bs = sp->s_value;
 135:             sp->s_value = hdr.a_bss + datbase;
 136:             hdr.a_bss += bs;
 137:         }
 138:        assignindex:
 139:         if (!ISLABEL(sp))
 140:             sp->s_index = relpos++;
 141:     }
 142: }
 143: 
 144: /*
 145:  *	For all of the stabs that had their final value undefined during pass 1
 146:  *	and during pass 2 assign a final value.
 147:  *	We have already given stab entrys a initial approximation
 148:  *	when we constsructed the sorted symbol table.
 149:  *	Iteration order doesn't matter.
 150:  */
 151: 
 152: stabfix()
 153: {
 154:     register struct symtab *sp, **cosp;
 155:     register struct symtab *p;
 156: 
 157:     SYMITERATE(cosp, sp){
 158:         if(sp->s_ptype && (sp->s_type & STABFLAG)) {
 159:             p = sp->s_dest;
 160: /*
 161:  * STABFLOATING indicates that the offset has been saved in s_desc, s_other
 162:  */
 163:             if(sp->s_tag == STABFLOATING) {
 164:               sp->s_value = ( ( ((unsigned char) sp->s_other) << 16)                    | ( (unsigned short) sp->s_desc )  );
 165:               sp->s_value = sp->s_value + p->s_value;
 166:             }
 167:             else sp->s_value = p->s_value;
 168:             sp->s_index = p->s_index;
 169:             sp->s_type = p->s_type;
 170: 
 171: 
 172:         }
 173:     }
 174: }
 175: 
 176: char *Calloc(number, size)
 177:     int number, size;
 178: {
 179:     register    char *newstuff;
 180:     char    *sbrk();
 181:     newstuff = sbrk(number*size);
 182:     if ((int)newstuff == -1){
 183:         yyerror("Ran out of Memory");
 184:         delexit();
 185:     }
 186:     return(newstuff);
 187: }
 188: 
 189: char *ClearCalloc(number, size)
 190:     int number, size;
 191: {
 192:     register    char    *newstuff;      /* r11 */
 193:     register    int length = number * size; /* r10 */
 194: #ifdef lint
 195:     length = length;
 196: #endif length
 197:     newstuff = Calloc(number, size);
 198:     asm("movc5 $0, (r0), $0, r10, (r11)");
 199:     return(newstuff);
 200: }
 201: 
 202: struct symtab *symalloc()
 203: {
 204:     if (symsleft == 0){
 205:         newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY);
 206:         symsleft = SYMDALLOP;
 207:         nextsym = &newbox->symslots[0];
 208:         if (alloctail == 0){
 209:             allochead = alloctail = newbox;
 210:         } else {
 211:             alloctail->nextalloc = newbox;
 212:             alloctail = newbox;
 213:         }
 214:     }
 215:     --symsleft;
 216:     ++nsyms;
 217:     return(nextsym++);
 218: }
 219: 
 220: strpoolalloc()
 221: {
 222:     register    struct  strpool *new;
 223: 
 224:     new = (struct strpool *)Calloc(1, sizeof (struct strpool));
 225:     new->str_nalloc = 0;
 226:     new->str_next = strplhead;
 227:     strplhead = new;
 228: }
 229: 
 230: symcmp(Pptr, Qptr)
 231:     struct symtab **Pptr, **Qptr;
 232: {
 233:     register struct symtab *p = *Pptr;
 234:     register struct symtab *q = *Qptr;
 235:     if (p->s_index < q->s_index)
 236:         return(-1);
 237:     if (p->s_index > q->s_index)
 238:         return(1);
 239:     if (p->s_value < q->s_value)
 240:         return(-1);
 241:     if (p->s_value > q->s_value)
 242:         return(1);
 243:     /*
 244: 	 *	Force jxxx entries to virtually preceed labels defined
 245: 	 *	to follow the jxxxx instruction, so that bumping the
 246: 	 *	jxxx instruction correctly fixes up the following labels
 247: 	 */
 248:     if (p->s_tag >= IGNOREBOUND)    /*p points to a jxxx*/
 249:         return(-1);
 250:     if (q->s_tag >= IGNOREBOUND)
 251:         return(1);
 252:     /*
 253: 	 *	both are now just plain labels; the relative order doesn't
 254: 	 *	matter.  Both can't be jxxxes, as they would have different
 255: 	 *	values.
 256: 	 */
 257:     return(0);
 258: }   /*end of symcmp*/
 259: 
 260: /*
 261:  *	We construct the auxiliary table of pointers, symptrs and
 262:  *	symdelim
 263:  *	We also assign preliminary values to stab entries that did not yet
 264:  *	have an absolute value (because they initially referred to
 265:  *	forward references). We don't worry about .stabds, as they
 266:  *	already have an estimated final value
 267:  */
 268: 
 269: sortsymtab()
 270: {
 271:     register    struct  symtab  *sp;
 272:     register    struct  symtab  **cowalk;
 273:     register    struct  allocbox    *allocwalk;
 274:             struct  symtab  *ubsp;
 275:                 int segno;
 276:                 int slotno;
 277:                 int symsin; /*number put into symptrs*/
 278: 
 279:     symptrs =  (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs);
 280:     /*
 281: 	 *	Allocate one word at the beginning of the symptr array
 282: 	 *	so that backwards scans through the symptr array will
 283: 	 *	work correctly while scanning through the zeroth segment
 284: 	 */
 285:     *symptrs++ = 0;
 286:     cowalk = symptrs;
 287:     symsin = 0;
 288:     DECLITERATE(allocwalk, sp, ubsp) {
 289:         if (sp->s_ptype && (sp->s_type &STABFLAG)){
 290:             sp->s_value = sp->s_dest->s_value;
 291:             sp->s_index = sp->s_dest->s_index;
 292:         }
 293:         if (symsin >= nsyms)
 294:             yyerror("INTERNAL ERROR: overfilled symbol table indirection table");
 295:         *cowalk++ = sp;
 296:         symsin++;
 297:     }
 298:     if (symsin != nsyms)
 299:         yyerror("INTERNAL ERROR: installed %d syms, should have installed %d",
 300:             symsin, nsyms);
 301:     symptrub = &symptrs[nsyms ];
 302:     qsort(symptrs, nsyms, sizeof *symptrs, symcmp);
 303:     symdelim[0] = symptrs;
 304:     for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1;
 305:          segno < NLOC + NLOC;
 306:          segno++, slotno++){
 307:         for (; sp && sp->s_index == segno; sp = *++cowalk);
 308:         symdelim[slotno] = cowalk;  /*forms the ub delimeter*/
 309:     }
 310: }   /*end of sortsymtab*/
 311: 
 312: #ifdef DEBUG
 313: dumpsymtab()
 314: {
 315:     register    int segno;
 316:     register    struct symtab *sp, **cosp, *ub;
 317:     char        *tagstring();
 318: 
 319:     printf("Symbol Table dump:\n");
 320:     for (segno = 0; segno < NLOC + NLOC; segno++){
 321:         printf("Segment number: %d\n", segno);
 322:         SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){
 323:             printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n",
 324:                 segno, FETCHNAME(sp),
 325:                 sp->s_value, sp->s_index,
 326:                 tagstring(sp->s_tag));
 327:             printf("\t\ttype: %d jxbump %d jxfear: %d\n",
 328:                 sp->s_type, sp->s_jxbump, sp->s_jxfear);
 329:         }
 330:         printf("\n\n");
 331:     }
 332: }
 333: 
 334: static  char tagbuff[4];
 335: 
 336: char *tagstring(tag)
 337:     unsigned    char    tag;
 338: {
 339:     switch(tag){
 340:         case JXACTIVE:      return("active");
 341:         case JXNOTYET:      return("notyet");
 342:         case JXALIGN:       return("align");
 343:         case JXQUESTIONABLE:    return("jxquestionable");
 344:         case JXINACTIVE:    return("inactive");
 345:         case JXTUNNEL:      return("tunnel");
 346:         case OBSOLETE:      return("obsolete");
 347:         case IGNOREBOUND:   return("ignorebound");
 348:         case STABFLOATING:  return("stabfloating");
 349:         case STABFIXED:     return("stabfixed");
 350:         case LABELID:       return("labelid");
 351:         case OKTOBUMP:      return("oktobump");
 352:         case ISET:      return("iset");
 353:         case ILSYM:     return("ilsym");
 354:         default:        sprintf(tagbuff,"%d", tag);
 355:                     return(tagbuff);
 356:     }
 357: }
 358: #endif DEBUG
 359: 
 360: htaballoc()
 361: {
 362:     register    struct  hashdallop  *new;
 363:     new = (struct hashdallop *)ClearCalloc(1, sizeof (struct hashdallop));
 364:     if (htab == 0)
 365:         htab = new;
 366:     else {      /* add AFTER the 1st slot */
 367:         new->h_next = htab->h_next;
 368:         htab->h_next = new;
 369:     }
 370: }
 371: 
 372: #define     HASHCLOGGED (NHASH / 2)
 373: 
 374: /*
 375:  *	Lookup a symbol stored in extern yytext.
 376:  *	All strings passed in via extern yytext had better have
 377:  *	a trailing null.  Strings are placed in yytext for hashing by
 378:  *	syminstall() and by yylex();
 379:  *
 380:  *	We take pains to avoid function calls; this functdion
 381:  *	is called quite frequently, and the calls overhead
 382:  *	in the vax contributes significantly to the overall
 383:  *	execution speed of as.
 384:  */
 385: struct symtab **lookup(instflg)
 386:     int instflg;        /* 0: don't install */
 387: {
 388:     static   int        initialprobe;
 389:     register struct symtab  **hp;
 390:     register char       *from;
 391:     register char       *to;
 392:     register    int len;
 393:     register    int nprobes;
 394:     static  struct  hashdallop *hdallop;
 395:     static  struct  symtab  **emptyslot;
 396:     static  struct  hashdallop *emptyhd;
 397:     static  struct  symtab  **hp_ub;
 398: 
 399:     emptyslot = 0;
 400:     for (nprobes = 0, from = yytext;
 401:          *from;
 402:          nprobes <<= 2, nprobes += *from++)
 403:         continue;
 404:     nprobes += from[-1] << 5;
 405:     nprobes %= NHASH;
 406:     if (nprobes < 0)
 407:         nprobes += NHASH;
 408: 
 409:     initialprobe = nprobes;
 410:     for (hdallop = htab; hdallop != 0; hdallop = hdallop->h_next){
 411:         for (hp = &(hdallop->h_htab[initialprobe]),
 412:                 nprobes = 1,
 413:                 hp_ub = &(hdallop->h_htab[NHASH]);
 414:              (*hp) && (nprobes < NHASH);
 415:                 hp += nprobes,
 416:                 hp -= (hp >= hp_ub) ? NHASH:0,
 417:                 nprobes += 2)
 418:         {
 419:             from = yytext;
 420:             to = FETCHNAME(*hp);
 421:             while (*from && *to)
 422:                 if (*from++ != *to++)
 423:                     goto nextprobe;
 424:             if (*to == *from)   /*assert both are == 0*/
 425:                 return(hp);
 426:         nextprobe: ;
 427:         }
 428:         if (*hp == 0 && emptyslot == 0 &&
 429:             hdallop->h_nused < HASHCLOGGED) {
 430:             emptyslot = hp;
 431:             emptyhd = hdallop;
 432:         }
 433:     }
 434:     if (emptyslot == 0) {
 435:         htaballoc();
 436:         hdallop = htab->h_next;     /* aren't we smart! */
 437:         hp = &hdallop->h_htab[initialprobe];
 438:     } else {
 439:         hdallop = emptyhd;
 440:         hp = emptyslot;
 441:     }
 442:     if (instflg) {
 443:         *hp = symalloc();
 444:         hdallop->h_nused++;
 445:         for (from = yytext, len = 0; *from++; len++)
 446:             continue;
 447:         (*hp)->s_name = (char *)savestr(yytext, len + 1, STR_BOTH);
 448:     }
 449:     return(hp);
 450: }   /*end of lookup*/
 451: /*
 452:  *	save a string str with len in the places indicated by place
 453:  */
 454: struct strdesc *savestr(str, len, place)
 455:     char    *str;
 456:     int len;
 457:     int place;
 458: {
 459:     reg struct  strdesc *res;
 460:         int tlen;
 461:     /*
 462: 	 *	Compute the total length of the record to live in core
 463: 	 */
 464:     tlen = sizeof(struct strdesc) - sizeof(res->sd_string);
 465:     if (place & STR_CORE)
 466:         tlen += len;
 467:     /*
 468: 	 *	See if there is enough space for the record,
 469: 	 *	and allocate the record.
 470: 	 */
 471:     if (tlen >= (STRPOOLDALLOP - strplhead->str_nalloc))
 472:         strpoolalloc();
 473:     res = (struct strdesc *)(strplhead->str_names + strplhead->str_nalloc);
 474:     /*
 475: 	 *	Save the string information that is always present
 476: 	 */
 477:     res->sd_stroff = strfilepos;
 478:     res->sd_strlen = len;
 479:     res->sd_place = place;
 480:     /*
 481: 	 *	Now, save the string itself.  If str is null, then
 482: 	 *	the characters have already been dumped to the file
 483: 	 */
 484:     if ((place & STR_CORE) && str)
 485:         movestr(res[0].sd_string, str, len);
 486:     if (place & STR_FILE){
 487:         if (str){
 488:             fwrite(str, 1, len, strfile);
 489:         }
 490:         strfilepos += len;
 491:     }
 492:     /*
 493: 	 *	Adjust the in core string pool size
 494: 	 */
 495:     strplhead->str_nalloc += tlen;
 496:     return(res);
 497: }
 498: /*
 499:  *	The relocation information is saved internally in an array of
 500:  *	lists of relocation buffers.  The relocation buffers are
 501:  *	exactly the same size as a token buffer; if we use VM for the
 502:  *	temporary file we reclaim this storage, otherwise we create
 503:  *	them by mallocing.
 504:  */
 505: #define RELBUFLG    TOKBUFLG
 506: #define NRELOC      ((TOKBUFLG - \
 507:               (sizeof (int) + sizeof (struct relbufdesc *)) \
 508:             ) / (sizeof (struct relocation_info)))
 509: 
 510: struct  relbufdesc{
 511:     int rel_count;
 512:     struct  relbufdesc  *rel_next;
 513:     struct  relocation_info rel_reloc[NRELOC];
 514: };
 515: extern  struct  relbufdesc  *tok_free;
 516: #define rel_free tok_free
 517: static  struct  relbufdesc  *rel_temp;
 518: struct  relocation_info r_can_1PC;
 519: struct  relocation_info r_can_0PC;
 520: 
 521: initoutrel()
 522: {
 523:     r_can_0PC.r_address = 0;
 524:     r_can_0PC.r_symbolnum = 0;
 525:     r_can_0PC.r_pcrel = 0;
 526:     r_can_0PC.r_length = 0;
 527:     r_can_0PC.r_extern = 0;
 528: 
 529:     r_can_1PC = r_can_0PC;
 530:     r_can_1PC.r_pcrel = 1;
 531: }
 532: 
 533: outrel(xp, reloc_how)
 534:     register    struct  exp *xp;
 535:     int     reloc_how;  /* TYPB..TYPH + (possibly)RELOC_PCREL */
 536: {
 537:     struct      relocation_info reloc;
 538:     register    int x_type_mask;
 539:             int pcrel;
 540: 
 541:     x_type_mask = xp->e_xtype & ~XFORW;
 542:     pcrel = reloc_how & RELOC_PCREL;
 543:     reloc_how &= ~RELOC_PCREL;
 544: 
 545:     if (bitoff&07)
 546:         yyerror("Padding error");
 547:     if (x_type_mask == XUNDEF)
 548:         yyerror("Undefined reference");
 549: 
 550:     if ( (x_type_mask != XABS) || pcrel ) {
 551:         if (ty_NORELOC[reloc_how])
 552:             yyerror("Illegal Relocation of floating or large int number.");
 553:         reloc = pcrel ? r_can_1PC : r_can_0PC;
 554:         reloc.r_address = dotp->e_xvalue -
 555:             ( (dotp < &usedot[NLOC] || readonlydata) ? 0 : datbase );
 556:         reloc.r_length = ty_nlg[reloc_how];
 557:         switch(x_type_mask){
 558:             case XXTRN | XUNDEF:
 559:                 reloc.r_symbolnum = xp->e_xname->s_index;
 560:                 reloc.r_extern = 1;
 561:                 break;
 562:             default:
 563:                 if (readonlydata && (x_type_mask&~XXTRN) == XDATA)
 564:                     x_type_mask = XTEXT | (x_type_mask&XXTRN);
 565:                 reloc.r_symbolnum = x_type_mask;
 566:                 break;
 567:         }
 568:         if ( (relfil == 0) || (relfil->rel_count >= NRELOC) ){
 569:             if (rel_free){
 570:                 rel_temp = rel_free;
 571:                 rel_free = rel_temp->rel_next;
 572:             } else {
 573:                 rel_temp = (struct relbufdesc *)
 574:                     Calloc(1,sizeof (struct relbufdesc));
 575:             }
 576:             rel_temp->rel_count = 0;
 577:             rel_temp->rel_next = relfil;
 578:             relfil = rusefile[dotp - &usedot[0]] = rel_temp;
 579:         }
 580:         relfil->rel_reloc[relfil->rel_count++] = reloc;
 581:     }
 582:     /*
 583: 	 *	write the unrelocated value to the text file
 584: 	 */
 585:     dotp->e_xvalue += ty_nbyte[reloc_how];
 586:     if (pcrel)
 587:         xp->e_xvalue -= dotp->e_xvalue;
 588:     switch(reloc_how){
 589:     case TYPO:
 590:     case TYPQ:
 591: 
 592:     case TYPF:
 593:     case TYPD:
 594:     case TYPG:
 595:     case TYPH:
 596:         bignumwrite(xp->e_number, reloc_how);
 597:         break;
 598: 
 599:     default:
 600:         bwrite((char *)&(xp->e_xvalue), ty_nbyte[reloc_how], txtfil);
 601:         break;
 602:     }
 603: }
 604: /*
 605:  *	Flush out all of the relocation information.
 606:  *	Note that the individual lists of buffers are in
 607:  *	reverse order, so we must reverse them
 608:  */
 609: off_t closeoutrel(relocfile)
 610:     BFILE   *relocfile;
 611: {
 612:     int locindex;
 613:     u_long  Closeoutrel();
 614: 
 615:     trsize = 0;
 616:     for (locindex = 0; locindex < NLOC; locindex++){
 617:         trsize += Closeoutrel(rusefile[locindex], relocfile);
 618:     }
 619:     drsize = 0;
 620:     for (locindex = 0; locindex < NLOC; locindex++){
 621:         drsize += Closeoutrel(rusefile[NLOC + locindex], relocfile);
 622:     }
 623:     return(trsize + drsize);
 624: }
 625: 
 626: u_long Closeoutrel(relfil, relocfile)
 627:     struct  relbufdesc  *relfil;
 628:     BFILE   *relocfile;
 629: {
 630:     u_long  tail;
 631:     if (relfil == 0)
 632:         return(0L);
 633:     tail = Closeoutrel(relfil->rel_next, relocfile);
 634:     bwrite((char *)&relfil->rel_reloc[0],
 635:         relfil->rel_count * sizeof (struct relocation_info),
 636:         relocfile);
 637:     return(tail + relfil->rel_count * sizeof (struct relocation_info));
 638: }
 639: 
 640: #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels))
 641: int sizesymtab()
 642: {
 643:     return (sizeof (struct nlist) * NOUTSYMS);
 644: }
 645: /*
 646:  *	Write out n symbols to file f, beginning at p
 647:  *	ignoring symbols that are obsolete, jxxx instructions, and
 648:  *	possibly, labels
 649:  */
 650: int symwrite(symfile)
 651:     BFILE *symfile;
 652: {
 653:         int symsout;        /*those actually written*/
 654:         int symsdesired = NOUTSYMS;
 655:     reg struct  symtab *sp, *ub;
 656:         char    *name;          /* temp to save the name */
 657:         int totalstr;
 658:     /*
 659: 	 *	We use sp->s_index to hold the length of the
 660: 	 *	name; it isn't used for anything else
 661: 	 */
 662:     register    struct  allocbox    *allocwalk;
 663: 
 664:     symsout = 0;
 665:     totalstr = sizeof(totalstr);
 666:     DECLITERATE(allocwalk, sp, ub) {
 667:         if (sp->s_tag >= IGNOREBOUND)
 668:             continue;
 669:         if (ISLABEL(sp))
 670:             continue;
 671:         symsout++;
 672:         name = sp->s_name;      /* save pointer */
 673:         /*
 674: 		 *	the length of the symbol table string
 675: 		 *	always includes the trailing null;
 676: 		 *	blast the pointer to its a.out value.
 677: 		 */
 678:         if (sp->s_name && (sp->s_index = STRLEN(sp))){
 679:             sp->s_nmx = totalstr;
 680:             totalstr += sp->s_index;
 681:         } else {
 682:             sp->s_nmx = 0;
 683:         }
 684:         if (sp->s_ptype != 0)
 685:             sp->s_type = sp->s_ptype;
 686:         else
 687:             sp->s_type = (sp->s_type & (~XFORW));
 688:         if (readonlydata && (sp->s_type&~N_EXT) == N_DATA)
 689:             sp->s_type = N_TEXT | (sp->s_type & N_EXT);
 690:         bwrite((char *)&sp->s_nm, sizeof (struct nlist), symfile);
 691:         sp->s_name = name;      /* restore pointer */
 692:     }
 693:     if (symsout != symsdesired)
 694:         yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n",
 695:             symsout, symsdesired);
 696:     /*
 697: 	 *	Construct the string pool from the symbols that were written,
 698: 	 *	possibly fetching from the string file if the string
 699: 	 *	is not core resident.
 700: 	 */
 701:     bwrite(&totalstr, sizeof(totalstr), symfile);
 702:     symsout = 0;
 703:     DECLITERATE(allocwalk, sp, ub) {
 704:         if (sp->s_tag >= IGNOREBOUND)
 705:             continue;
 706:         if (ISLABEL(sp))
 707:             continue;
 708:         symsout++;
 709:         if (STRLEN(sp) > 0){
 710:          if (STRPLACE(sp) & STR_CORE){
 711:             bwrite(FETCHNAME(sp), STRLEN(sp), symfile);
 712:          } else if (STRPLACE(sp) & STR_FILE){
 713:             char    rbuf[2048];
 714:             int left, nread;
 715:             fseek(strfile, STROFF(sp), 0);
 716:             for (left = STRLEN(sp); left > 0; left -= nread){
 717:                 nread = fread(rbuf, sizeof(char),
 718:                     min(sizeof(rbuf), left), strfile);
 719:                 if (nread == 0)
 720:                     break;
 721:                 bwrite(rbuf, nread, symfile);
 722:             }
 723:          }
 724:         }
 725:     }
 726:     if (symsout != symsdesired)
 727:         yyerror("INTERNAL ERROR: Wrote %d strings, wanted %d\n",
 728:             symsout, symsdesired);
 729: }

Defined functions

Calloc defined in line 176; used 10 times
ClearCalloc defined in line 189; used 5 times
Closeoutrel defined in line 626; used 4 times
closeoutrel defined in line 609; used 1 times
dumpsymtab defined in line 313; used 2 times
freezesymtab defined in line 110; used 1 times
htaballoc defined in line 360; used 2 times
initoutrel defined in line 521; used 1 times
lookup defined in line 385; used 5 times
outrel defined in line 533; used 2 times
savestr defined in line 454; used 5 times
sizesymtab defined in line 641; used 1 times
sortsymtab defined in line 269; used 1 times
stabfix defined in line 152; used 1 times
strpoolalloc defined in line 220; used 2 times
symalloc defined in line 202; used 5 times
symcmp defined in line 230; used 1 times
syminstall defined in line 65; used 1 times
symtabinit defined in line 51; used 1 times
symwrite defined in line 650; used 1 times
tagstring defined in line 336; used 2 times

Defined variables

allochead defined in line 22; used 3 times
alloctail defined in line 23; used 6 times
htab defined in line 34; used 7 times
itab defined in line 36; used 13 times
newbox defined in line 24; used 5 times
nextsym defined in line 25; used 4 times
nforgotten defined in line 43; used 1 times
njxxx defined in line 42; used 1 times
nlabels defined in line 44; used 1 times
nsyms defined in line 41; used 8 times
r_can_0PC defined in line 519; used 7 times
r_can_1PC defined in line 518; used 3 times
rel_temp defined in line 517; used 6 times
sccsid defined in line 8; never used
strplhead defined in line 49; used 6 times
symdelim defined in line 29; used 5 times
symptrs defined in line 28; used 10 times
symptrub defined in line 30; used 2 times
symsleft defined in line 26; used 4 times
tagbuff defined in line 334; used 2 times

Defined struct's

relbufdesc defined in line 510; used 12 times

Defined macros

HASHCLOGGED defined in line 372; used 1 times
ISLABEL defined in line 98; used 3 times
NOUTSYMS defined in line 640; used 2 times
NRELOC defined in line 506; used 2 times
RELBUFLG defined in line 505; never used
rel_free defined in line 516; used 3 times
Last modified: 1985-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2778
Valid CSS Valid XHTML 1.0 Strict