3 Copyright (C) 1989-1995 Alan R. Baldwin
4 721 Berkeley St., Kent, Ohio 44240
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
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/>. */
21 * - change lkparea to use a_type == 0 as "virgin area" flag
22 * 02-Apr-98 JLH: add code to link 8051 data spaces
31 * The module lkarea.c contains the functions which
32 * create and link together all area definitions read
33 * from the .rel file(s).
35 * lkarea.c contains the following functions:
41 * lkarea.c contains no global variables.
44 /*)Function VOID newarea()
46 * The function newarea() creates and/or modifies area
47 * and areax structures for each A directive read from
48 * the .rel file(s). The function lkparea() is called
49 * to find the area structure associated with this name.
50 * If the area does not yet exist then a new area
51 * structure is created and linked to any existing
52 * linked area structures. The area flags are copied
53 * into the area flag variable. For each occurence of
54 * an A directive an areax structure is created and
55 * linked to the areax structures associated with this
56 * area. The size of this area section is placed into
57 * the areax structure. The flag value for all subsequent
58 * area definitions for the same area are compared and
59 * flagged as an error if they are not identical.
60 * The areax structure created for every occurence of
61 * an A directive is loaded with a pointer to the base
62 * area structure and a pointer to the associated
63 * head structure. And finally, a pointer to this
64 * areax structure is loaded into the list of areax
65 * structures in the head structure. Refer to lkdata.c
66 * for details of the structures and their linkage.
69 * areax **halp pointer to an array of pointers
70 * int i counter, loop variable, value
72 * int narea number of areas in this head structure
73 * areax * taxp pointer to an areax structure
77 * area *ap Pointer to the current
79 * areax *axp Pointer to the current
81 * head *hp Pointer to the current
83 * int lkerr error flag
86 * Addr_T eval() lkeval.c
87 * VOID exit() c_library
88 * int fprintf() c_library
89 * VOID getid() lklex.c
90 * VOID lkparea() lkarea.c
94 * The area and areax structures are created and
95 * linked with the appropriate head structures.
96 * Failure to allocate area or areax structure
97 * space will terminate the linker. Other internal
98 * errors most likely caused by corrupted .rel
99 * files will also terminate the linker.
103 * Create an area entry.
105 * A xxxxxx size nnnn flags mm
108 * | `------------- axp->a_size
109 * `------------------------- ap->a_id
115 register int i, narea;
129 axp->a_size = eval();
136 while (taxp->a_axp) {
144 /* if (i && (ap->a_flag != i)) { */
145 /* fprintf(stderr, "Conflicting flags in area %8s\n", id); */
150 * Evaluate area address
153 axp->a_addr = eval();
155 * Place pointer in header area list
158 fprintf(stderr, "No header defined\n");
163 for (i=0; i < narea ;++i) {
164 if (halp[i] == NULL) {
169 fprintf(stderr, "Header area list overflow\n");
173 /*)Function VOID lkparea(id)
175 * char * id pointer to the area name string
177 * The function lkparea() searches the linked area structures
178 * for a name match. If the name is not found then an area
179 * structure is created. An areax structure is created and
180 * appended to the areax structures linked to the area structure.
181 * The associated base area and head structure pointers are
182 * loaded into the areax structure.
185 * area * tap pointer to an area structure
186 * areax * taxp pointer to an areax structure
189 * area *ap Pointer to the current
191 * area *areap The pointer to the first
192 * area structure of a linked list
193 * areax *axp Pointer to the current
197 * VOID * new() lksym()
198 * char * strcpy() c_library
199 * int symeq() lksym.c
202 * Area and/or areax structures are created.
203 * Failure to allocate space for created structures
204 * will terminate the linker.
210 register struct area *tap;
211 register struct areax *taxp;
214 axp = (struct areax *) new (sizeof(struct areax));
215 axp->a_addr = -1; /* default: no address yet */
217 if (symeq(id, ap->a_id)) {
228 ap = (struct area *) new (sizeof(struct area));
240 strncpy(ap->a_id, id, NCPS);
244 /*)Function VOID lnkarea()
246 * The function lnkarea() resolves all area addresses.
247 * The function evaluates each area structure (and all
248 * the associated areax structures) in sequence. The
249 * linking process supports four (4) possible area types:
251 * ABS/OVR - All sections (each individual areax
252 * section) starts at the identical base
253 * area address overlaying all other
254 * areax sections for this area. The
255 * size of the area is largest of the area
258 * ABS/CON - All sections (each individual areax
259 * section) are concatenated with the
260 * first section starting at the base
261 * area address. The size of the area
262 * is the sum of the section sizes.
264 * NOTE: Multiple absolute (ABS) areas are
265 * never concatenated with each other,
266 * thus absolute area A and absolute area
267 * B will overlay each other if they begin
268 * at the same location (the default is
269 * always address 0 for absolute areas).
271 * REL/OVR - All sections (each individual areax
272 * section) starts at the identical base
273 * area address overlaying all other
274 * areax sections for this area. The
275 * size of the area is largest of the area
278 * REL/CON - All sections (each individual areax
279 * section) are concatenated with the
280 * first section starting at the base
281 * area address. The size of the area
282 * is the sum of the section sizes.
284 * NOTE: Relocatable (REL) areas are always concatenated
285 * with each other, thus relocatable area B
286 * (defined after area A) will follow
287 * relocatable area A independent of the
288 * starting address of area A. Within a
289 * specific area each areax section may be
290 * overlayed or concatenated with other
294 * If a base address for an area is specified then the
295 * area will start at that address. Any relocatable
296 * areas defined subsequently will be concatenated to the
297 * previous relocatable area if it does not have a base
300 * The names s_<areaname> and l_<areaname> are created to
301 * define the starting address and length of each area.
304 * Addr_T rloc ;current relocation address
305 * char temp[] ;temporary string
306 * struct symbol *sp ;symbol structure
309 * area *ap Pointer to the current
311 * area *areap The pointer to the first
312 * area structure of a linked list
315 * int fprintf() c_library
316 * VOID lnksect() lkarea.c
317 * symbol *lkpsym() lksym.c
318 * char * strncpy() c_library
319 * int symeq() lksym.c
322 * All area and areax addresses and sizes are
323 * determined and saved in their respective
327 unsigned long codemap[2048];
328 Addr_T lnksect(struct area *tap);
330 * Resolve all area addresses.
335 Addr_T rloc[4] = {0, 0, 0, 0};
340 /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
343 struct area *abs_ap = NULL;
344 struct area *gs0_ap = NULL;
346 memset(codemap, 0, sizeof(codemap));
348 /* first sort all absolute areas to the front */
350 /* no need to check first area, it's in front anyway */
351 while (ap && ap->a_ap)
353 if (ap->a_ap->a_flag & A_ABS)
354 {/* next area is absolute, move it to front,
355 reversed sequence is no problem for absolutes */
357 ap->a_ap = abs_ap->a_ap;
358 abs_ap->a_ap = areap;
367 /* next accumulate all GSINITx/GSFINAL area sizes
368 into GSINIT so they stay together */
372 if (!strncmp(ap->a_id, "GS", 2))
379 ap->a_size += axp->a_size;
383 gs_size += ap->a_size;
384 if (!strcmp(ap->a_id, "GSINIT0"))
392 gs0_ap->a_size = gs_size;
396 if (ap->a_flag & A_ABS) {
402 /* Determine memory space */
405 if (ap->a_flag & A_CODE) {
408 if (ap->a_flag & A_XDATA) {
411 if (ap->a_flag & A_BIT) {
416 * Relocatable sections
418 if (ap->a_type == 0) { /* JLH */
419 if (ap->a_flag & A_NOLOAD) {
423 ap->a_addr = rloc[ locIndex ];
428 rloc[ locIndex ] = lnksect(ap);
432 * Create symbols called:
433 * s_<areaname> the start address of the area
434 * l_<areaname> the length of the area
437 if (! symeq(ap->a_id, _abs_))
439 strncpy(temp+2,ap->a_id,NCPS-2);
443 sp = lkpsym(temp, 1);
444 sp->s_addr = ap->a_addr ;
445 /* sp->s_axp = ap->a_axp; JLH: was NULL; */
449 sp = lkpsym(temp, 1);
450 sp->s_addr = ap->a_size;
456 /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
457 to compute the byte size of BSEG_BYTES: */
458 if (!strcmp(ap->a_id, "BSEG")) {
459 ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
461 else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
462 else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
463 else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
464 else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
465 else if (!strcmp(ap->a_id, "BSEG_BYTES"))
470 /*If upper register banks are not used roll back the relocation counter*/
471 if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
483 Addr_T find_empty_space(Addr_T start, Addr_T size, unsigned long *map)
486 unsigned long mask, b;
492 j = (start + size) >> 5;
493 mask = -(1 << (start & 0x1F));
500 for (b=0x80000000; b!=0; b>>=1, k--)
515 mask &= (1 << ((start + size) & 0x1F)) - 1;
519 for (b=0x80000000; b!=0; b>>=1, k--)
524 start = (a & ~0x1F) + k;
533 Addr_T allocate_space(Addr_T start, Addr_T size, char* id, unsigned long *map)
539 j = (start + size) >> 5;
540 mask = -(1 << (start & 0x1F));
546 fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
552 mask &= (1 << ((start + size) & 0x1F)) - 1;
555 fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
561 /*)Function VOID lnksect()
563 * area * tap pointer to an area structure
565 * The function lnksect() is the function called by
566 * lnkarea() to resolve the areax addresses. Refer
567 * to the function lnkarea() for more detail. Pageing
568 * boundary and length errors will be reported by this
572 * Addr_T size size of area
573 * Addr_T addr address of area
574 * areax * taxp pointer to an areax structure
577 * int lkerr error flag
583 * All area and areax addresses and sizes area determined
584 * and linked into the structures.
587 Addr_T lnksect(struct area *tap)
589 register Addr_T size, addr;
590 register struct areax *taxp;
595 if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
597 "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
602 if (tap->a_flag&A_OVR) {
608 if (taxp->a_size > size)
612 } else if (tap->a_flag & A_ABS) {
617 allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap);
618 taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
619 size += taxp->a_size;
624 * Concatenated sections
627 addr = find_empty_space(addr, tap->a_size, codemap);
630 //find next unused address now
633 addr = find_empty_space(addr, taxp->a_size, codemap);
634 allocate_space(addr, taxp->a_size, tap->a_id, codemap);
637 addr += taxp->a_size;
638 size += taxp->a_size;
644 if ((tap->a_flag&A_PAG) && (size > 256)) {
646 "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);