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