1 /* lkhead.c */
2
3 /*
4 * Copyright (C) 1989-2009 Alan R. Baldwin
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 *
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
23 */
24
25 #include "aslink.h"
26
27 /*Module lkhead.c
28 *
29 * The module lkhead.c contains the function newhead() which
30 * creates a head structure, the function module() which
31 * loads the module name into the current head structure,
32 * and newmode() which loads the linker merge modes.
33 *
34 * lkhead.c contains the following functions:
35 * VOID newhead()
36 * VOID newmode()
37 * VOID module()
38 *
39 * lkhead.c contains no local variables.
40 */
41
42 /*)Function VOID newhead()
43 *
44 * The function newhead() creates a head structure. All head
45 * structures are linked to form a linked list of head structures
46 * with the current head structure at the tail of the list.
47 *
48 * local variables:
49 * int i evaluation value
50 * char id[] temporary string
51 * head * thp temporary pointer
52 * to a header structure
53 *
54 * global variables:
55 * area *ap Pointer to the current
56 * area structure
57 * lfile *cfp The pointer *cfp points to the
58 * current lfile structure
59 * head *headp The pointer to the first
60 * head structure of a linked list
61 * head *hp Pointer to the current
62 * head structure
63 *
64 * functions called:
65 * a_uint expr() lkeval.c
66 * a_uint eval() lkeval.c
67 * VOID getid() lklex.c
68 * VOID * new() lksym.c
69 * VOID lkparea() lkarea.c
70 * int more() lklex.c
71 * int symeq() lksym.c
72 *
73 * side effects:
74 * A new head structure is created and linked to any
75 * existing linked head structure. The head structure
76 * parameters of file handle, number of areas, number
77 * of global symbols, number of banks and number of
78 * merge modes are loaded into the structure. The
79 * area, bank, symbol, and mode structure lists are created.
80 * The default area "_abs_" is created when the first
81 * head structure is created and an areax structure is
82 * created for every head structure called.
83 */
84
85 /*
86 * Create a new header entry.
87 *
88 * H n areas n global symbols n banks n modes
89 * | | | |
90 * | | | `----- G Lines
91 * | | `------------- B Lines
92 * | `------------------------------ hp->h_nsym
93 * `-------------------------------------- hp->h_narea
94 *
95 */
96 VOID
newhead()97 newhead()
98 {
99 int i;
100 char id[NCPS];
101 struct head *thp;
102
103 hp = (struct head *) new (sizeof(struct head));
104 if (headp == NULL) {
105 headp = hp;
106 } else {
107 thp = headp;
108 while (thp->h_hp)
109 thp = thp->h_hp;
110 thp->h_hp = hp;
111 }
112 /*
113 * Initialize the header
114 */
115 hp->h_lfile = cfp; /* Set file pointer */
116 hp->m_id = ""; /* No Module */
117 /*
118 * Scan for Parameters
119 */
120 while (more()) {
121 i = (int) eval();
122 getid(id, -1);
123 /*
124 * Area pointer list
125 */
126 if (symeq("areas", id, 1)) {
127 hp->h_narea = i;
128 if (i)
129 hp->a_list = (struct areax **) new (i*sizeof(struct areax *));
130 } else
131 /*
132 * Symbol pointer list
133 */
134 if (symeq("global", id, 1)) {
135 hp->h_nsym = i;
136 if (i)
137 hp->s_list = (struct sym **) new (i*sizeof(struct sym *));
138 skip(-1);
139 } else
140 /*
141 * Bank pointer list
142 */
143 if (symeq("banks", id, 1)) {
144 hp->h_nbank = i;
145 if (i)
146 hp->b_list = (struct bank **) new (i*sizeof(struct bank *));
147 } else
148 /*
149 * Mode pointer list
150 */
151 if (symeq("modes", id, 1)) {
152 hp->h_nmode = i;
153 if (i)
154 hp->m_list = (struct mode **) new (i*sizeof(struct mode *));
155 }
156 }
157 /*
158 * Setup Absolute DEF linkage.
159 */
160 lkparea(_abs_);
161 ap->a_flag = A3_ABS;
162 axp->a_addr = 0;
163 }
164
165
166 /*)Function VOID newmode()
167 *
168 * The function newmode() creates / fills in a merge mode
169 * definition for this module.
170 *
171 * The MODE structure contains the specification of one of the
172 * assemblers' relocation modes. Each assembler must specify
173 * at least one relocation mode. The relocation specification
174 * allows arbitrarily defined active bits and bit positions.
175 * The 32 element arrays are indexed from 0 to 31.
176 * Index 0 corresponds to bit 0, ..., and 31 corresponds to bit 31
177 * of a normal integer value.
178 *
179 * The value an array element defines if the normal integer bit is
180 * active (bit <7> is set, 0x80) and what destination bit
181 * (bits <4:0>, 0 - 31) should be loaded with this normal
182 * integer bit.
183 *
184 * The mode structure also contains a flag indicating if bit
185 * positioning is required, a mask word containing the active
186 * bits for merging, and an address paging mask.
187 *
188 * local variables:
189 * int index bit index of mode definition
190 * int n counter
191 * struct mode *mp pointer to a mode structure
192 *
193 * global variables:
194 * head *headp The pointer to the first
195 * head structure of a linked list
196 * head *hp Pointer to the current
197 * head structure
198 * FILE * stderr standard library error handle
199 *
200 * functions called:
201 * a_uint eval() lkexpr.c
202 * int fprintf() c_library
203 * VOID lkexit() lkmain.c
204 * int more() lklex.c
205 * char * new() lksym.c
206 *
207 * side effects:
208 * The merge mode structure is created / updated with
209 * the definition values.
210 */
211
212 VOID
newmode()213 newmode()
214 {
215 int index, n;
216 a_uint v;
217 struct mode *mp;
218
219 if (headp == NULL) {
220 fprintf(stderr, "No header defined\n");
221 lkexit(ER_FATAL);
222 }
223 /*
224 * Mode number
225 */
226 n = (int) eval();
227 if (n >= hp->h_nmode) {
228 fprintf(stderr, "Header mode list overflow\n");
229 lkexit(ER_FATAL);
230 }
231 /*
232 * Bit index
233 */
234 index = (int) eval();
235 if (index == 0) {
236 mp = (struct mode *) new (sizeof(struct mode));
237 hp->m_list[n] = mp;
238 /*
239 * Initialize Mode
240 */
241 for (n=0; n<32; n++) {
242 mp->m_def[n] = n;
243 }
244 } else {
245 mp = hp->m_list[n];
246 }
247 /*
248 * Load Bits
249 */
250 while (more() && (index < 32)) {
251 n = (int) eval();
252 if (mp->m_def[index] != (n & 0x1F)) {
253 mp->m_flag |= 1;
254 }
255 mp->m_def[index] = n;
256 if (n & 0x80) {
257 mp->m_dbits |= (((a_uint) 1) << (n & 0x1F));
258 mp->m_sbits |= (((a_uint) 1) << index);
259 }
260 index += 1;
261 }
262 /*
263 * Set Missing Low Order Bits
264 */
265 for (n=0; n<32; n++) {
266 v = 1 << n;
267 if (mp->m_sbits & v) {
268 break;
269 } else {
270 mp->m_sbits |= v;
271 }
272 }
273 }
274
275
276 /*)Function VOID module()
277 *
278 * The function module() copies the module name into
279 * the current head structure.
280 *
281 * local variables:
282 * char id[] module id string
283 *
284 * global variables:
285 * head *headp The pointer to the first
286 * head structure of a linked list
287 * head *hp Pointer to the current
288 * head structure
289 * int lkerr error flag
290 * FILE * stderr c_library
291 *
292 * functions called:
293 * int fprintf() c_library
294 * VOID getid() lklex.c
295 * char * strsto() lksym.c
296 *
297 * side effects:
298 * The module name is copied into the head structure.
299 */
300
301 VOID
module()302 module()
303 {
304 char id[NCPS];
305
306 if (headp) {
307 getid(id, -1);
308 hp->m_id = strsto(id);
309 } else {
310 fprintf(stderr, "No header defined\n");
311 lkerr++;
312 }
313 }
314