]> git.sur5r.net Git - cc65/blob - src/ld65/objdata.c
Merge remote-tracking branch 'upstream/master' into a5200
[cc65] / src / ld65 / objdata.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 objdata.c                                 */
4 /*                                                                           */
5 /*               Handling object file data for the ld65 linker               */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-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 #include <string.h>
37
38 /* common */
39 #include "check.h"
40 #include "xmalloc.h"
41
42 /* ld65 */
43 #include "error.h"
44 #include "exports.h"
45 #include "fileinfo.h"
46 #include "library.h"
47 #include "objdata.h"
48 #include "spool.h"
49
50
51
52 /*****************************************************************************/
53 /*                                   Data                                    */
54 /*****************************************************************************/
55
56
57
58 /* Collection containing used ObjData objects */
59 Collection       ObjDataList = STATIC_COLLECTION_INITIALIZER;
60
61
62
63 /*****************************************************************************/
64 /*                                   Code                                    */
65 /*****************************************************************************/
66
67
68
69 ObjData* NewObjData (void)
70 /* Allocate a new structure on the heap, insert it into the list, return it */
71 {
72     /* Allocate memory */
73     ObjData* O = xmalloc (sizeof (ObjData));
74
75     /* Initialize the data */
76     O->Next             = 0;
77     O->Name             = INVALID_STRING_ID;
78     O->Lib              = 0;
79     O->MTime            = 0;
80     O->Start            = 0;
81     O->Flags            = 0;
82     O->HLLSymBaseId     = 0;
83     O->SymBaseId        = 0;
84     O->ScopeBaseId      = 0;
85     O->SpanBaseId       = 0;
86     O->Files            = EmptyCollection;
87     O->Sections         = EmptyCollection;
88     O->Exports          = EmptyCollection;
89     O->Imports          = EmptyCollection;
90     O->DbgSyms          = EmptyCollection;
91     O->HLLDbgSyms       = EmptyCollection;
92     O->LineInfos        = EmptyCollection;
93     O->StringCount      = 0;
94     O->Strings          = 0;
95     O->Assertions       = EmptyCollection;
96     O->Scopes           = EmptyCollection;
97     O->Spans            = EmptyCollection;
98
99     /* Return the new entry */
100     return O;
101 }
102
103
104
105 void FreeObjData (ObjData* O)
106 /* Free an ObjData object. NOTE: This function works only for unused object
107  * data, that is, ObjData objects that aren't used because they aren't
108  * referenced.
109  */
110 {
111     unsigned I;
112
113     for (I = 0; I < CollCount (&O->Files); ++I) {
114         CollDeleteItem (&((FileInfo*) CollAtUnchecked (&O->Files, I))->Modules, O);
115     }
116     DoneCollection (&O->Files);
117     DoneCollection (&O->Sections);
118     for (I = 0; I < CollCount (&O->Exports); ++I) {
119         FreeExport (CollAtUnchecked (&O->Exports, I));
120     }
121     DoneCollection (&O->Exports);
122     for (I = 0; I < CollCount (&O->Imports); ++I) {
123         FreeImport (CollAtUnchecked (&O->Imports, I));
124     }
125     DoneCollection (&O->Imports);
126     DoneCollection (&O->DbgSyms);
127     DoneCollection (&O->HLLDbgSyms);
128
129     for (I = 0; I < CollCount (&O->LineInfos); ++I) {
130         FreeLineInfo (CollAtUnchecked (&O->LineInfos, I));
131     }
132     DoneCollection (&O->LineInfos);
133     xfree (O->Strings);
134     DoneCollection (&O->Assertions);
135     DoneCollection (&O->Scopes);
136     for (I = 0; I < CollCount (&O->Spans); ++I) {
137         FreeSpan (CollAtUnchecked (&O->Spans, I));
138     }
139     DoneCollection (&O->Spans);
140
141     xfree (O);
142 }
143
144
145
146 void FreeObjStrings (ObjData* O)
147 /* Free the module string data. Used once the object file is loaded completely
148  * when all strings are converted to global strings.
149  */
150 {
151     xfree (O->Strings);
152     O->Strings = 0;
153 }
154
155
156
157 void InsertObjData (ObjData* O)
158 /* Insert the ObjData object into the collection of used ObjData objects. */
159 {
160     CollAppend (&ObjDataList, O);
161 }
162
163
164
165 void InsertObjGlobals (ObjData* O)
166 /* Insert imports and exports from the object file into the global import and
167  * export lists.
168  */
169 {
170     unsigned I;
171
172     /* Insert exports and imports */
173     for (I = 0; I < CollCount (&O->Exports); ++I) {
174         InsertExport (CollAt (&O->Exports, I));
175     }
176     for (I = 0; I < CollCount (&O->Imports); ++I) {
177         InsertImport (CollAt (&O->Imports, I));
178     }
179 }
180
181
182
183 unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
184 /* Convert a local string id into a global one and return it. */
185 {
186     if (Index >= O->StringCount) {
187         Error ("Invalid string index (%u) in module `%s'",
188                Index, GetObjFileName (O));
189     }
190     return O->Strings[Index];
191 }
192
193
194
195 const char* GetObjFileName (const ObjData* O)
196 /* Get the name of the object file. Return "[linker generated]" if the object
197  * file is NULL.
198  */
199 {
200     return O? GetString (O->Name) : "[linker generated]";
201 }
202
203
204
205 const struct StrBuf* GetObjString (const ObjData* Obj, unsigned Id)
206 /* Get a string from an object file checking for an invalid index */
207 {
208     return GetStrBuf (MakeGlobalStringId (Obj, Id));
209 }
210
211
212
213 struct Section* GetObjSection (const ObjData* O, unsigned Id)
214 /* Get a section from an object file checking for a valid index */
215 {
216     if (Id >= CollCount (&O->Sections)) {
217         Error ("Invalid section index (%u) in module `%s'",
218                Id, GetObjFileName (O));
219     }
220     return CollAtUnchecked (&O->Sections, Id);
221 }
222
223
224
225 struct Import* GetObjImport (const ObjData* O, unsigned Id)
226 /* Get an import from an object file checking for a valid index */
227 {
228     if (Id >= CollCount (&O->Imports)) {
229         Error ("Invalid import index (%u) in module `%s'",
230                Id, GetObjFileName (O));
231     }
232     return CollAtUnchecked (&O->Imports, Id);
233 }
234
235
236
237 struct Export* GetObjExport (const ObjData* O, unsigned Id)
238 /* Get an export from an object file checking for a valid index */
239 {
240     if (Id >= CollCount (&O->Exports)) {
241         Error ("Invalid export index (%u) in module `%s'",
242                Id, GetObjFileName (O));
243     }
244     return CollAtUnchecked (&O->Exports, Id);
245 }
246
247
248
249 struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id)
250 /* Get a debug symbol from an object file checking for a valid index */
251 {
252     if (Id >= CollCount (&O->DbgSyms)) {
253         Error ("Invalid debug symbol index (%u) in module `%s'",
254                Id, GetObjFileName (O));
255     }
256     return CollAtUnchecked (&O->DbgSyms, Id);
257 }
258
259
260
261 struct Scope* GetObjScope (const ObjData* O, unsigned Id)
262 /* Get a scope from an object file checking for a valid index */
263 {
264     if (Id >= CollCount (&O->Scopes)) {
265         Error ("Invalid scope index (%u) in module `%s'",
266                Id, GetObjFileName (O));
267     }
268     return CollAtUnchecked (&O->Scopes, Id);
269 }
270
271
272
273 unsigned ObjDataCount (void)
274 /* Return the total number of modules */
275 {
276     return CollCount (&ObjDataList);
277 }
278
279
280
281 void PrintDbgModules (FILE* F)
282 /* Output the modules to a debug info file */
283 {
284     unsigned I;
285
286     /* Output modules */
287     for (I = 0; I < CollCount (&ObjDataList); ++I) {
288
289         /* Get this object file */
290         const ObjData* O = CollConstAt (&ObjDataList, I);
291
292         /* The main source file is the one at index zero */
293         const FileInfo* Source = CollConstAt (&O->Files, 0);
294
295         /* Output the module line */
296         fprintf (F,
297                  "mod\tid=%u,name=\"%s\",file=%u",
298                  I,
299                  GetObjFileName (O),
300                  Source->Id);
301
302         /* Add library if any */
303         if (O->Lib != 0) {
304             fprintf (F, ",lib=%u", GetLibId (O->Lib));
305         }
306
307         /* Terminate the output line */
308         fputc ('\n', F);
309     }
310
311 }