📄 assyms.c
字号:
/*#@(#)assyms.c 4.3 Ultrix 9/4/90*//************************************************************************ * * * Copyright (c) 1984 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * Modification History * * * * * 002 Tanya Klinchina, 20-Nov-1989 * Added support for vector instructions. * * * 001 - Modified stabfix() to work with changes made in asparse.c * * (don't have to shift/mask the offset back out of * * n_desc and n_other fields). Takes advantage of new * * stabtype FORWARDSTAB. * * Also modified sortsymtab(): no longer assign value field * * of a forward-referencing stab for sorting; this is * * unnecessary, and munges the s_value field of the stab * * which might be used to hold an offset later needed in * * stabfix(). * * (Victoria Holt, May 7, 1985) * * * ************************************************************************//* * Copyright (c) 1982 Regents of the University of California */#ifndef lintstatic char sccsid[] = "@(#)assyms.c 4.14 8/11/83";#endif /* not lint */#include <stdio.h>#include <ctype.h>#include "as.h"#include "asscan.h"#include "assyms.h"/* * Managers for chunks of symbols allocated from calloc() * We maintain a linked list of such chunks. * */struct allocbox *allochead; /*head of chunk list*/struct allocbox *alloctail; /*tail*/struct allocbox *newbox; /*for creating a new chunk*/struct symtab *nextsym; /*next symbol free*/int symsleft; /*slots left in current chunk*/struct symtab **symptrs;struct symtab **symdelim[NLOC + NLOC +1];struct symtab **symptrub;/* * Managers for the dynamically extendable hash table */struct hashdallop *htab;Iptr *itab[NINST]; /*maps opcodes to instructions*//* * Counts what went into the symbol table, so that the * size of the symbol table can be computed. */int nsyms; /* total number in the symbol table */int njxxx; /* number of jxxx entrys */int nforgotten; /* number of symbols erroneously entered */int nlabels; /* number of label entries *//* * Managers of the symbol literal storage. */struct strpool *strplhead = 0;symtabinit(){ allochead = 0; alloctail = 0; nextsym = 0; symsleft = 0; strpoolalloc(); /* get the first strpool storage area */ htab = 0; htaballoc(); /* get the first part of the hash table */}/* * Install all known instructions in the symbol table */syminstall(){ register Iptr ip; register struct symtab **hp; register char *p1, *p2; register int i; for (i = 0; i < NINST; i++) itab[i] = (Iptr*)BADPOINT; for (ip = (Iptr)instab; FETCHNAME(ip)[0]; ip++) { p1 = FETCHNAME(ip); p2 = yytext; while (*p2++ = *p1++); hp = lookup(0); /* 0 => don't install this*/ if (*hp==NULL) { *hp = (struct symtab *)ip; if ( (ip->s_tag!=INSTn) && (ip->s_tag!=INST0) && (ip->s_tag!=VINSTn) && (ip->s_tag!=VINST0) && (ip->s_tag!=0)) continue; /* was pseudo-op */ if (itab[ip->i_eopcode] == (Iptr*)BADPOINT){ itab[ip->i_eopcode] = (Iptr*)ClearCalloc(256, sizeof(Iptr)); for (i = 0; i < 256; i++) itab[ip->i_eopcode][i] = (Iptr)BADPOINT; } itab[ip->i_eopcode][ip->i_popcode] = ip; } }} /*end of syminstall*/#define ISLABEL(sp) \ ( (!savelabels) \ && (sp->s_tag == LABELID) \ && (STRPLACE(sp) & STR_CORE) \ && (FETCHNAME(sp)[0] == 'L'))/* * Assign final values to symbols, * and overwrite the index field with its relative position in * the symbol table we give to the loader. */extern struct exec hdr;freezesymtab(){ register struct symtab *sp; long bs; register int relpos = 0; register struct symtab *ubsp; register struct allocbox *allocwalk; DECLITERATE(allocwalk, sp, ubsp) { if (sp->s_tag >= IGNOREBOUND) continue; /*totally ignore jxxx entries */ /* * Ignore stabs, but give them a symbol table index */ if (sp->s_type & STABFLAG) goto assignindex; if ((sp->s_type&XTYPE)==XUNDEF) sp->s_type = XXTRN+XUNDEF; else if ((sp->s_type&XTYPE)==XDATA) sp->s_value += usedot[sp->s_index].e_xvalue; else if ((sp->s_type&XTYPE)==XTEXT) sp->s_value += usedot[sp->s_index].e_xvalue; else if ((sp->s_type&XTYPE)==XBSS) { bs = sp->s_value; sp->s_value = hdr.a_bss + datbase; hdr.a_bss += bs; } assignindex: if (!ISLABEL(sp)) sp->s_index = relpos++; }}/* * For all of the stabs that had their final value undefined * at pass 1, we now assign a final value. * We have already given stab entrys a initial approximation * when we constsructed the sorted symbol table. * Iteration order doesn't matter. */stabfix(){ register struct symtab *sp, **cosp; register struct symtab *p; SYMITERATE(cosp, sp) { if(sp->s_ptype && (sp->s_type & STABFLAG)) { p = sp->s_dest; sp->s_index = p->s_index; sp->s_type = p->s_type; if (sp->s_tag == FORWARDSTAB) { sp->s_value += p->s_value; } else { sp->s_value = p->s_value; } } }}char *Calloc(number, size) int number, size;{ register char *newstuff; char *sbrk(); newstuff = sbrk(number*size); if ((int)newstuff == -1){ yyerror("Ran out of Memory"); delexit(); } return(newstuff);}char *ClearCalloc(number, size) int number, size;{ register char *newstuff; /* r11 */ register int length = number * size; /* r10 */#ifdef lint length = length;#endif /* length */ newstuff = Calloc(number, size); asm("movc5 $0, (r0), $0, r10, (r11)"); return(newstuff);}struct symtab *symalloc(){ if (symsleft == 0){ newbox = (struct allocbox *)ClearCalloc(1,ALLOCQTY); symsleft = SYMDALLOP; nextsym = &newbox->symslots[0]; if (alloctail == 0){ allochead = alloctail = newbox; } else { alloctail->nextalloc = newbox; alloctail = newbox; } } --symsleft; ++nsyms; return(nextsym++);}strpoolalloc(){ register struct strpool *new; new = (struct strpool *)Calloc(1, sizeof (struct strpool)); new->str_nalloc = 0; new->str_next = strplhead; strplhead = new;}symcmp(Pptr, Qptr) struct symtab **Pptr, **Qptr;{ register struct symtab *p = *Pptr; register struct symtab *q = *Qptr; if (p->s_index < q->s_index) return(-1); if (p->s_index > q->s_index) return(1); if (p->s_value < q->s_value) return(-1); if (p->s_value > q->s_value) return(1); /* * Force jxxx entries to virtually preceed labels defined * to follow the jxxxx instruction, so that bumping the * jxxx instruction correctly fixes up the following labels */ if (p->s_tag >= IGNOREBOUND) /*p points to a jxxx*/ return(-1); if (q->s_tag >= IGNOREBOUND) return(1); /* * both are now just plain labels; the relative order doesn't * matter. Both can't be jxxxes, as they would have different * values. */ return(0); } /*end of symcmp*//* * We construct the auxiliary table of pointers, symptrs and * symdelim. * Also assign a segment (s_index) to stabs that previously * addressed a forward reference. */sortsymtab(){ register struct symtab *sp; register struct symtab **cowalk; register struct allocbox *allocwalk; struct symtab *ubsp; int segno; int slotno; int symsin; /*number put into symptrs*/ symptrs = (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs); /* * Allocate one word at the beginning of the symptr array * so that backwards scans through the symptr array will * work correctly while scanning through the zeroth segment */ *symptrs++ = 0; cowalk = symptrs; symsin = 0; DECLITERATE(allocwalk, sp, ubsp) { if (sp->s_ptype && (sp->s_type &STABFLAG)){ sp->s_index = sp->s_dest->s_index; /* No longer assign the address; is not needed */ /* because true value will be assigned in */ /* stabfix(). Sorting of stabs need only be */ /* done by index for this reason (jxxxfix will */ /* not have any effect. */ /* sp->s_value = sp->dest->s_value; */ } if (symsin >= nsyms) yyerror("INTERNAL ERROR: overfilled symbol table indirection table"); *cowalk++ = sp; symsin++; } if (symsin != nsyms) yyerror("INTERNAL ERROR: installed %d syms, should have installed %d", symsin, nsyms); symptrub = &symptrs[nsyms ]; qsort(symptrs, nsyms, sizeof *symptrs, symcmp); symdelim[0] = symptrs; for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1; segno < NLOC + NLOC; segno++, slotno++){ for (; sp && sp->s_index == segno; sp = *++cowalk); symdelim[slotno] = cowalk; /*forms the ub delimeter*/ }} /*end of sortsymtab*/#ifdef DEBUGdumpsymtab(){ register int segno; register struct symtab *sp, **cosp, *ub; char *tagstring(); printf("Symbol Table dump:\n"); for (segno = 0; segno < NLOC + NLOC; segno++){ printf("Segment number: %d\n", segno); SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){ printf("\tSeg: %d \"%s\" value: %d index: %d tag %s\n", segno, FETCHNAME(sp), sp->s_value, sp->s_index, tagstring(sp->s_tag)); printf("\t\ttype: %d jxbump %d jxfear: %d\n", sp->s_type, sp->s_jxbump, sp->s_jxfear); } printf("\n\n"); }}static char tagbuff[4];char *tagstring(tag) unsigned char tag;{ switch(tag){ case JXACTIVE: return("active"); case JXNOTYET: return("notyet");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -