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