b103bc0a6cbae8fe55ac5ec675985f45c94f3d3d
[fw/sdcc] / as / link / hc08 / lkarea.c
1 /* lkarea.c */
2
3 /*
4  * (C) Copyright 1989-1995
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  *
11  *  3-Nov-97 JLH:
12  *           - change lkparea to use a_type == 0 as "virgin area" flag
13  * 02-Apr-98 JLH: add code to link 8051 data spaces
14  */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include "aslink.h"
19
20 /*)Module       lkarea.c
21  *
22  *      The module lkarea.c contains the functions which
23  *      create and link together all area definitions read
24  *      from the .rel file(s).
25  *
26  *      lkarea.c contains the following functions:
27  *              VOID    lnkarea()
28  *              VOID    lnksect()
29  *              VOID    lkparea()
30  *              VOID    newarea()
31  *
32  *      lkarea.c contains no global variables.
33  */
34
35 /*)Function     VOID    newarea()
36  *
37  *      The function newarea() creates and/or modifies area
38  *      and areax structures for each A directive read from
39  *      the .rel file(s).  The function lkparea() is called
40  *      to find the area structure associated with this name.
41  *      If the area does not yet exist then a new area
42  *      structure is created and linked to any existing
43  *      linked area structures. The area flags are copied
44  *      into the area flag variable.  For each occurence of
45  *      an A directive an areax structure is created and
46  *      linked to the areax structures associated with this
47  *      area.  The size of this area section is placed into
48  *      the areax structure.  The flag value for all subsequent
49  *      area definitions for the same area are compared and
50  *      flagged as an error if they are not identical.
51  *      The areax structure created for every occurence of
52  *      an A directive is loaded with a pointer to the base
53  *      area structure and a pointer to the associated
54  *      head structure.  And finally, a pointer to this
55  *      areax structure is loaded into the list of areax
56  *      structures in the head structure.  Refer to lkdata.c
57  *      for details of the structures and their linkage.
58  *
59  *      local variables:
60  *              areax **halp            pointer to an array of pointers
61  *              int     i               counter, loop variable, value
62  *              char    id[]            id string
63  *              int     narea           number of areas in this head structure
64  *              areax * taxp            pointer to an areax structure
65  *                                      to areax structures
66  *
67  *      global variables:
68  *              area    *ap             Pointer to the current
69  *                                      area structure
70  *              areax   *axp            Pointer to the current
71  *                                      areax structure
72  *              head    *hp             Pointer to the current
73  *                                      head structure
74  *              int     lkerr           error flag
75  *
76  *      functions called:
77  *              Addr_T  eval()          lkeval.c
78  *              VOID    exit()          c_library
79  *              int     fprintf()       c_library
80  *              VOID    getid()         lklex.c
81  *              VOID    lkparea()       lkarea.c
82  *              VOID    skip()          lklex.c
83  *
84  *      side effects:
85  *              The area and areax structures are created and
86  *              linked with the appropriate head structures.
87  *              Failure to allocate area or areax structure
88  *              space will terminate the linker.  Other internal
89  *              errors most likely caused by corrupted .rel
90  *              files will also terminate the linker.
91  */
92
93 /*
94  * Create an area entry.
95  *
96  * A xxxxxx size nnnn flags mm
97  *   |           |          |
98  *   |           |          `--  ap->a_flag
99  *   |           `------------- axp->a_size
100  *   `-------------------------  ap->a_id
101  *
102  */
103 VOID
104 newarea()
105 {
106     register int i, narea;
107     struct areax *taxp;
108     struct areax **halp;
109     char id[NCPS];
110
111     /*
112      * Create Area entry
113      */
114     getid(id, -1);
115     lkparea(id);
116     /*
117      * Evaluate area size
118      */
119     skip(-1);
120     axp->a_size = eval();
121     /*
122      * Evaluate flags
123      */
124     skip(-1);
125     i = 0;
126     taxp = ap->a_axp;
127     while (taxp->a_axp) {
128         ++i;
129         taxp = taxp->a_axp;
130     }
131     if (i == 0) {
132         ap->a_flag = eval();
133     } else {
134         i = eval();
135 /*      if (i && (ap->a_flag != i)) { */
136 /*          fprintf(stderr, "Conflicting flags in area %8s\n", id); */
137 /*          lkerr++; */
138 /*      } */
139     }
140     /*
141      * Evaluate area address
142      */
143     skip(-1);
144     axp->a_addr = eval();
145     /*
146      * Place pointer in header area list
147      */
148     if (headp == NULL) {
149         fprintf(stderr, "No header defined\n");
150         lkexit(1);
151     }
152     narea = hp->h_narea;
153     halp = hp->a_list;
154     for (i=0; i < narea ;++i) {
155         if (halp[i] == NULL) {
156             halp[i] = taxp;
157             return;
158         }
159     }
160     fprintf(stderr, "Header area list overflow\n");
161     lkexit(1);
162 }
163
164 /*)Function     VOID    lkparea(id)
165  *
166  *              char *  id              pointer to the area name string
167  *
168  *      The function lkparea() searches the linked area structures
169  *      for a name match.  If the name is not found then an area
170  *      structure is created.  An areax structure is created and
171  *      appended to the areax structures linked to the area structure.
172  *      The associated base area and head structure pointers are
173  *      loaded into the areax structure.
174  *
175  *      local variables:
176  *              area *  tap             pointer to an area structure
177  *              areax * taxp            pointer to an areax structure
178  *
179  *      global variables:
180  *              area    *ap             Pointer to the current
181  *                                      area structure
182  *              area    *areap          The pointer to the first
183  *                                      area structure of a linked list
184  *              areax   *axp            Pointer to the current
185  *                                      areax structure
186  *
187  *      functions called:
188  *              VOID *  new()           lksym()
189  *              char *  strcpy()        c_library
190  *              int     symeq()         lksym.c
191  *
192  *      side effects:
193  *              Area and/or areax structures are created.
194  *              Failure to allocate space for created structures
195  *              will terminate the linker.
196  */
197
198 VOID
199 lkparea(char *id)
200 {
201     register struct area *tap;
202     register struct areax *taxp;
203
204     ap = areap;
205     axp = (struct areax *) new (sizeof(struct areax));
206     axp->a_addr = -1; /* default: no address yet */
207     while (ap) {
208         if (symeq(id, ap->a_id)) {
209             taxp = ap->a_axp;
210             while (taxp->a_axp)
211                 taxp = taxp->a_axp;
212             taxp->a_axp = axp;
213             axp->a_bap = ap;
214             axp->a_bhp = hp;
215             return;
216         }
217         ap = ap->a_ap;
218     }
219     ap = (struct area *) new (sizeof(struct area));
220     if (areap == NULL) {
221         areap = ap;
222     } else {
223         tap = areap;
224         while (tap->a_ap)
225             tap = tap->a_ap;
226         tap->a_ap = ap;
227     }
228     ap->a_axp = axp;
229     axp->a_bap = ap;
230     axp->a_bhp = hp;
231     strncpy(ap->a_id, id, NCPS);
232     ap->a_addr = 0;
233 }
234
235 /*)Function     VOID    lnkarea()
236  *
237  *      The function lnkarea() resolves all area addresses.
238  *      The function evaluates each area structure (and all
239  *      the associated areax structures) in sequence.  The
240  *      linking process supports four (4) possible area types:
241  *
242  *      ABS/OVR -       All sections (each individual areax
243  *                      section) starts at the identical base
244  *                      area address overlaying all other
245  *                      areax sections for this area.  The
246  *                      size of the area is largest of the area
247  *                      sections.
248  *
249  *      ABS/CON -       All sections (each individual areax
250  *                      section) are concatenated with the
251  *                      first section starting at the base
252  *                      area address.  The size of the area
253  *                      is the sum of the section sizes.
254  *
255  *      NOTE:   Multiple absolute (ABS) areas are
256  *                      never concatenated with each other,
257  *                      thus absolute area A and absolute area
258  *                      B will overlay each other if they begin
259  *                      at the same location (the default is
260  *                      always address 0 for absolute areas).
261  *
262  *      REL/OVR -       All sections (each individual areax
263  *                      section) starts at the identical base
264  *                      area address overlaying all other
265  *                      areax sections for this area.  The
266  *                      size of the area is largest of the area
267  *                      sections.
268  *
269  *      REL/CON -       All sections (each individual areax
270  *                      section) are concatenated with the
271  *                      first section starting at the base
272  *                      area address.  The size of the area
273  *                      is the sum of the section sizes.
274  *
275  *      NOTE:           Relocatable (REL) areas are always concatenated
276  *                      with each other, thus relocatable area B
277  *                      (defined after area A) will follow
278  *                      relocatable area A independent of the
279  *                      starting address of area A.  Within a
280  *                      specific area each areax section may be
281  *                      overlayed or concatenated with other
282  *                      areax sections.
283  *
284  *
285  *      If a base address for an area is specified then the
286  *      area will start at that address.  Any relocatable
287  *      areas defined subsequently will be concatenated to the
288  *      previous relocatable area if it does not have a base
289  *      address specified.
290  *
291  *      The names s_<areaname> and l_<areaname> are created to
292  *      define the starting address and length of each area.
293  *
294  *      local variables:
295  *              Addr_T  rloc            ;current relocation address
296  *              char    temp[]          ;temporary string
297  *              struct symbol   *sp     ;symbol structure
298  *
299  *      global variables:
300  *              area    *ap                     Pointer to the current
301  *                                                      area structure
302  *              area    *areap          The pointer to the first
303  *                                                      area structure of a linked list
304  *
305  *      functions called:
306  *              int             fprintf()       c_library
307  *              VOID    lnksect()       lkarea.c
308  *              symbol *lkpsym()        lksym.c
309  *              char *  strncpy()       c_library
310  *              int     symeq()         lksym.c
311  *
312  *      side effects:
313  *              All area and areax addresses and sizes are
314  *              determined and saved in their respective
315  *              structures.
316  */
317
318 unsigned long codemap[2048];
319 Addr_T lnksect(struct area *tap);
320 /*
321  * Resolve all area addresses.
322  */
323 VOID
324 lnkarea()
325 {
326     Addr_T rloc[4] = {0, 0, 0, 0};
327     Addr_T gs_size = 0;
328     int  locIndex;
329     char temp[NCPS];
330     struct sym *sp;
331     /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
332     struct area *ta[5];
333     int j;
334     struct area *abs_ap = NULL;
335     struct area *gs0_ap = NULL;
336
337     memset(codemap, 0, sizeof(codemap));
338
339     /* first sort all absolute areas to the front */
340     ap = areap;
341     /* no need to check first area, it's in front anyway */
342     while (ap && ap->a_ap)
343     {
344         if (ap->a_ap->a_flag & A_ABS)
345         {/* next area is absolute, move it to front,
346             reversed sequence is no problem for absolutes */
347             abs_ap = ap->a_ap;
348             ap->a_ap = abs_ap->a_ap;
349             abs_ap->a_ap = areap;
350             areap = abs_ap;
351         }
352         else
353         {
354             ap = ap->a_ap;
355         }
356     }
357
358     /* next accumulate all GSINITx/GSFINAL area sizes
359        into GSINIT so they stay together */
360     ap = areap;
361     while (ap)
362     {
363         if (!strncmp(ap->a_id, "GS", 2))
364         {/* GSxxxxx area */
365             if (ap->a_size == 0)
366             {
367                 axp = ap->a_axp;
368                 while (axp)
369                 {
370                     ap->a_size += axp->a_size;
371                     axp = axp->a_axp;
372                 }
373             }
374             gs_size += ap->a_size;
375             if (!strcmp(ap->a_id, "GSINIT0"))
376             {/* GSINIT0 area */
377                 gs0_ap = ap;
378             }
379         }
380         ap = ap->a_ap;
381     }
382     if (gs0_ap)
383         gs0_ap->a_size = gs_size;
384
385     ap = areap;
386     while (ap) {
387         if (ap->a_flag & A_ABS) {
388             /*
389              * Absolute sections
390              */
391             lnksect(ap);
392         } else {
393             /* Determine memory space */
394             locIndex = 0;
395             #if 0
396             if (ap->a_flag & A_CODE) {
397                 locIndex = 1;
398             }
399             if (ap->a_flag & A_XDATA) {
400                 locIndex = 2;
401             }
402             if (ap->a_flag & A_BIT) {
403                 locIndex = 3;
404             }
405             #endif
406             /*
407              * Relocatable sections
408              */
409             if (ap->a_type == 0) {  /* JLH */
410                 if (ap->a_flag & A_NOLOAD) {
411                     locIndex = 2;
412                     ap->a_addr = 0;
413                 } else {
414                     ap->a_addr = rloc[ locIndex ];
415                 }
416                 ap->a_type = 1;
417             }
418
419             rloc[ locIndex ] = lnksect(ap);
420         }
421
422         /*
423          * Create symbols called:
424          *      s_<areaname>    the start address of the area
425          *      l_<areaname>    the length of the area
426          */
427
428         if (! symeq(ap->a_id, _abs_))
429         {
430             strncpy(temp+2,ap->a_id,NCPS-2);
431             *(temp+1) = '_';
432
433             *temp = 's';
434             sp = lkpsym(temp, 1);
435             sp->s_addr = ap->a_addr ;
436             /* sp->s_axp = ap->a_axp;  JLH: was NULL; */
437             sp->s_type |= S_DEF;
438
439             *temp = 'l';
440             sp = lkpsym(temp, 1);
441             sp->s_addr = ap->a_size;
442             sp->s_axp = NULL;
443             sp->s_type |= S_DEF;
444
445         }
446
447         /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
448         to compute the byte size of BSEG_BYTES: */
449         if (!strcmp(ap->a_id, "BSEG")) {
450             ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
451         }
452         else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
453         else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
454         else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
455         else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
456         else if (!strcmp(ap->a_id, "BSEG_BYTES"))
457         {
458             ta[4]=ap;
459             for(j=4; j>1; j--)
460             {
461                 /*If upper register banks are not used roll back the relocation counter*/
462                 if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
463                 {
464                     rloc[0]-=8;
465                 }
466                 else break;
467             }
468         }
469         ap = ap->a_ap;
470     }
471 }
472
473 static
474 Addr_T find_empty_space(Addr_T start, Addr_T size, unsigned long *map)
475 {
476     int i, j, k;
477     unsigned long mask, b;
478
479     while (1)
480     {
481         Addr_T a = start;
482         i = start >> 5;
483         j = (start + size) >> 5;
484         mask = -(1 << (start & 0x1F));
485
486         while (i < j)
487         {
488             if (map[i] & mask)
489             {
490                 k = 32;
491                 for (b=0x80000000; b!=0; b>>=1, k--)
492                 {
493                     if (map[i] & b)
494                       break;
495                 }
496                 start = a + k;
497                 break;
498             }
499             i++;
500             mask = 0xFFFFFFFF;
501             a += 32;
502         }
503         if (start > a)
504           continue;
505
506         mask &= (1 << ((start + size) & 0x1F)) - 1;
507         if (map[i] & mask)
508         {
509             k = 32;
510             for (b=0x80000000; b!=0; b>>=1, k--)
511             {
512                 if (map[i] & b)
513                   break;
514             }
515             start = (a & ~0x1F) + k;
516         }
517         if (start <= a)
518           break;
519     }
520     return start;
521 }
522
523 static
524 Addr_T allocate_space(Addr_T start, Addr_T size, char* id, unsigned long *map)
525 {
526     int i, j;
527     unsigned long mask;
528     Addr_T a = start;
529     i = start >> 5;
530     j = (start + size) >> 5;
531     mask = -(1 << (start & 0x1F));
532
533     while (i < j)
534     {
535         if (map[i] & mask)
536         {
537             fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
538         }
539         map[i++] |= mask;
540         mask = 0xFFFFFFFF;
541         a += 32;
542     }
543     mask &= (1 << ((start + size) & 0x1F)) - 1;
544     if (map[i] & mask)
545     {
546         fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
547     }
548     map[i] |= mask;
549     return start;
550 }
551
552 /*)Function     VOID    lnksect()
553  *
554  *              area *  tap             pointer to an area structure
555  *
556  *      The function lnksect() is the function called by
557  *      lnkarea() to resolve the areax addresses.  Refer
558  *      to the function lnkarea() for more detail. Pageing
559  *      boundary and length errors will be reported by this
560  *      function.
561  *
562  *      local variables:
563  *              Addr_T  size            size of area
564  *              Addr_T  addr            address of area
565  *              areax * taxp            pointer to an areax structure
566  *
567  *      global variables:
568  *              int     lkerr           error flag
569  *
570  *      functions called:
571  *              none
572  *
573  *      side effects:
574  *              All area and areax addresses and sizes area determined
575  *              and linked into the structures.
576  */
577
578 Addr_T lnksect(struct area *tap)
579 {
580     register Addr_T size, addr;
581     register struct areax *taxp;
582
583     size = 0;
584     addr = tap->a_addr;
585
586     if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
587         fprintf(stderr,
588         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
589         lkerr++;
590     }
591
592     taxp = tap->a_axp;
593     if (tap->a_flag&A_OVR) {
594         /*
595          * Overlayed sections
596          */
597         while (taxp) {
598             taxp->a_addr = addr;
599             if (taxp->a_size > size)
600                 size = taxp->a_size;
601             taxp = taxp->a_axp;
602         }
603     } else if (tap->a_flag & A_ABS) {
604         /*
605          * Absolute sections
606          */
607         while (taxp) {
608             allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap);
609             taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
610             size += taxp->a_size;
611             taxp = taxp->a_axp;
612         }
613     } else {
614         /*
615          * Concatenated sections
616          */
617         if (tap->a_size) {
618             addr = find_empty_space(addr, tap->a_size, codemap);
619         }
620         while (taxp) {
621             //find next unused address now
622             if (taxp->a_size)
623             {
624                 addr = find_empty_space(addr, taxp->a_size, codemap);
625                 allocate_space(addr, taxp->a_size, tap->a_id, codemap);
626             }
627             taxp->a_addr = addr;
628             addr += taxp->a_size;
629             size += taxp->a_size;
630             taxp = taxp->a_axp;
631         }
632     }
633     tap->a_size = size;
634
635     if ((tap->a_flag&A_PAG) && (size > 256)) {
636         fprintf(stderr,
637         "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
638         lkerr++;
639     }
640
641     return addr;
642 }