1 /*****************************************************************************/
5 /* Library data structures and helpers for the ld65 linker */
9 /* (C) 1998-2005 Ullrich von Bassewitz */
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 export size, then read the exports */
215 (void) ReadVar (L->F);
216 ObjReadExports (L->F, FileGetPos (L->F), O);
218 /* Skip the import size, then read the imports */
219 (void) ReadVar (L->F);
220 ObjReadImports (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 < O->ExportCount; ++I) {
263 if (IsUnresolved (O->Exports[I]->Name)) {
264 /* We need this module */
265 O->Flags |= OBJ_REF; break;
269 /* If we need this module, insert the imports and exports */
270 if (O->Flags & OBJ_REF) {
271 InsertObjGlobals (O);
277 static void LibOpen (FILE* F, const char* Name)
278 /* Open the library for use */
280 /* Create a new library structure */
281 Library* L = NewLibrary (F, Name);
283 /* Read the remaining header fields (magic is already read) */
286 /* Seek to the index position and read the index */
289 /* Add the library to the list of open libraries */
290 CollAppend (&OpenLibs, L);
295 static void LibResolve (void)
296 /* Resolve all externals from the list of all currently open libraries */
301 /* Walk repeatedly over all open libraries until there's nothing more
308 /* Walk over all libraries */
309 for (I = 0; I < CollCount (&OpenLibs); ++I) {
311 /* Get the next library */
312 Library* L = CollAt (&OpenLibs, I);
314 /* Walk through all modules in this library and check for each
315 * module if there are unresolved externals in existing modules
316 * that may be resolved by adding the module.
318 for (J = 0; J < L->ModCount; ++J) {
320 /* Get the next module */
321 ObjData* O = L->Modules[J];
323 /* We only need to check this module if it wasn't added before */
324 if ((O->Flags & OBJ_REF) == 0) {
326 if (O->Flags & OBJ_REF) {
327 /* The routine added the file */
334 } while (Additions > 0);
336 /* We do know now which modules must be added, so we can load the data
337 * for these modues into memory. Since we're walking over all modules
338 * anyway, we will also remove data for unneeded modules.
340 for (I = 0; I < CollCount (&OpenLibs); ++I) {
342 /* Get the next library */
343 Library* L = CollAt (&OpenLibs, I);
345 /* Walk over all modules in this library and add the files list and
346 * sections for all referenced modules.
348 for (J = 0; J < L->ModCount; ++J) {
350 /* Get the object data */
351 ObjData* O = L->Modules[J];
353 /* Is this object file referenced? */
354 if (O->Flags & OBJ_REF) {
356 /* Seek to the start of the object file and read the header */
357 LibSeek (L, O->Start);
358 LibReadObjHeader (L, O);
360 /* Seek to the start of the files list and read the files list */
361 ObjReadFiles (L->F, O->Start + O->Header.FileOffs, O);
363 /* Seek to the start of the debug info and read the debug info */
364 ObjReadDbgSyms (L->F, O->Start + O->Header.DbgSymOffs, O);
366 /* Seek to the start of the line infos and read them */
367 ObjReadLineInfos (L->F, O->Start + O->Header.LineInfoOffs, O);
369 /* Read the assertions from the object file */
370 ObjReadAssertions (L->F, O->Start + O->Header.AssertOffs, O);
372 /* Read the scope table from the object file */
373 ObjReadScopes (L->F, O->Start + O->Header.ScopeOffs, O);
375 /* Seek to the start of the segment list and read the segments.
376 * This must be last, since the data here may reference other
379 ObjReadSections (L->F, O->Start + O->Header.SegOffs, O);
381 /* Remember from which library this module is */
382 O->LibName = L->Name;
384 /* All references to strings are now resolved, so we can delete
385 * the module string pool.
389 /* Insert the object into the list of all used object files */
394 /* Unreferenced object file, remove it */
400 /* Close the file and delete the library data */
404 /* We're done with all open libraries, clear the OpenLibs collection */
405 CollDeleteAll (&OpenLibs);
410 void LibAdd (FILE* F, const char* Name)
411 /* Add files from the library to the list if there are references that could
415 /* Add the library to the list of open libraries */
418 /* If there is no library group open, just resolve all open symbols and
419 * close the library. Otherwise we will do nothing because resolving will
420 * be done when the group is closed.
429 void LibStartGroup (void)
430 /* Start a library group. Objects within a library group may reference each
431 * other, and libraries are searched repeatedly until all references are
435 /* We cannot already have a group open */
437 Error ("There's already a library group open");
440 /* Start a new group */
446 void LibEndGroup (void)
447 /* End a library group and resolve all open references. Objects within a
448 * library group may reference each other, and libraries are searched
449 * repeatedly until all references are satisfied.
452 /* We must have a library group open */
454 Error ("There's no library group open");
457 /* Resolve symbols, end the group */
464 void LibCheckGroup (void)
465 /* Check if there are open library groups */
468 Error ("Library group was never closed");