1 /*****************************************************************************/
5 /* Library data structures and helpers for the ld65 linker */
9 /* (C) 1998-2011, 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 Collection Modules; /* Modules */
75 /* List of open libraries */
76 static Collection OpenLibs = STATIC_COLLECTION_INITIALIZER;
78 /* Flag for library grouping */
79 static int Grouping = 0;
83 /*****************************************************************************/
85 /*****************************************************************************/
89 static Library* NewLibrary (FILE* F, const char* Name)
90 /* Create a new Library structure and return it */
93 Library* L = xmalloc (sizeof (*L));
95 /* Initialize the fields */
97 L->Name = GetStringId (Name);
99 L->Modules = EmptyCollection;
101 /* Return the new struct */
107 static void FreeLibrary (Library* L)
108 /* Free a library structure */
110 /* Close the library file */
111 if (fclose (L->F) != 0) {
112 Error ("Error closing `%s': %s", GetString (L->Name), strerror (errno));
115 /* Free the module index */
116 DoneCollection (&L->Modules);
118 /* Free the library structure */
124 /*****************************************************************************/
125 /* Reading file data structures */
126 /*****************************************************************************/
130 static void LibSeek (Library* L, unsigned long Offs)
131 /* Do a seek in the library checking for errors */
133 if (fseek (L->F, Offs, SEEK_SET) != 0) {
134 Error ("Seek error in `%s' (%lu): %s",
135 GetString (L->Name), Offs, strerror (errno));
141 static void LibReadHeader (Library* L)
142 /* Read a library header */
144 /* Read the remaining header fields (magic is already read) */
145 L->Header.Magic = LIB_MAGIC;
146 L->Header.Version = Read16 (L->F);
147 if (L->Header.Version != LIB_VERSION) {
148 Error ("Wrong data version in `%s'", GetString (L->Name));
150 L->Header.Flags = Read16 (L->F);
151 L->Header.IndexOffs = Read32 (L->F);
156 static void LibReadObjHeader (Library* L, ObjData* O)
157 /* Read the header of the object file checking the signature */
159 O->Header.Magic = Read32 (L->F);
160 if (O->Header.Magic != OBJ_MAGIC) {
161 Error ("Object file `%s' in library `%s' is invalid",
162 GetObjFileName (O), GetString (L->Name));
164 O->Header.Version = Read16 (L->F);
165 if (O->Header.Version != OBJ_VERSION) {
166 Error ("Object file `%s' in library `%s' has wrong version",
167 GetObjFileName (O), GetString (L->Name));
169 O->Header.Flags = Read16 (L->F);
170 O->Header.OptionOffs = Read32 (L->F);
171 O->Header.OptionSize = Read32 (L->F);
172 O->Header.FileOffs = Read32 (L->F);
173 O->Header.FileSize = Read32 (L->F);
174 O->Header.SegOffs = Read32 (L->F);
175 O->Header.SegSize = Read32 (L->F);
176 O->Header.ImportOffs = Read32 (L->F);
177 O->Header.ImportSize = Read32 (L->F);
178 O->Header.ExportOffs = Read32 (L->F);
179 O->Header.ExportSize = Read32 (L->F);
180 O->Header.DbgSymOffs = Read32 (L->F);
181 O->Header.DbgSymSize = Read32 (L->F);
182 O->Header.LineInfoOffs = Read32 (L->F);
183 O->Header.LineInfoSize = Read32 (L->F);
184 O->Header.StrPoolOffs = Read32 (L->F);
185 O->Header.StrPoolSize = Read32 (L->F);
186 O->Header.AssertOffs = Read32 (L->F);
187 O->Header.AssertSize = Read32 (L->F);
188 O->Header.ScopeOffs = Read32 (L->F);
189 O->Header.ScopeSize = Read32 (L->F);
194 static ObjData* ReadIndexEntry (Library* L)
195 /* Read one entry in the index */
197 /* Create a new entry and insert it into the list */
198 ObjData* O = NewObjData ();
200 /* Remember from which library this module is */
201 O->LibName = L->Name;
204 O->Name = ReadStr (L->F);
206 /* Module flags/MTime/Start/Size */
207 O->Flags = Read16 (L->F);
208 O->MTime = Read32 (L->F);
209 O->Start = Read32 (L->F);
210 Read32 (L->F); /* Skip Size */
218 static void ReadBasicData (Library* L, ObjData* O)
219 /* Read basic data for an object file that is necessary to resolve external
223 /* Seek to the start of the object file and read the header */
224 LibSeek (L, O->Start);
225 LibReadObjHeader (L, O);
227 /* Read the string pool */
228 ObjReadStrPool (L->F, O->Start + O->Header.StrPoolOffs, O);
230 /* Read the files list */
231 ObjReadFiles (L->F, O->Start + O->Header.FileOffs, O);
233 /* Read the line infos */
234 ObjReadLineInfos (L->F, O->Start + O->Header.LineInfoOffs, O);
236 /* Read the imports */
237 ObjReadImports (L->F, O->Start + O->Header.ImportOffs, O);
239 /* Read the exports */
240 ObjReadExports (L->F, O->Start + O->Header.ExportOffs, O);
245 static void LibReadIndex (Library* L)
246 /* Read the index of a library file */
248 unsigned ModuleCount, I;
250 /* Seek to the start of the index */
251 LibSeek (L, L->Header.IndexOffs);
253 /* Read the object file count and allocate memory */
254 ModuleCount = ReadVar (L->F);
255 CollGrow (&L->Modules, ModuleCount);
257 /* Read all entries in the index */
258 while (ModuleCount--) {
259 CollAppend (&L->Modules, ReadIndexEntry (L));
262 /* Walk over the index and read basic data for all object files in the
265 for (I = 0; I < CollCount (&L->Modules); ++I) {
266 ReadBasicData (L, CollAtUnchecked (&L->Modules, I));
272 /*****************************************************************************/
273 /* High level stuff */
274 /*****************************************************************************/
278 static void LibCheckExports (ObjData* O)
279 /* Check if the exports from this file can satisfy any import requests. If so,
280 * insert the imports and exports from this file and mark the file as added.
285 /* Check all exports */
286 for (I = 0; I < CollCount (&O->Exports); ++I) {
287 const Export* E = CollConstAt (&O->Exports, I);
288 if (IsUnresolved (E->Name)) {
289 /* We need this module, insert the imports and exports */
291 InsertObjGlobals (O);
299 static void LibOpen (FILE* F, const char* Name)
300 /* Open the library for use */
302 /* Create a new library structure */
303 Library* L = NewLibrary (F, Name);
305 /* Read the remaining header fields (magic is already read) */
308 /* Seek to the index position and read the index */
311 /* Add the library to the list of open libraries */
312 CollAppend (&OpenLibs, L);
317 static void LibResolve (void)
318 /* Resolve all externals from the list of all currently open libraries */
323 /* Walk repeatedly over all open libraries until there's nothing more
330 /* Walk over all libraries */
331 for (I = 0; I < CollCount (&OpenLibs); ++I) {
333 /* Get the next library */
334 Library* L = CollAt (&OpenLibs, I);
336 /* Walk through all modules in this library and check for each
337 * module if there are unresolved externals in existing modules
338 * that may be resolved by adding the module.
340 for (J = 0; J < CollCount (&L->Modules); ++J) {
342 /* Get the next module */
343 ObjData* O = CollAtUnchecked (&L->Modules, J);
345 /* We only need to check this module if it wasn't added before */
346 if ((O->Flags & OBJ_REF) == 0) {
348 if (O->Flags & OBJ_REF) {
349 /* The routine added the file */
356 } while (Additions > 0);
358 /* We do know now which modules must be added, so we can load the data
359 * for these modues into memory. Since we're walking over all modules
360 * anyway, we will also remove data for unneeded modules.
362 for (I = 0; I < CollCount (&OpenLibs); ++I) {
364 /* Get the next library */
365 Library* L = CollAt (&OpenLibs, I);
367 /* Walk over all modules in this library and add the files list and
368 * sections for all referenced modules.
370 for (J = 0; J < CollCount (&L->Modules); ++J) {
372 /* Get the object data */
373 ObjData* O = CollAtUnchecked (&L->Modules, J);
375 /* Is this object file referenced? */
376 if (O->Flags & OBJ_REF) {
378 /* Seek to the start of the debug info and read the debug info */
379 ObjReadDbgSyms (L->F, O->Start + O->Header.DbgSymOffs, O);
381 /* Read the assertions from the object file */
382 ObjReadAssertions (L->F, O->Start + O->Header.AssertOffs, O);
384 /* Read the scope table from the object file */
385 ObjReadScopes (L->F, O->Start + O->Header.ScopeOffs, O);
387 /* Seek to the start of the segment list and read the segments.
388 * This must be last, since the data here may reference other
391 ObjReadSections (L->F, O->Start + O->Header.SegOffs, O);
393 /* All references to strings are now resolved, so we can delete
394 * the module string pool.
398 /* Insert the object into the list of all used object files */
403 /* Unreferenced object file, remove it */
409 /* Close the file and delete the library data */
413 /* We're done with all open libraries, clear the OpenLibs collection */
414 CollDeleteAll (&OpenLibs);
419 void LibAdd (FILE* F, const char* Name)
420 /* Add files from the library to the list if there are references that could
424 /* Add the library to the list of open libraries */
427 /* If there is no library group open, just resolve all open symbols and
428 * close the library. Otherwise we will do nothing because resolving will
429 * be done when the group is closed.
438 void LibStartGroup (void)
439 /* Start a library group. Objects within a library group may reference each
440 * other, and libraries are searched repeatedly until all references are
444 /* We cannot already have a group open */
446 Error ("There's already a library group open");
449 /* Start a new group */
455 void LibEndGroup (void)
456 /* End a library group and resolve all open references. Objects within a
457 * library group may reference each other, and libraries are searched
458 * repeatedly until all references are satisfied.
461 /* We must have a library group open */
463 Error ("There's no library group open");
466 /* Resolve symbols, end the group */
473 void LibCheckGroup (void)
474 /* Check if there are open library groups */
477 Error ("Library group was never closed");