1 /*****************************************************************************/
5 /* Library data structures and helpers for the ld65 linker */
9 /* (C) 1998-2010, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
59 /*****************************************************************************/
61 /*****************************************************************************/
65 /* Library data structure */
66 typedef struct Library Library;
69 unsigned Name; /* String id of the name */
70 FILE* F; /* Open file stream */
71 LibHeader Header; /* Library header */
72 unsigned ModCount; /* Number of modules in the library */
73 ObjData** Modules; /* Modules */
76 /* List of open libraries */
77 static Collection OpenLibs = STATIC_COLLECTION_INITIALIZER;
79 /* Flag for library grouping */
80 static int Grouping = 0;
84 /*****************************************************************************/
86 /*****************************************************************************/
90 static Library* NewLibrary (FILE* F, const char* Name)
91 /* Create a new Library structure and return it */
94 Library* L = xmalloc (sizeof (*L));
96 /* Initialize the fields */
98 L->Name = GetStringId (Name);
103 /* Return the new struct */
109 static void FreeLibrary (Library* L)
110 /* Free a library structure */
112 /* Close the library file */
113 if (fclose (L->F) != 0) {
114 Error ("Error closing `%s': %s", GetString (L->Name), strerror (errno));
117 /* Free the module index */
120 /* Free the library structure */
126 /*****************************************************************************/
127 /* Reading file data structures */
128 /*****************************************************************************/
132 static void LibSeek (Library* L, unsigned long Offs)
133 /* Do a seek in the library checking for errors */
135 if (fseek (L->F, Offs, SEEK_SET) != 0) {
136 Error ("Seek error in `%s' (%lu): %s",
137 GetString (L->Name), Offs, strerror (errno));
143 static void LibReadHeader (Library* L)
144 /* Read a library header */
146 /* Read the remaining header fields (magic is already read) */
147 L->Header.Magic = LIB_MAGIC;
148 L->Header.Version = Read16 (L->F);
149 if (L->Header.Version != LIB_VERSION) {
150 Error ("Wrong data version in `%s'", GetString (L->Name));
152 L->Header.Flags = Read16 (L->F);
153 L->Header.IndexOffs = Read32 (L->F);
158 static void LibReadObjHeader (Library* L, ObjData* O)
159 /* Read the header of the object file checking the signature */
161 O->Header.Magic = Read32 (L->F);
162 if (O->Header.Magic != OBJ_MAGIC) {
163 Error ("Object file `%s' in library `%s' is invalid",
164 GetObjFileName (O), GetString (L->Name));
166 O->Header.Version = Read16 (L->F);
167 if (O->Header.Version != OBJ_VERSION) {
168 Error ("Object file `%s' in library `%s' has wrong version",
169 GetObjFileName (O), GetString (L->Name));
171 O->Header.Flags = Read16 (L->F);
172 O->Header.OptionOffs = Read32 (L->F);
173 O->Header.OptionSize = Read32 (L->F);
174 O->Header.FileOffs = Read32 (L->F);
175 O->Header.FileSize = Read32 (L->F);
176 O->Header.SegOffs = Read32 (L->F);
177 O->Header.SegSize = Read32 (L->F);
178 O->Header.ImportOffs = Read32 (L->F);
179 O->Header.ImportSize = Read32 (L->F);
180 O->Header.ExportOffs = Read32 (L->F);
181 O->Header.ExportSize = Read32 (L->F);
182 O->Header.DbgSymOffs = Read32 (L->F);
183 O->Header.DbgSymSize = Read32 (L->F);
184 O->Header.LineInfoOffs = Read32 (L->F);
185 O->Header.LineInfoSize = Read32 (L->F);
186 O->Header.StrPoolOffs = Read32 (L->F);
187 O->Header.StrPoolSize = Read32 (L->F);
188 O->Header.AssertOffs = Read32 (L->F);
189 O->Header.AssertSize = Read32 (L->F);
190 O->Header.ScopeOffs = Read32 (L->F);
191 O->Header.ScopeSize = Read32 (L->F);
196 static ObjData* ReadIndexEntry (Library* L)
197 /* Read one entry in the index */
199 /* Create a new entry and insert it into the list */
200 ObjData* O = NewObjData ();
203 O->Name = ReadStr (L->F);
205 /* Module flags/MTime/Start/Size */
206 O->Flags = Read16 (L->F);
207 O->MTime = Read32 (L->F);
208 O->Start = Read32 (L->F);
209 Read32 (L->F); /* Skip Size */
211 /* Read the string pool */
212 ObjReadStrPool (L->F, FileGetPos (L->F), O);
214 /* Skip the import size, then read the imports */
215 (void) ReadVar (L->F);
216 ObjReadImports (L->F, FileGetPos (L->F), O);
218 /* Skip the export size, then read the exports */
219 (void) ReadVar (L->F);
220 ObjReadExports (L->F, FileGetPos (L->F), O);
228 static void LibReadIndex (Library* L)
229 /* Read the index of a library file */
233 /* Seek to the start of the index */
234 LibSeek (L, L->Header.IndexOffs);
236 /* Read the object file count and allocate memory */
237 L->ModCount = ReadVar (L->F);
238 L->Modules = xmalloc (L->ModCount * sizeof (L->Modules[0]));
240 /* Read all entries in the index */
241 for (I = 0; I < L->ModCount; ++I) {
242 L->Modules[I] = ReadIndexEntry (L);
248 /*****************************************************************************/
249 /* High level stuff */
250 /*****************************************************************************/
254 static void LibCheckExports (ObjData* O)
255 /* Check if the exports from this file can satisfy any import requests. If so,
256 * insert the imports and exports from this file and mark the file as added.
261 /* Check all exports */
262 for (I = 0; I < CollCount (&O->Exports); ++I) {
263 const Export* E = CollConstAt (&O->Exports, I);
264 if (IsUnresolved (E->Name)) {
265 /* We need this module, insert the imports and exports */
267 InsertObjGlobals (O);
275 static void LibOpen (FILE* F, const char* Name)
276 /* Open the library for use */
278 /* Create a new library structure */
279 Library* L = NewLibrary (F, Name);
281 /* Read the remaining header fields (magic is already read) */
284 /* Seek to the index position and read the index */
287 /* Add the library to the list of open libraries */
288 CollAppend (&OpenLibs, L);
293 static void LibResolve (void)
294 /* Resolve all externals from the list of all currently open libraries */
299 /* Walk repeatedly over all open libraries until there's nothing more
306 /* Walk over all libraries */
307 for (I = 0; I < CollCount (&OpenLibs); ++I) {
309 /* Get the next library */
310 Library* L = CollAt (&OpenLibs, I);
312 /* Walk through all modules in this library and check for each
313 * module if there are unresolved externals in existing modules
314 * that may be resolved by adding the module.
316 for (J = 0; J < L->ModCount; ++J) {
318 /* Get the next module */
319 ObjData* O = L->Modules[J];
321 /* We only need to check this module if it wasn't added before */
322 if ((O->Flags & OBJ_REF) == 0) {
324 if (O->Flags & OBJ_REF) {
325 /* The routine added the file */
332 } while (Additions > 0);
334 /* We do know now which modules must be added, so we can load the data
335 * for these modues into memory. Since we're walking over all modules
336 * anyway, we will also remove data for unneeded modules.
338 for (I = 0; I < CollCount (&OpenLibs); ++I) {
340 /* Get the next library */
341 Library* L = CollAt (&OpenLibs, I);
343 /* Walk over all modules in this library and add the files list and
344 * sections for all referenced modules.
346 for (J = 0; J < L->ModCount; ++J) {
348 /* Get the object data */
349 ObjData* O = L->Modules[J];
351 /* Is this object file referenced? */
352 if (O->Flags & OBJ_REF) {
354 /* Seek to the start of the object file and read the header */
355 LibSeek (L, O->Start);
356 LibReadObjHeader (L, O);
358 /* Seek to the start of the files list and read the files list */
359 ObjReadFiles (L->F, O->Start + O->Header.FileOffs, O);
361 /* Seek to the start of the debug info and read the debug info */
362 ObjReadDbgSyms (L->F, O->Start + O->Header.DbgSymOffs, O);
364 /* Seek to the start of the line infos and read them */
365 ObjReadLineInfos (L->F, O->Start + O->Header.LineInfoOffs, O);
367 /* Read the assertions from the object file */
368 ObjReadAssertions (L->F, O->Start + O->Header.AssertOffs, O);
370 /* Read the scope table from the object file */
371 ObjReadScopes (L->F, O->Start + O->Header.ScopeOffs, O);
373 /* Seek to the start of the segment list and read the segments.
374 * This must be last, since the data here may reference other
377 ObjReadSections (L->F, O->Start + O->Header.SegOffs, O);
379 /* Remember from which library this module is */
380 O->LibName = L->Name;
382 /* All references to strings are now resolved, so we can delete
383 * the module string pool.
387 /* Insert the object into the list of all used object files */
392 /* Unreferenced object file, remove it */
398 /* Close the file and delete the library data */
402 /* We're done with all open libraries, clear the OpenLibs collection */
403 CollDeleteAll (&OpenLibs);
408 void LibAdd (FILE* F, const char* Name)
409 /* Add files from the library to the list if there are references that could
413 /* Add the library to the list of open libraries */
416 /* If there is no library group open, just resolve all open symbols and
417 * close the library. Otherwise we will do nothing because resolving will
418 * be done when the group is closed.
427 void LibStartGroup (void)
428 /* Start a library group. Objects within a library group may reference each
429 * other, and libraries are searched repeatedly until all references are
433 /* We cannot already have a group open */
435 Error ("There's already a library group open");
438 /* Start a new group */
444 void LibEndGroup (void)
445 /* End a library group and resolve all open references. Objects within a
446 * library group may reference each other, and libraries are searched
447 * repeatedly until all references are satisfied.
450 /* We must have a library group open */
452 Error ("There's no library group open");
455 /* Resolve symbols, end the group */
462 void LibCheckGroup (void)
463 /* Check if there are open library groups */
466 Error ("Library group was never closed");