|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #include <stdio.h>
3: #include "as.h"
4: #include "assyms.h"
5:
6: struct allocbox *allochead;
7: struct allocbox *alloctail;
8: struct symtab *nextsym;
9: struct allocbox *newbox;
10: char *namebuffer;
11: int symsleft;
12:
13: symtabinit()
14: {
15: allochead = 0;
16: alloctail = 0;
17: nextsym = 0;
18: symsleft = 0;
19: }
20:
21: /*
22: * Install all known instructions in the symbol table
23: */
24: syminstall()
25: {
26: register struct instab *ip;
27: register struct symtab **hp;
28: register char *p1, *p2;
29:
30: for (ip=instab; ip->name[0]!=0; ip++) {
31: p1 = ip->name;
32: p2 = yytext;
33: while (*p2++ = *p1++);
34: hp = lookup(0); /* 0 => don't install this*/
35: if (*hp==NULL) {
36: *hp = (struct symtab *)ip;
37: if ( (ip->tag!=INSTn)
38: && (ip->tag!=INST0)
39: && (ip->tag!=0))
40: continue; /* was pseudo-op */
41: itab[ip->opcode & 0xFF] = ip;
42: }
43: }
44: } /*end of syminstall*/
45:
46:
47: /*
48: * Assign final values to symbols,
49: * and overwrite the index field with its relative position in
50: * the symbol table we give to the loader.
51: */
52: extern struct hdr hdr;
53:
54: freezesymtab()
55: {
56: register struct symtab *sp;
57: long bs;
58: register int relpos = 0;
59: #ifdef SORTEDOUTPUT
60: register struct symtab **cosp;
61: #else
62: register struct symtab *ubsp;
63: register struct allocbox *allocwalk;
64: #endif
65:
66: #ifdef SORTEDOUTPUT
67: SYMITERATE(cosp, sp)
68: #else
69: DECLITERATE(allocwalk, sp, ubsp)
70: #endif
71: {
72: if (sp->tag >= IGNOREBOUND)
73: continue; /*totally ignore jxxx entries */
74: /*
75: * Ignore stabs, but give them a symbol table index
76: */
77: if (sp->type & STABFLAG)
78: goto assignindex;
79: if ((sp->type&XTYPE)==XUNDEF)
80: sp->type = XXTRN+XUNDEF;
81: else if ((sp->type&XTYPE)==XDATA)
82: sp->value += usedot[sp->index].xvalue;
83: else if ((sp->type&XTYPE)==XTEXT)
84: sp->value += usedot[sp->index].xvalue;
85: else if ((sp->type&XTYPE)==XBSS) {
86: bs = sp->value;
87: sp->value = hdr.bsize + datbase;
88: hdr.bsize += bs;
89: }
90: assignindex:
91: if ( (sp->name[0] != 'L')
92: || (sp->tag != LABELID)
93: || savelabels
94: ) /*then, we will write it later on*/
95: sp->index = relpos++;
96: }
97: }
98:
99:
100:
101: /*
102: * For all of the stabs that had their final value undefined during pass 1
103: * and during pass 2 assign a final value.
104: * We have already given stab entrys a initial approximation
105: * when we constsructed the sorted symbol table.
106: * Iteration order doesn't matter.
107: */
108: stabfix() {
109: register struct symtab *sp, **cosp;
110: register struct symtab *p;
111:
112: SYMITERATE(cosp, sp){
113: if(sp->ptype && (sp->type & STABFLAG)) {
114: p = sp->dest;
115: sp->value = p->value;
116: sp->index = p->index;
117: sp->type = p->type;
118: #ifdef DSTAB
119: printf("STABFIX: %s (old %s) to %d offsets %d %d\n",
120: sp->name, p->name, sp->value, sp, p);
121: #endif
122: }
123: }
124: }
125:
126: char *Calloc(number, size)
127: int number, size;
128: {
129: register char *newstuff;
130: newstuff = (char *)sbrk(number*size);
131: if ((int)newstuff == -1){
132: yyerror("Ran out of Memory");
133: delexit();
134: }
135: return(newstuff);
136: }
137:
138: struct symtab * symalloc()
139: {
140: if (symsleft == 0){
141: register int *p;
142:
143: newbox = (struct allocbox *)Calloc(1,ALLOCQTY);
144: symsleft = SYMDALLOP;
145: nextsym = &newbox->symslots[0];
146: namebuffer = &newbox->symnames[0];
147: p = (int *)(&newbox->symnames[SYMDALLOP * NCPS]);
148: while ( p > (int *)newbox){
149: *--p = 0;
150: }
151: if (alloctail == 0){
152: allochead = alloctail = newbox;
153: } else {
154: alloctail->nextalloc = newbox;
155: alloctail = newbox;
156: }
157: }
158: --symsleft;
159: ++nsyms;
160: nextsym->name = namebuffer;
161: namebuffer += NCPS;
162: return(nextsym++);
163: }
164:
165: symcmp(pptr, qptr)
166: struct symtab **pptr, **qptr;
167: {
168: register struct symtab *p = *pptr;
169: register struct symtab *q = *qptr;
170: if (p->index < q->index)
171: return(-1);
172: if (p->index > q->index)
173: return(1);
174: if (p->value < q->value)
175: return(-1);
176: if (p->value > q->value)
177: return(1);
178: /*
179: * Force jxxx entries to virtually preceed labels defined
180: * to follow the jxxxx instruction, so that bumping the
181: * jxxx instruction correctly fixes up the following labels
182: */
183: if (p->tag >= IGNOREBOUND) /*p points to a jxxx*/
184: return(-1);
185: if (q->tag >= IGNOREBOUND)
186: return(1);
187: /*
188: * both are now just plain labels; the relative order doesn't
189: * matter. Both can't be jxxxes, as they would have different
190: * values.
191: */
192: return(0);
193: } /*end of symcmp*/
194:
195: /*
196: * We construct the auxiliary table of pointers, symptrs and
197: * symdelim
198: * We also assign preliminary values to stab entries that did not yet
199: * have an absolute value (because they initially referred to
200: * forward references). We don't worry about .stabds, as they
201: * already have an estimated final value
202: */
203:
204: sortsymtab()
205: {
206: register struct symtab *sp;
207: register struct symtab **cowalk;
208: register struct allocbox *allocwalk;
209: struct symtab *ubsp;
210: int segno;
211: int slotno;
212: int symsin; /*number put into symptrs*/
213:
214: symptrs = (struct symtab **)Calloc(nsyms + 2, sizeof *symptrs);
215: /*
216: * Allocate one word at the beginning of the symptr array
217: * so that backwards scans through the symptr array will
218: * work correctly while scanning through the zeroth segment
219: */
220: *symptrs++ = 0;
221: cowalk = symptrs;
222: symsin = 0;
223: DECLITERATE(allocwalk, sp, ubsp) {
224: if (sp->ptype && (sp->type &STABFLAG)){
225: sp->value = sp->dest->value;
226: sp->index = sp->dest->index;
227: }
228: if (symsin >= nsyms)
229: yyerror("INTERNAL ERROR: overfilled symbol table indirection table");
230: *cowalk++ = sp;
231: symsin++;
232: }
233: if (symsin != nsyms)
234: yyerror("INTERNAL ERROR: installed %d syms, should have installed %d",
235: symsin, nsyms);
236: symptrub = &symptrs[nsyms ];
237: qsort(symptrs, nsyms, sizeof *symptrs, symcmp);
238: symdelim[0] = symptrs;
239: for (cowalk = symptrs, sp = *cowalk, segno = 0, slotno = 1;
240: segno < NLOC + NLOC;
241: segno++, slotno++){
242: for (; sp && sp->index == segno; sp = *++cowalk);
243: symdelim[slotno] = cowalk; /*forms the ub delimeter*/
244: }
245: } /*end of sortsymtab*/
246:
247: #ifdef DEBUG
248: dumpsymtab()
249: {
250: register int segno;
251: register struct symtab *sp, **cosp, *ub;
252: char *tagstring();
253:
254: printf("Symbol Table dump:\n");
255: for (segno = 0; segno < NLOC + NLOC; segno++){
256: printf("Segment number: %d\n", segno);
257: SEGITERATE(segno, 0, 0, cosp, sp, ub, ++){
258: printf("\tSeg: %d \"%8.8s\" value: %d index: %d tag %s\n",
259: segno, sp->name, sp->value, sp->index, tagstring(sp->tag));
260: printf("\t\ttype: %d jxbump %d jxfear: %d\n",
261: sp->type, sp->jxbump, sp->jxfear);
262: }
263: printf("\n\n");
264: }
265: }
266:
267: static char tagbuff[4];
268:
269: char *tagstring(tag)
270: unsigned char tag;
271: {
272: switch(tag){
273: case JXACTIVE: return("active");
274: case JXNOTYET: return("notyet");
275: case JXALIGN: return("align");
276: case JXQUESTIONABLE: return("jxquestionable");
277: case JXINACTIVE: return("inactive");
278: case JXTUNNEL: return("tunnel");
279: case OBSOLETE: return("obsolete");
280: case IGNOREBOUND: return("ignorebound");
281: case STABFLOATING: return("stabfloating");
282: case STABFIXED: return("stabfixed");
283: case LABELID: return("labelid");
284: case OKTOBUMP: return("oktobump");
285: case ISET: return("iset");
286: case ILSYM: return("ilsym");
287: default: sprintf(tagbuff,"%d", tag);
288: return(tagbuff);
289: }
290: }
291: #endif
292:
293: #define HASHCLOGGED (NHASH * 3 ) / 4
294:
295: struct symtab **lookup(instflg)
296: int instflg; /* 0: don't install */
297: {
298: register int ihash;
299: register struct symtab **hp;
300: register char *p1, *p2;
301: register int i;
302:
303: #ifdef METRIC
304: nhashed++;
305: #endif
306:
307: /*
308: * All strings passed in in yytext had better have
309: * a trailing null. Strings are placed in yytext for
310: * hashing by syminstall() and yylex()
311: */
312: for (ihash = 0, p1 = yytext ; *p1; ihash <<= 2, ihash += *p1++);
313: ihash += p1[-1] << 5;
314: ihash %= NHASH;
315: if (ihash < 0) ihash += NHASH;
316: hp = &hshtab[ihash];
317: ihash = 1; /*now, it counts the number of times we rehash*/
318: while (*hp) {
319: p1 = yytext;
320: p2 = (*hp)->name;
321: for (i = 0; (i<NCPS) && *p1; i++)
322: if (*p1++ != *p2++)
323: goto no;
324: if (i >= NCPS) /*both symbols are maximal length*/
325: return(hp);
326: if (*p2 == 0) /*assert *p1 == 0*/
327: return(hp);
328: no:
329: #ifdef METRIC
330: nhcollisions++;
331: #endif
332: hp += ihash;
333: ihash += 2;
334: if (hp >= &hshtab[NHASH])
335: hp -= NHASH;
336: }
337: if(++hshused >= HASHCLOGGED) {
338: yyerror("Symbol table overflow");
339: delexit();
340: }
341: if (instflg) {
342: #ifdef METRIC
343: nentered++;
344: #endif
345: *hp = symalloc();
346: p1 = yytext;
347: p2 = (*hp)->name;
348: while (*p2++ = *p1++);
349: }
350: return(hp);
351: } /*end of symlook*/
352:
353: #ifdef vax
354: #define writel(p,n,f) fwrite((long)p, sizeof (long), n, f)
355: #else
356: writel(p,n,f)
357: long *p;
358: FILE *f;
359: {
360: while (n--) {
361: fwrite(&(*p).loword,2,1,f);
362: fwrite(&(*p).hiword,2,1,f);
363: p++;
364: }
365: }
366: #endif
367:
368: int reflen[] = {0,0,1,1,2,2,4,4,8,8};
369:
370: /*
371: * Save the relocation information
372: */
373: outrel(pval,reftype,reltype,xsym)
374: long *pval;
375: register int reftype,reltype;
376: struct symtab *xsym;
377: {
378:
379: /*
380: * reftype: PCREL or not, plus length LEN1, LEN2, LEN4, LEN8
381: * reltype: csect ("segment") number (XTEXT, XDATA, ...) associated with 'val'
382: * xsym: symbol table pointer
383: */
384: long ts;
385: char tc;
386: long tl;
387: short t;
388: if (passno!=2) {
389: dotp->xvalue += reflen[reftype];
390: return;
391: }
392: if (bitoff&07)
393: yyerror("Padding error");
394: reltype &= ~XFORW;
395: if (reltype == XUNDEF)
396: yyerror("Undefined reference");
397: if (reltype != XABS || reftype & PCREL) {
398: /* write the address portion of a relocation datum */
399: if (dotp >= &usedot[NLOC]) {
400: hdr.drsize += sizeof(dotp->xvalue) + 3 + sizeof tc;
401: tl = dotp->xvalue-datbase;
402: writel(&tl,1,relfil);
403: } else {
404: hdr.trsize += sizeof(dotp->xvalue) + 3 + sizeof tc;
405: writel(&dotp->xvalue,1,relfil);
406: }
407: /* write the properties portion of a relocation datum */
408: if (reltype == XXTRN+XUNDEF) {
409: ts = (xsym->index);
410: tc = (XXTRN<<3) | (reftype-LEN1);
411: } else if ((reltype&XTYPE) == XUNDEFO) {
412: ts = (xsym->index);
413: tc = ((XXTRN+2)<<3) | (reftype-LEN1);
414: } else {
415: ts = (reltype);
416: tc = (reftype-LEN1);
417: }
418: fwrite((char *)&ts, 3, 1, relfil);
419: fwrite(&tc, sizeof(tc), 1, relfil);
420: }
421: /* write the raw ("unrelocated") value to the text file */
422: t = reflen[reftype];
423: dotp->xvalue += t;
424: if (reftype & PCREL)
425: *pval -= dotp->xvalue;
426: #ifdef vax
427: fwrite(pval,1,t,txtfil);
428: #else
429: if (t>2) {
430: fwrite(&((*pval).loword),1,2,txtfil);
431: fwrite(&((*pval).hiword),1,t-2,txtfil);
432: } else fwrite(&((*pval).loword),1,t,txtfil);
433: #endif
434: }
435:
436:
437: /*
438: * Write out n symbols to file f, beginning at p
439: * ignoring symbols that are obsolete, jxxx instructions, and
440: * possibly, labels
441: */
442:
443: int sizesymtab()
444: {
445: struct symtab *sp;
446:
447: #define NOUTSYMS (nsyms - njxxx - nforgotten - (savelabels ? 0 : nlabels))
448:
449: return (
450: ( NCPS
451: + sizeof (sp->ptype)
452: + sizeof (sp->other)
453: + sizeof (sp->desc)
454: + sizeof (sp->value)
455: )
456: * NOUTSYMS
457: );
458: }
459:
460: symwrite(f)
461: FILE *f;
462: {
463: int symsout; /*those actually written*/
464: int symsdesired = NOUTSYMS;
465: register struct symtab *sp, *ub;
466: #ifdef SORTEDOUTPUT
467: int segno;
468: register struct symtab **copointer;
469: #else
470: register struct allocbox *allocwalk;
471: #endif
472:
473: #ifdef SORTEDOUTPUT
474: for (segno = 0, symsout = 0; segno < NLOC + NLOC; segno++)
475: SEGITERATE(segno, 0, 0, copointer, sp, ub, ++)
476: #else
477: symsout = 0;
478: DECLITERATE(allocwalk, sp, ub)
479: #endif
480: {
481: if (sp->tag >= IGNOREBOUND)
482: continue;
483: if ((sp->name[0] == 'L') && (sp->tag == LABELID) && !savelabels)
484: continue;
485: symsout++;
486: fwrite(sp->name, NCPS, 1, f);
487: sp->type &= ~XFORW;
488: fwrite((sp->ptype) ? (char *)(&(sp->ptype)) : (char *)(&(sp->type)),
489: sizeof(char), 1, f);
490: /*
491: * WATCH OUT. THIS DEPENDS THAT THE ALLOCATION OF
492: * the four fields ptype, other, desc and value are
493: * contiguous. This may have to be changed!
494: * This is safe (as of 2-Nov-79).
495: */
496: fwrite(&(sp->other),
497: sizeof (sp->other)
498: + sizeof (sp->desc)
499: + sizeof (sp->value), 1, f
500: );
501: #ifdef fooie
502: #ifdef vax
503: fwrite(&(sp->name[0]), sizeof(symtab[0].name), 1, f);
504: fwrite(sp->ptype ? &(sp->ptype) : &(sp->type),
505: sizeof(symtab[0].type), 1, f);
506: fwrite(&(sp->other), sizeof(symtab[0].other), 1, f);
507: fwrite(&(sp->desc), sizeof(symtab[0].desc), 1, f);
508: fwrite(&(sp->value), sizeof(symtab[0].value), 1, f);
509: #else
510: writel(&(p->value), 1, f);
511: #endif
512: #endif
513: }
514: if (symsout != symsdesired)
515: yyerror("INTERNAL ERROR: Wrote %d symbols, wanted to write %d symbols\n",
516: symsout, symsdesired);
517: }
518:
519: Flushfield(n)
520: register int n;
521: {
522: while (n>0) {
523: outb(bitfield);
524: bitfield >>= 8;
525: n -= 8;
526: }
527: bitoff=0;
528: bitfield=0;
529: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.