]> git.sur5r.net Git - cc65/blob - src/ld65/span.c
f1bf280c3e20218f5cd32bb89f346200fe058cef
[cc65] / src / ld65 / span.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                  span.c                                   */
4 /*                                                                           */
5 /*                      A span of data within a segment                      */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2011,      Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 /* common */
37 #include "xmalloc.h"
38
39 /* ld65 */           
40 #include "fileio.h"
41 #include "objdata.h"
42 #include "segments.h"
43 #include "span.h"
44
45
46
47 /*****************************************************************************/
48 /*                                   Code                                    */
49 /*****************************************************************************/
50
51
52
53 Span* NewSpan (struct Segment* Seg, unsigned long Offs, unsigned long Size)
54 /* Create and return a new span */
55 {
56     /* Allocate memory */
57     Span* S = xmalloc (sizeof (*S));
58
59     /* Initialize the fields */
60     S->Seg      = Seg;
61     S->Offs     = Offs;
62     S->Size     = Size;
63
64     /* Return the result */
65    return S;
66 }
67
68
69
70 Span* ReadSpan (FILE* F, ObjData* O)
71 /* Read a Span from a file and return it */
72 {
73     /* Read the section id and translate it to a section pointer */
74     Section* Sec = GetObjSection (O, ReadVar (F));
75
76     /* Read the offset and relocate it */
77     unsigned long Offs = ReadVar (F) + Sec->Offs;
78
79     /* Create and return a new Span */
80     return NewSpan (Sec->Seg, Offs, ReadVar (F));
81 }
82
83
84
85 void ReadSpans (Collection* Spans, FILE* F, ObjData* O)
86 /* Read a list of Spans from a file and return it */
87 {
88     /* First is number of Spans */
89     unsigned Count = ReadVar (F);
90
91     /* Preallocate enough entries in the collection */
92     CollGrow (Spans, Count);
93
94     /* Read the spans and add them */
95     while (Count--) {
96         CollAppend (Spans, ReadSpan (F, O));
97     }
98 }
99
100
101
102 void FreeSpan (Span* S)
103 /* Free a span structure */
104 {
105     /* Just free the structure */
106     xfree (S);
107 }
108
109
110
111 void AddSpan (Collection* Spans, struct Segment* Seg, unsigned long Offs,
112               unsigned long Size)
113 /* Either add a new span to the ones already in the given collection, or - if
114  * possible - merge it with adjacent ones that already exist.
115  */
116 {
117     unsigned I;
118
119     /* We don't have many spans in a collection, so we do a linear search here.
120      * The collection is kept sorted which eases our work here.
121      */
122     for (I = 0; I < CollCount (Spans); ++I) {
123
124         /* Get the next span */
125         Span* S = CollAtUnchecked (Spans, I);
126
127         /* Must be same segment, otherwise we cannot merge */
128         if (S->Seg != Seg) {
129             continue;
130         }
131
132         /* Check if we can merge it */
133         if (Offs < S->Offs) {
134
135             /* Got the insert position */
136             if (Offs + Size == S->Offs) {
137                 /* Merge the two */
138                 S->Offs = Offs;
139                 S->Size += Size;
140             } else {
141                 /* Insert a new entry */
142                 CollInsert (Spans, NewSpan (Seg, Offs, Size), I);
143             }
144
145             /* Done */
146             return;
147
148         } else if (S->Offs + S->Size == Offs) {
149
150             /* This is the regular case. Merge the two. */
151             S->Size += Size;
152
153             /* Done */
154             return;
155         }
156     }
157
158     /* We must append an entry */
159     CollAppend (Spans, NewSpan (Seg, Offs, Size));
160 }
161
162
163