BSD 3 development
[unix-history] / usr / src / cmd / as / assyms.c
CommitLineData
629188b5
JR
1/* Copyright (c) 1979 Regents of the University of California */
2#include <stdio.h>
3#include "as.h"
4#include "assyms.h"
5
6struct allocbox *allochead;
7struct allocbox *alloctail;
8struct symtab *nextsym;
9struct allocbox *newbox;
10char *namebuffer;
11int symsleft;
12
13symtabinit()
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 */
24syminstall()
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 */
52extern struct hdr hdr;
53
54freezesymtab()
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 */
108stabfix() {
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
126char *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
138struct 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
165symcmp(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
204sortsymtab()
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
248dumpsymtab()
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
267static char tagbuff[4];
268
269char *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
295struct 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
356writel(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
368int reflen[] = {0,0,1,1,2,2,4,4,8,8};
369
370/*
371 * Save the relocation information
372 */
373outrel(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
443int 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
460symwrite(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
519Flushfield(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}