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/>.
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:
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.
57 * bank **hblp pointer to an array of pointers
58 * int i counter, loop variable, value
60 * int nbank number of banks in this head structure
61 * a_uint v temporary value
64 * bank *bp Pointer to the current
66 * head *hp Pointer to the current
68 * int lkerr error flag
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
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
92 * | | | | | `-- bp->b_fsfx
93 * | | | | `--------- bp->b_flag
94 * | | | `--------------------bp->b_map
95 * | | `---------------------------- bp->b_size
96 * | `-------------------------------------- bp->b_base
97 * `-------------------------------------------------- bp->b_id
110 fprintf(stderr
, "No header defined\n");
119 * Evaluate Parameters
124 * Evaluate base address
126 if (symeq("base", id
, 1)) {
128 if (bp
->b_base
== 0) {
131 if (v
&& (bp
->b_base
!= v
)) {
132 fprintf(stderr
, "Conflicting address in bank %s\n", id
);
140 if (symeq("size", id
, 1)) {
142 if (bp
->b_size
== 0) {
145 if (v
&& (bp
->b_size
!= v
)) {
146 fprintf(stderr
, "Conflicting size in bank %s\n", id
);
152 * Evaluate bank mapping
154 if (symeq("map", id
, 1)) {
156 if (bp
->b_map
== 0) {
159 if (v
&& (bp
->b_map
!= v
)) {
160 fprintf(stderr
, "Conflicting mapping in bank %s\n", id
);
168 if (symeq("flags", id
, 1)) {
170 if (bp
->b_flag
== 0) {
173 if (i
&& (bp
->b_flag
!= i
)) {
174 fprintf(stderr
, "Conflicting flags in bank %s\n", id
);
182 if (symeq("fsfx", id
, 1)) {
185 if (bp
->b_fsfx
== NULL
) {
186 bp
->b_fsfx
= strsto(id
);
188 if (!symeq(bp
->b_fsfx
, id
, 1)) {
189 fprintf(stderr
, "Conflicting fsfx in bank %s\n", id
);
197 * Place pointer in header bank list
201 for (i
=0; i
< nbank
; i
++) {
202 if (hblp
[i
] == NULL
) {
207 fprintf(stderr
, "Header bank list overflow\n");
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.
221 * area * tbp pointer to a bank structure
224 * bank *bp Pointer to the current
226 * bank *bankp The pointer to the first
227 * bank structure of a linked list
230 * VOID * new() lksym()
231 * char * strsto() lksym.c
232 * int symeq() lksym.c
235 * Bank structure may be created.
236 * Failure to allocate space for a structure
237 * will terminate the linker.
247 if (symeq(id
, bp
->b_id
, 1)) {
252 bp
= (struct bank
*) new (sizeof(struct bank
));
257 bp
->b_id
= strsto(id
);
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.
279 * a_uint base base address in 'bytes'
280 * int bytes size of PC increment in bytes
283 * area *ap Pointer to the current
285 * area *areap The pointer to the first
286 * area structure of a linked list
287 * bank *bp Pointer to the current
289 * bank *bankp The pointer to the first
290 * bank structure of a linked list
296 * Base starting address may be set and non-banked
297 * areas linked to bank[0].
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)
317 for (ap
= areap
; ap
!= NULL
; ap
= ap
->a_ap
) {
320 if ((ap
->a_flag
& A4_BNK
) != A4_BNK
)
324 bytes
= 1 + (ap
->a_flag
& A4_WLMSK
);
326 ap
->a_addr
= (base
/bytes
) + ((base
% bytes
) ? 1 : 0);
328 if ((ap
->a_flag
& A4_ABS
) == A4_ABS
) {
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) {
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.
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
364 * area *ap Pointer to the current
366 * area *areap The pointer to the first
367 * area structure of a linked list
368 * bank *bp Pointer to the current
370 * bank *bankp The pointer to the first
371 * bank structure of a linked list
377 * Bank size may be flagged.
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) {
395 for (ap
= areap
; ap
!= NULL
; ap
= ap
->a_ap
) {
396 if (ap
->a_bp
!= bp
) {
399 if ((ap
->a_flag
& A4_BNK
) != A4_BNK
) {
402 bytes
= ap
->a_addr
* (1 + (ap
->a_flag
& A4_WLMSK
));
406 bytes
= (ap
->a_addr
+ ap
->a_size
) * (1 + (ap
->a_flag
& A4_WLMSK
));
411 if ((ahigh
- alow
) > blimit
) {
413 "\n?ASlink-Warning-Size limit exceeded in bank %s\n", bp
->b_id
);
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.
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
439 * int a_bytes T line address bytes
440 * area *ap Pointer to the current
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
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
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
463 * All data output files are opened.
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
);
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
);
495 * If .__.END. is defined force
496 * an output file to be opened.
498 sp
= lkpsym(".__.END.", 0);
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.
509 if ((ap
->a_flag
& A4_BNK
) != A4_BNK
) {
512 if ((ap
->a_flag
& A4_OUT
) || (ap
->a_size
!= 0)) {
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
) {
537 case 2: frmt
= "ihx"; break;
539 fpt
= strsto(bp
->b_fspec
);
541 fp
= afile(fpt
, frmt
, 1);
546 case 2: frmt
= "s19"; break;
548 fpt
= strsto(bp
->b_fspec
);
550 fp
= afile(fpt
, frmt
, 1);
555 case 2: frmt
= "bin"; break;
556 case 3: frmt
= "bi3"; break;
557 case 4: frmt
= "bi4"; break;
559 fpt
= strsto(bp
->b_fspec
);
562 fp
= afile(fpt
, frmt
, 2);
566 fpt
= strsto(bp
->b_fspec
);
568 fp
= afile(fpt
, "elf", 2);
570 /* end sdld specific */
575 bp
->b_ofspec
= strsto(afspec
);
578 * Include NoICE command to load file
581 fprintf(jfp
, "LOAD %s\n", bp
->b_ofspec
);
587 ap
->a_ofp
= bp
->b_ofp
;
596 /*)Function VOID lkfclose()
598 * The function lkfclose() scans the bank structures to
599 * close all open data output files.
602 * struct bank *tbp temporary bank pointer
605 * bank *bp Pointer to the current
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
613 * VOID lkout() lkout.c
614 * int fclose() c_library
617 * All open data output files are closed.
626 * Scan Bank Structure
627 * Output data terminations
628 * and close open files
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
) {