Announce SDCC 4.5.0 RC3.
[sdcc.git] / sdcc / sdas / linksrc / lkbank.c
blob43e9c28af515eccda96bcef0c3791f9fdd0545e7
1 /* lkbank.c */
3 /*
4 * Copyright (C) 2001-2009 Alan R. Baldwin
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.
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.
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/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
25 #include "aslink.h"
27 /*Module lkbank.c
29 * The module lkbank.c contains the function newbank() which
30 * creates a bank structure and the function module() which
31 * loads the module name into the current head structure.
33 * lkbank.c contains the following functions:
34 * VOID newbank()
35 * VOID lkpbank()
36 * VOID setbank()
37 * VOID chkbank()
38 * VOID lkfopen()
39 * VOID lkfclose()
41 * lkbank.c contains no local variables.
44 /*)Function VOID newbank()
46 * The function newbank() creates and/or modifies bank
47 * structures for each B directive read from
48 * the .rel file(s). The function lkpbank() is called
49 * to find the bank structure associated with this name.
50 * If the bank does not yet exist then a new bank
51 * structure is created and linked to any existing
52 * linked bank structures. The bank flags are copied
53 * into the bank flag variable. Refer to lkdata.c for
54 * details of the structures and their linkage.
56 * local variables:
57 * bank **hblp pointer to an array of pointers
58 * int i counter, loop variable, value
59 * char id[] id string
60 * int nbank number of banks in this head structure
61 * a_uint v temporary value
63 * global variables:
64 * bank *bp Pointer to the current
65 * bank structure
66 * head *hp Pointer to the current
67 * head structure
68 * int lkerr error flag
70 * functions called:
71 * a_uint eval() lkeval.c
72 * VOID exit() c_library
73 * int fprintf() c_library
74 * VOID getid() lklex.c
75 * VOID lkpbank() lkbank.c
76 * VOID skip() lklex.c
78 * side effects:
79 * The bank structure is created and
80 * linked with the appropriate head structures.
81 * Failure to allocate bank structure
82 * space will terminate the linker. Other internal
83 * errors most likely caused by corrupted .rel
84 * files will also terminate the linker.
88 * Create a bank entry.
90 * B xxxxxx base nnnn size nnnn map nnn flags n fsfx xxxxxx
91 * | | | | | |
92 * | | | | | `-- bp->b_fsfx
93 * | | | | `--------- bp->b_flag
94 * | | | `--------------------bp->b_map
95 * | | `---------------------------- bp->b_size
96 * | `-------------------------------------- bp->b_base
97 * `-------------------------------------------------- bp->b_id
100 VOID
101 newbank(void)
103 int i;
104 a_uint v;
105 char id[NCPS];
106 int nbank;
107 struct bank **hblp;
109 if (headp == NULL) {
110 fprintf(stderr, "No header defined\n");
111 lkexit(ER_FATAL);
114 * Create bank entry
116 getid(id, -1);
117 lkpbank(id);
119 * Evaluate Parameters
121 while (more()) {
122 getid(id, -1);
124 * Evaluate base address
126 if (symeq("base", id, 1)) {
127 v = eval();
128 if (bp->b_base == 0) {
129 bp->b_base = v;
130 } else {
131 if (v && (bp->b_base != v)) {
132 fprintf(stderr, "Conflicting address in bank %s\n", id);
133 lkerr++;
136 } else
138 * Evaluate bank size
140 if (symeq("size", id, 1)) {
141 v = eval();
142 if (bp->b_size == 0) {
143 bp->b_size = v;
144 } else {
145 if (v && (bp->b_size != v)) {
146 fprintf(stderr, "Conflicting size in bank %s\n", id);
147 lkerr++;
150 } else
152 * Evaluate bank mapping
154 if (symeq("map", id, 1)) {
155 v = eval();
156 if (bp->b_map == 0) {
157 bp->b_map = v;
158 } else {
159 if (v && (bp->b_map != v)) {
160 fprintf(stderr, "Conflicting mapping in bank %s\n", id);
161 lkerr++;
164 } else
166 * Evaluate flags
168 if (symeq("flags", id, 1)) {
169 i = (int) eval();
170 if (bp->b_flag == 0) {
171 bp->b_flag = i;
172 } else {
173 if (i && (bp->b_flag != i)) {
174 fprintf(stderr, "Conflicting flags in bank %s\n", id);
175 lkerr++;
178 } else
180 * File Suffix
182 if (symeq("fsfx", id, 1)) {
183 if (more()) {
184 getid(id, -1);
185 if (bp->b_fsfx == NULL) {
186 bp->b_fsfx = strsto(id);
187 } else {
188 if (!symeq(bp->b_fsfx, id, 1)) {
189 fprintf(stderr, "Conflicting fsfx in bank %s\n", id);
190 lkerr++;
197 * Place pointer in header bank list
199 nbank = hp->h_nbank;
200 hblp = hp->b_list;
201 for (i=0; i < nbank; i++) {
202 if (hblp[i] == NULL) {
203 hblp[i] = bp;
204 return;
207 fprintf(stderr, "Header bank list overflow\n");
208 lkexit(ER_FATAL);
211 /*)Function VOID lkpbank(id)
213 * char * id pointer to the bank name string
215 * The function lkpbank() searches the linked bank structures
216 * for a name match. If the name is not found then a bank
217 * structure is created. The linker flag, rtaflg, for initializing
218 * i86 format output is set.
220 * local variables:
221 * area * tbp pointer to a bank structure
223 * global variables:
224 * bank *bp Pointer to the current
225 * bank structure
226 * bank *bankp The pointer to the first
227 * bank structure of a linked list
229 * functions called:
230 * VOID * new() lksym()
231 * char * strsto() lksym.c
232 * int symeq() lksym.c
234 * side effects:
235 * Bank structure may be created.
236 * Failure to allocate space for a structure
237 * will terminate the linker.
240 VOID
241 lkpbank(char *id)
243 struct bank *tbp;
245 bp = bankp;
246 while (bp) {
247 if (symeq(id, bp->b_id, 1)) {
248 return;
250 bp = bp->b_bp;
252 bp = (struct bank *) new (sizeof(struct bank));
253 tbp = bankp;
254 while (tbp->b_bp)
255 tbp = tbp->b_bp;
256 tbp->b_bp = bp;
257 bp->b_id = strsto(id);
258 bp->b_rtaflg = 1;
262 /*)Function VOID setbank()
264 * The function setbank() sets the base address of the bank by
265 * finding the first area in the bank and initializing the
266 * value to the bank base address. The bank base address is always
267 * specified in 'byte' addressing. A first area which is not 'byte'
268 * addressed (e.g. a processor addressed by a 'word' of 2 or more bytes)
269 * has the base address scaled to begin at the 'byte' address.
271 * If the area base address has been set using the -b linker
272 * option then the bank base address is NOT set.
274 * The function setbank() also scans all the areas searching
275 * for non-banked entries. All non-banked areas are linked
276 * to bank[0] which does not have a bank file suffix.
278 * local variables:
279 * a_uint base base address in 'bytes'
280 * int bytes size of PC increment in bytes
282 * global variables:
283 * area *ap Pointer to the current
284 * area structure
285 * area *areap The pointer to the first
286 * area structure of a linked list
287 * bank *bp Pointer to the current
288 * bank structure
289 * bank *bankp The pointer to the first
290 * bank structure of a linked list
292 * functions called:
293 * none
295 * side effects:
296 * Base starting address may be set and non-banked
297 * areas linked to bank[0].
300 VOID
301 setbank(void)
303 a_uint base;
304 int bytes;
307 * For each bank structure with a defined base address value
308 * scan the area structures for the first relocatable area
309 * in the bank and all absolute areas in the bank.
310 * Load the base address value into the area address if the
311 * bank base address has not been overridden by a -b option.
312 * The bank base address is always expressed in 'bytes'.
314 for (bp = bankp; bp != NULL; bp = bp->b_bp) {
315 if ((bp->b_flag & B_BASE) == 0)
316 continue;
317 for (ap = areap; ap != NULL; ap = ap->a_ap) {
318 if (ap->a_bp != bp)
319 continue;
320 if ((ap->a_flag & A4_BNK) != A4_BNK)
321 continue;
322 if (ap->a_bset)
323 continue;
324 bytes = 1 + (ap->a_flag & A4_WLMSK);
325 base = bp->b_base;
326 ap->a_addr = (base/bytes) + ((base % bytes) ? 1 : 0);
327 ap->a_bset = 1;
328 if ((ap->a_flag & A4_ABS) == A4_ABS) {
329 continue;
330 } else {
331 break;
337 * Scan all the area structures for non-banked
338 * areas. Set the area bank pointer to reference
339 * bank[0] which has no file suffix.
341 for (ap = areap; ap != NULL; ap = ap->a_ap) {
342 if ((ap->a_flag & A4_BNK) == 0) {
343 ap->a_bp = bankp;
349 /*)Function VOID chkbank(fp)
351 * FILE *fp file handle
353 * The function chkbank() scans the bank/area structures to
354 * determine the length of a bank. Banks exceeding the size
355 * specified from a bank size option are flagged. The bank
356 * size is always in 'byte' units.
358 * local variables:
359 * a_uint alow lowest address in a bank
360 * a_uint ahigh highest address in a bank
361 * a_uint blimit bank size limit
363 * global variables:
364 * area *ap Pointer to the current
365 * area structure
366 * area *areap The pointer to the first
367 * area structure of a linked list
368 * bank *bp Pointer to the current
369 * bank structure
370 * bank *bankp The pointer to the first
371 * bank structure of a linked list
373 * functions called:
374 * none
376 * side effects:
377 * Bank size may be flagged.
380 VOID
381 chkbank(FILE *fp)
383 a_uint alow, ahigh, blimit, bytes;
385 for (bp = bankp; bp != NULL; bp = bp->b_bp) {
386 if ((bp->b_flag & B_SIZE) == 0) {
387 continue;
389 blimit = bp->b_size;
390 if (blimit == 0) {
391 continue;
393 alow = ~0;
394 ahigh = 0;
395 for (ap = areap; ap != NULL; ap = ap->a_ap) {
396 if (ap->a_bp != bp) {
397 continue;
399 if ((ap->a_flag & A4_BNK) != A4_BNK) {
400 continue;
402 bytes = ap->a_addr * (1 + (ap->a_flag & A4_WLMSK));
403 if (bytes < alow) {
404 alow = bytes;
406 bytes = (ap->a_addr + ap->a_size) * (1 + (ap->a_flag & A4_WLMSK));
407 if (bytes > ahigh) {
408 ahigh = bytes;
411 if ((ahigh - alow) > blimit) {
412 fprintf(fp,
413 "\n?ASlink-Warning-Size limit exceeded in bank %s\n", bp->b_id);
414 lkerr++;
420 /*)Function VOID lkfopen()
422 * The function lkfopen() scans the bank/area structures to
423 * open output data files for banks with any data. Files
424 * are not opened for banks/areas with no output data.
426 * The bank structures are first scanned to create the
427 * file specification from the output file name combined
428 * with any given file suffixs.
430 * local variables:
431 * int idx position of FSEPX in file specification
432 * File * fp temporary file handle
433 * char * frmt temporary file type string
434 * char str[] File Specification String
435 * struct bank *tbp temporary bank pointer
438 * global variables:
439 * int a_bytes T line address bytes
440 * area *ap Pointer to the current
441 * area structure
442 * area *areap The pointer to the first
443 * area structure of a linked list
444 * char afspec[] Filespec from afile()
445 * bank *bp Pointer to the current
446 * bank structure
447 * bank *bankp The pointer to the first
448 * bank structure of a linked list
449 * FILE * jfp NoICE output file handle
450 * int oflag data output type flag
451 * FILE * stderr Standard Error Output handle
453 * functions called:
454 * FILE * afile() lkmain.c
455 * int fclose() c_library
456 * int fprintf() c_library
457 * VOID lkexit() lkmain.c
458 * char * strcpy() c_library
459 * char * strsto() lksym.c
460 * char * symeq() lksym.c
462 * side effects:
463 * All data output files are opened.
466 VOID
467 lkfopen(void)
469 int idx;
470 char * frmt;
471 char str[NCPS+NCPS];
472 struct bank *tbp;
473 struct sym *sp;
474 FILE * fp;
476 if (oflag == 0) return;
479 * Scan bank structures preparing
480 * the output file specifications.
482 idx = linkp->f_idx + fndext(linkp->f_idp + linkp->f_idx);
483 strncpy(str, linkp->f_idp, idx);
484 str[idx] = 0;
486 for (bp = bankp; bp != NULL; bp = bp->b_bp) {
487 if (bp->b_flag & B_FSFX) {
488 strcpy(str + idx, bp->b_fsfx);
490 bp->b_fspec = strsto(str);
491 str[idx] = 0;
495 * If .__.END. is defined force
496 * an output file to be opened.
498 sp = lkpsym(".__.END.", 0);
499 if (sp) {
500 sp->s_axp->a_bap->a_flag |= A4_OUT;
504 * Scan the area list opening the appropriate
505 * output file if there is data in the area.
507 ap = areap;
508 while (ap) {
509 if ((ap->a_flag & A4_BNK) != A4_BNK) {
510 ap->a_bp = bankp;
512 if ((ap->a_flag & A4_OUT) || (ap->a_size != 0)) {
513 bp = ap->a_bp;
514 if (bp->b_ofp == NULL) {
516 * Scan file specifications for
517 * identical file already opened.
519 for (tbp = bankp; tbp != NULL; tbp = tbp->b_bp) {
520 if (symeq(tbp->b_fspec, bp->b_fspec, 1)) {
521 if (tbp->b_ofp != NULL) {
522 bp->b_ofp = tbp->b_ofp;
523 bp->b_ofspec = tbp->b_ofspec;
528 if (bp->b_ofp == NULL) {
529 char *fpt;
530 fp = stderr;
532 * Open output file
534 if (oflag == 1) {
535 switch(a_bytes) {
536 default:
537 case 2: frmt = "ihx"; break;
539 fpt = strsto(bp->b_fspec);
540 strcat(fpt, ".ihx");
541 fp = afile(fpt, frmt, 1);
542 } else
543 if (oflag == 2) {
544 switch(a_bytes) {
545 default:
546 case 2: frmt = "s19"; break;
548 fpt = strsto(bp->b_fspec);
549 strcat(fpt, ".s19");
550 fp = afile(fpt, frmt, 1);
551 } else
552 if (oflag == 3) {
553 switch(a_bytes) {
554 default:
555 case 2: frmt = "bin"; break;
556 case 3: frmt = "bi3"; break;
557 case 4: frmt = "bi4"; break;
559 fpt = strsto(bp->b_fspec);
560 strcat(fpt, ".");
561 strcat(fpt, frmt);
562 fp = afile(fpt, frmt, 2);
563 } else
564 /* sdld specific */
565 if (oflag == 4) {
566 fpt = strsto(bp->b_fspec);
567 strcat(fpt, ".elf");
568 fp = afile(fpt, "elf", 2);
570 /* end sdld specific */
571 if (fp != stderr) {
572 if (fp == NULL) {
573 lkexit(ER_FATAL);
575 bp->b_ofspec = strsto(afspec);
576 #if NOICE
578 * Include NoICE command to load file
580 if (jfp) {
581 fprintf(jfp, "LOAD %s\n", bp->b_ofspec);
583 #endif
585 bp->b_ofp = fp;
587 ap->a_ofp = bp->b_ofp;
588 } else {
589 ap->a_ofp = NULL;
591 ap = ap->a_ap;
596 /*)Function VOID lkfclose()
598 * The function lkfclose() scans the bank structures to
599 * close all open data output files.
601 * local variables:
602 * struct bank *tbp temporary bank pointer
604 * global variables:
605 * bank *bp Pointer to the current
606 * bank structure
607 * bank *bankp The pointer to the first
608 * bank structure of a linked list
609 * FILE * ofp Output file handle
610 * FILE * stderr Standard Error Output handle
612 * functions called:
613 * VOID lkout() lkout.c
614 * int fclose() c_library
616 * side effects:
617 * All open data output files are closed.
620 VOID
621 lkfclose(void)
623 struct bank *tbp;
626 * Scan Bank Structure
627 * Output data terminations
628 * and close open files
630 bp = bankp;
631 while (bp != NULL) {
632 ofp = bp->b_ofp;
633 if (ofp != NULL) {
634 lkout(0);
635 if (ofp != stderr) {
636 fclose(ofp);
639 * Scan bank structure for
640 * identical file handles.
642 for (tbp = bp->b_bp; tbp != NULL; tbp = tbp->b_bp) {
643 if (tbp->b_ofp == ofp) {
644 tbp->b_ofp = NULL;
647 ofp = NULL;
648 bp->b_ofp = NULL;
650 bp = bp->b_bp;