]> git.sur5r.net Git - cc65/blob - src/ld65/lineinfo.c
Some changes in debug info generation.
[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 (Segment* Seg, 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->Seg  = Seg;
63     R->Offs = Offs;
64     R->Size = Size;
65
66     /* Return the new struct */
67     return R;
68 }
69
70
71
72 LineInfo* NewLineInfo (ObjData* O, const FilePos* Pos)
73 /* Create and return a new LineInfo struct */
74 {
75     /* Allocate memory */
76     LineInfo* LI = xmalloc (sizeof (LineInfo));
77
78     /* Make sure the name index is valid */
79     CHECK (Pos->Name < CollCount (&O->Files));
80
81     /* Initialize the fields */
82     LI->File = CollAt (&O->Files, Pos->Name);
83     LI->Pos = *Pos;
84     InitCollection (&LI->Fragments);
85     InitCollection (&LI->CodeRanges);
86
87     /* Return the new struct */
88     return LI;
89 }
90
91
92
93 LineInfo* ReadLineInfo (FILE* F, ObjData* O)
94 /* Read a line info from a file and return it */
95 {
96     /* Read the file position */
97     FilePos Pos;
98     ReadFilePos (F, &Pos);
99
100     /* Allocate a new LineInfo struct, initialize and return it */
101     return NewLineInfo (O, &Pos);
102 }
103
104
105
106 static void AddCodeRange (LineInfo* LI, Segment* Seg, unsigned long Offs,
107                           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         /* Must be same segment */
123         if (R->Seg == Seg) {
124             if (Offs < R->Offs) {
125
126                 /* Got the insert position */
127                 if (Offs + Size == R->Offs) {
128                     /* Merge the two */
129                     R->Offs = Offs;
130                     R->Size += Size;
131                 } else {
132                     /* Insert a new entry */
133                     CollInsert (CodeRanges, NewCodeRange (Seg, Offs, Size), I);
134                 }
135
136                 /* Done */
137                 return;
138
139             } else if (R->Offs + R->Size == Offs) {
140                 /* This is the regular case. Merge the two. */
141                 R->Size += Size;
142
143                 /* Done */
144                 return;
145             }
146         }
147     }
148
149     /* We must append an entry */
150     CollAppend (CodeRanges, NewCodeRange (Seg, Offs, Size));
151 }
152
153
154
155 void RelocLineInfo (Segment* S)
156 /* Relocate the line info for a segment. */
157 {
158     unsigned long Offs = S->PC;
159
160     /* Loop over all sections in this segment */
161     Section* Sec = S->SecRoot;
162     while (Sec) {
163         Fragment* Frag;
164
165         /* Adjust for fill bytes */
166         Offs += Sec->Fill;
167
168         /* Loop over all fragments in this section */
169         Frag = Sec->FragRoot;
170         while (Frag) {
171
172             unsigned I;
173
174             /* Add the range for this fragment to all line infos */
175             for (I = 0; I < CollCount (&Frag->LineInfos); ++I) {
176                 AddCodeRange (CollAt (&Frag->LineInfos, I), S, Offs, Frag->Size);
177             }
178
179             /* Update the offset */
180             Offs += Frag->Size;
181
182             /* Next fragment */
183             Frag = Frag->Next;
184         }
185
186         /* Next section */
187         Sec = Sec->Next;
188     }
189 }
190
191
192
193