1 /* gensym.c - generate symbol table for assembler */
2 
3 #include "syshead.h"
4 #include "const.h"
5 #include "type.h"
6 #include "flag.h"
7 #include "file.h"
8 #include "globvar.h"
9 
10 FORWARD int printsym P((register struct sym_s *symptr, unsigned column));
11 FORWARD void sort P((struct sym_s **array, struct sym_s **top,
12 		     bool_pt nameflag));
13 
14 /* sort labels in symbol table on name and value */
15 /* if listing, write human-readable table to list file */
16 /* if symbol file, write machine-readable tables to it */
17 /* pointers become relative to start of file */
18 
gensym()19 PUBLIC void gensym()
20 {
21     unsigned column;
22     struct sym_s **copyptr;
23     struct sym_s **copytop;
24     register struct sym_s **hashptr;
25     unsigned label_count;	/* number of labels */
26     unsigned labels_length;	/* length of all label strings */
27     struct sym_s **symlptr;	/* start of symbol output list */
28     register struct sym_s *symptr;
29 #ifdef BINSYM
30     unsigned label_stringptr;	/* offset of label str from start of file */
31 #endif
32     int symcount = 0;
33 
34     labels_length = label_count = 0;
35 
36     /* make copy of all relavant symbol ptrs on heap */
37     /* original ptrs can now be modified, but need to be an array for sort */
38 
39     for (hashptr = spt; hashptr < spt_top;)
40 	if ((symptr = *hashptr++) != NUL_PTR)
41 	    do
42 		if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
43 		   symcount++;
44 	    while ((symptr = symptr->next) != NUL_PTR);
45     symlptr = copyptr = asalloc( sizeof(struct sym_s *) * symcount);
46 
47     for (hashptr = spt; hashptr < spt_top;)
48 	if ((symptr = *hashptr++) != NUL_PTR)
49 	    do
50 		if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
51 		{
52 		    *copyptr++ = symptr;
53 		    ++label_count;
54 		    labels_length += symptr->length + 3; /* 3 for type, value */
55 		}
56 	    while ((symptr = symptr->next) != NUL_PTR);
57 
58     sort(symlptr, copyptr, TRUE);	/* sort on name */
59     copytop = copyptr;
60     if (list.global)
61     {
62 	outfd = lstfil;
63 	writenl();
64 	writesn("Symbols:");
65 	for (copyptr = symlptr, column = 0; copyptr < copytop;)
66 	    column = printsym(*copyptr++, column);
67 	if (column != 0)
68 	    writenl();
69     }
70     if ((outfd = symfil) != 0)
71     {
72 #ifndef BINSYM
73 	for (copyptr = symlptr; copyptr < copytop;)
74 	/* for (copyptr = spt; copyptr < spt_top;) */
75 	{
76 	    int sft;
77 	    if((symptr = *copyptr++) == NUL_PTR ) continue;
78 	    if( globals_only_in_obj &&
79 	       !(symptr->type & EXPBIT)) continue;
80 
81             writec(hexdigit[symptr->data & SEGM]);
82 	    writec(' ');
83 
84 	    for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
85                writec(hexdigit[(symptr->value_reg_or_op.value>>sft) & 0xF]);
86 
87 	    writec(' ');
88             writec(symptr->type & EXPBIT ? 'E' : '-');
89             writec(symptr->type & ENTBIT ? 'N' : '-');
90             writec(symptr->data & IMPBIT ? 'I' : '-');
91             writec(symptr->data & RELBIT ? 'R' : 'A');
92             writec(symptr->type & COMMBIT ? 'C' : '-');
93 
94 	    writec(' ');
95 	    write(outfd, symptr->name, (unsigned) (symptr->length));
96 
97 	    /* printsym(*copyptr++, 0); */
98 	    writenl();
99         }
100 #else
101 	writew(mapnum);
102 	label_count *= 2;	/* now length of ptr table (2 bytes per ptr) */
103 	label_stringptr = label_count + 6;
104 				/* offset to current string in symbol file */
105 				/* 6 is length of header */
106 	labels_length += label_stringptr;
107 	/* offset to ptr table sorted on value */
108 	writew(labels_length + label_count);
109 	/* total length of symbol file */
110 	writew(label_count);
111 	for (copyptr = symlptr; copyptr < copytop;)
112 	{
113 	    symptr = *copyptr++;
114 	    writew((unsigned)
115 		   (symptr->next = (struct sym_s *) label_stringptr));
116 				/* reuse "next" to record string position */
117 	    label_stringptr += symptr->length + 3;
118 	}
119 	for (copyptr = symlptr; copyptr < copytop;)
120 	{
121 	    symptr = *copyptr++;
122 	    writew((unsigned) symptr->value_reg_or_op.value);
123 	    writec(symptr->type);
124 	    write(outfd, symptr->name, (unsigned) (symptr->length - 1));
125 	    writec(symptr->name[symptr->length - 1] | 0x80);
126 	}
127 	sort(symlptr, copyptr, FALSE);
128 	/* sort on value */
129 	for (copyptr = symlptr; copyptr < copytop;)
130 	{
131 	    symptr = *copyptr++;
132 	    writew((unsigned) symptr->next);	/* now has string position */
133 	}
134 #endif
135     }
136 }
137 
138 /* print symbol nicely formatted for given column */
139 
printsym(symptr,column)140 PRIVATE int printsym(symptr, column)
141 register struct sym_s *symptr;
142 unsigned column;
143 {
144     unsigned char length;
145     register struct sym_listing_s *listptr;
146     char *outname;
147     char *symname;
148 
149     listptr = (struct sym_listing_s *) temp_buf();
150     memset((char *) listptr, ' ', SYMLIS_LEN);
151     listptr->nullterm = 0;
152     if ((length = symptr->length) > SYMLIS_NAMELEN)
153     {
154 	outname = listptr->name;
155 	outname[length = SYMLIS_NAMELEN] = '+';
156     }
157     else
158 	outname = listptr->name; /*(listptr->name + SYMLIS_NAMELEN) - length;*/
159     symname = symptr->name;
160     do
161 	*outname++ = *symname++;
162     while (--length != 0);
163     listptr->ar[0] = symptr->data & RELBIT ? 'R' : 'A';
164     listptr->segm[0] = hexdigit[symptr->data & SEGM];
165     if (symptr->type & COMMBIT)
166 	listptr->cein[0] = 'C';
167     else if (symptr->type & ENTBIT)
168 	listptr->cein[0] = 'N';
169     else if (symptr->type & EXPBIT)
170 	listptr->cein[0] = 'E';
171     else if (symptr->data & IMPBIT)
172 	listptr->cein[0] = 'I';
173 #if SIZEOF_OFFSET_T > 2
174     build_2hex_number((unsigned) (symptr->value_reg_or_op.value >> 16),
175 		      listptr->value);
176 #endif
177     build_2hex_number((unsigned) symptr->value_reg_or_op.value,
178 		      listptr->value);
179     writes((char *) listptr);
180     if ((column += SYMLIS_LEN) > (80 - SYMLIS_LEN))
181     {
182 	writenl();
183 	column = 0;
184     }
185     return column;
186 }
187 
188 /* shell sort symbols */
189 
sort(array,top,nameflag)190 PRIVATE void sort(array, top, nameflag)
191 struct sym_s **array;
192 struct sym_s **top;
193 bool_pt nameflag;
194 {
195     int gap;
196     int i;
197     int j;
198     register struct sym_s **left;
199     register struct sym_s **right;
200     int size;
201     struct sym_s *swap;
202 
203     size = top - array;
204     /* choose gaps according to Knuth V3 p95 */
205     for (gap = 1, i = 4; (j = 3 * i + 1) < size; gap = i, i = j)
206 	;
207     do
208     {
209 	for (j = gap; j < size; ++j)
210 	    for (i = j - gap; i >= 0; i -= gap)
211 	    {
212 		left = &array[i];
213 		right = &array[i + gap];
214 		if ((bool_t) nameflag)
215 		{
216 		    if (strcmp((*left)->name, (*right)->name) <= 0)
217 			break;
218 		}
219 		else if ((unsigned) (*left)->value_reg_or_op.value <=
220 			 (*right)->value_reg_or_op.value)
221 		    break;
222 		swap = *left;
223 		*left = *right;
224 		*right = swap;
225 	    }
226     }
227     while ((gap /= 3) != 0);
228 }
229