]> git.sur5r.net Git - cc65/blob - src/ld65/lineinfo.c
Fixed a bug
[cc65] / src / ld65 / lineinfo.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                lineinfo.h                                 */
4 /*                                                                           */
5 /*                      Source file line info structure                      */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2001      Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
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 "check.h"
38 #include "xmalloc.h"
39
40 /* ld65 */
41 #include "fileio.h"
42 #include "fragment.h"
43 #include "segments.h"
44 #include "lineinfo.h"
45
46
47
48 /*****************************************************************************/
49 /*                                   Code                                    */
50 /*****************************************************************************/
51
52
53
54 static CodeRange* NewCodeRange (unsigned long Offs, unsigned long Size)
55 /* Create and return a new CodeRange struct */
56 {
57     /* Allocate memory */
58     CodeRange* R = xmalloc (sizeof (CodeRange));
59
60     /* Initialize the fields */
61     R->Offs = Offs;
62     R->Size = Size;
63
64     /* Return the new struct */
65     return R;
66 }
67
68
69
70 static LineInfo* NewLineInfo (void)
71 /* Create and return a new LineInfo struct */
72 {
73     /* Allocate memory */
74     LineInfo* LI = xmalloc (sizeof (LineInfo));
75
76     /* Initialize the fields */
77     LI->File = 0;
78     InitFilePos (&LI->Pos);
79     InitCollection (&LI->Fragments);
80     InitCollection (&LI->CodeRanges);
81
82     /* Return the new struct */
83     return LI;
84 }
85
86
87
88 LineInfo* ReadLineInfo (FILE* F, ObjData* O)
89 /* Read a line info from a file and return it */
90 {
91     /* Allocate a new LineInfo struct and initialize it */
92     LineInfo* LI = NewLineInfo ();
93
94     /* Read the file position */
95     ReadFilePos (F, &LI->Pos);
96
97     /* Resolve the file index to a pointer to FileInfo struct */
98     CHECK (LI->Pos.Name < O->FileCount);
99     LI->File = O->Files[LI->Pos.Name];
100
101     /* Return the new LineInfo */
102     return LI;
103 }
104
105
106
107 static void AddCodeRange (LineInfo* LI, unsigned long Offs, unsigned long Size)
108 /* Add a range of code to this line */
109 {
110     unsigned I;
111
112     /* Get a pointer to the collection */
113     Collection* CodeRanges = &LI->CodeRanges;
114
115     /* We will keep the CodeRanges collection sorted by starting offset,
116      * so we have to search for the correct insert position. Since in most
117      * cases, the fragments have increasing order, and there is usually not
118      * more than one or two ranges, we do a linear search.
119      */
120     for (I = 0; I < CollCount (CodeRanges); ++I) {
121         CodeRange* R = CollAtUnchecked (CodeRanges, I);
122         if (Offs < R->Offs) {
123
124             /* Got the insert position */
125             if (Offs + Size == R->Offs) {
126                 /* Merge the two */
127                 R->Offs = Offs;
128                 R->Size += Size;
129             } else {
130                 /* Insert a new entry */
131                 CollInsert (CodeRanges, NewCodeRange (Offs, Size), I);
132             }
133
134             /* Done */
135             return;
136
137         } else if (R->Offs + R->Size == Offs) {
138
139             /* This is the regular case. Merge the two. */
140             R->Size += Size;
141
142             /* Done */
143             return;
144
145         }
146     }
147
148     /* We must append an entry */
149     CollAppend (CodeRanges, NewCodeRange (Offs, Size));
150 }
151
152
153
154 void RelocLineInfo (struct Segment* S)
155 /* Relocate the line info for a segment. */
156 {
157     unsigned long Offs = 0;
158
159     /* Loop over all sections in this segment */
160     Section* Sec = S->SecRoot;
161     while (Sec) {
162         Fragment* Frag;
163
164         /* Adjust for fill bytes */
165         Offs += Sec->Fill;
166
167         /* Loop over all fragments in this section */
168         Frag = Sec->FragRoot;
169         while (Frag) {
170
171             /* Add the range for this fragment to the line info if there
172              * is any
173              */
174             if (Frag->LI) {
175                 AddCodeRange (Frag->LI, Offs, Frag->Size);
176             }
177
178             /* Update the offset */
179             Offs += Frag->Size;
180
181             /* Next fragment */
182             Frag = Frag->Next;
183         }
184
185         /* Next section */
186         Sec = Sec->Next;
187     }
188 }
189
190
191