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