]> git.sur5r.net Git - cc65/blob - src/ld65/library.c
This commit was generated by cvs2svn to compensate for changes in r2,
[cc65] / src / ld65 / library.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 library.c                                 */
4 /*                                                                           */
5 /*          Library data structures and helpers for the ld65 linker          */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998     Ullrich von Bassewitz                                        */
10 /*              Wacholderweg 14                                              */
11 /*              D-70597 Stuttgart                                            */
12 /* EMail:       uz@musoftware.de                                             */
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 <stdio.h>
37 #include <string.h>
38 #include <errno.h>
39
40 #include "../common/objdefs.h"
41 #include "../common/libdefs.h"
42 #include "../common/symdefs.h"
43 #include "../common/exprdefs.h"
44 #include "../common/filepos.h"
45
46 #include "mem.h"
47 #include "error.h"
48 #include "fileio.h"
49 #include "objdata.h"
50 #include "objfile.h"
51 #include "exports.h"
52 #include "library.h"
53
54
55
56 /*****************************************************************************/
57 /*                                   Data                                    */
58 /*****************************************************************************/
59
60
61
62 /* Library data */
63 static FILE*            Lib             = 0;
64 static char*            LibName         = 0;
65 static unsigned         ModuleCount     = 0;
66 static ObjData**        Index           = 0;
67
68
69
70 /*****************************************************************************/
71 /*                       Reading file data structures                        */
72 /*****************************************************************************/
73
74
75
76 static void LibReadObjHeader (ObjData* O)
77 /* Read the header of the object file checking the signature */
78 {
79     O->Header.Magic      = Read32 (Lib);
80     if (O->Header.Magic != OBJ_MAGIC) {
81         Error ("Object file `%s' in library `%s' is invalid", O->Name, LibName);
82     }
83     O->Header.Version    = Read16 (Lib);
84     if (O->Header.Version != OBJ_VERSION) {
85         Error ("Object file `%s' in library `%s' has wrong version",
86                O->Name, LibName);
87     }
88     O->Header.Flags      = Read16 (Lib);
89     O->Header.OptionOffs = Read32 (Lib);
90     O->Header.OptionSize = Read32 (Lib);
91     O->Header.FileOffs   = Read32 (Lib);
92     O->Header.FileSize   = Read32 (Lib);
93     O->Header.SegOffs    = Read32 (Lib);
94     O->Header.SegSize    = Read32 (Lib);
95     O->Header.ImportOffs = Read32 (Lib);
96     O->Header.ImportSize = Read32 (Lib);
97     O->Header.ExportOffs = Read32 (Lib);
98     O->Header.ExportSize = Read32 (Lib);
99     O->Header.DbgSymOffs = Read32 (Lib);
100     O->Header.DbgSymSize = Read32 (Lib);                                        
101 }
102
103
104
105 static ObjData* ReadIndexEntry (void)
106 /* Read one entry in the index */
107 {
108     unsigned I;
109
110     /* Create a new entry and insert it into the list */
111     ObjData* O  = NewObjData ();
112
113     /* Module name/flags/MTime/Start/Size */
114     O->Name     = ReadMallocedStr (Lib);
115     O->Flags    = Read16 (Lib);
116     Read32 (Lib);                       /* Skip MTime */
117     O->Start    = Read32 (Lib);
118     Read32 (Lib);                       /* Skip Size */
119
120     /* Skip the export size, then read the exports */
121     Read16 (Lib);
122     O->ExportCount = Read16 (Lib);
123     O->Exports = Xmalloc (O->ExportCount * sizeof (Export*));
124     for (I = 0; I < O->ExportCount; ++I) {
125         O->Exports [I] = ReadExport (Lib, O);
126     }
127
128     /* Skip the import size, then read the imports */
129     Read16 (Lib);
130     O->ImportCount = Read16 (Lib);
131     O->Imports = Xmalloc (O->ImportCount * sizeof (Import*));
132     for (I = 0; I < O->ImportCount; ++I) {
133         O->Imports [I] = ReadImport (Lib, O);
134     }
135
136     /* Done */
137     return O;
138 }
139
140
141
142 static void ReadIndex (void)
143 /* Read the index of a library file */
144 {
145     unsigned I;
146
147     /* Read the object file count and allocate memory */
148     ModuleCount = Read16 (Lib);
149     Index = Xmalloc (ModuleCount * sizeof (ObjData*));
150
151     /* Read all entries in the index */
152     for (I = 0; I < ModuleCount; ++I) {
153         Index [I] = ReadIndexEntry ();
154     }
155 }
156
157
158
159 /*****************************************************************************/
160 /*                             High level stuff                              */
161 /*****************************************************************************/
162
163
164
165 static void LibCheckExports (ObjData* O)
166 /* Check if the exports from this file can satisfy any import requests. If so,
167  * insert the imports and exports from this file and mark the file as added.
168  */
169 {
170     unsigned I;
171
172     /* Check all exports */
173     for (I = 0; I < O->ExportCount; ++I) {
174         if (IsUnresolved (O->Exports [I]->Name)) {
175             /* We need this module */
176             O->Flags |= OBJ_REF;
177             break;
178         }
179     }
180
181     /* If we need this module, insert the imports and exports */
182     if (O->Flags & OBJ_REF) {
183         /* Insert the exports */
184         for (I = 0; I < O->ExportCount; ++I) {
185             InsertExport (O->Exports [I]);
186         }
187         /* Insert the imports */
188         for (I = 0; I < O->ImportCount; ++I) {
189             InsertImport (O->Imports [I]);
190         }
191     }
192 }
193
194
195
196 void LibAdd (FILE* F, const char* Name)
197 /* Add files from the library to the list if there are references that could
198  * be satisfied.
199  */
200 {
201     int Add;
202     unsigned I;
203     LibHeader Header;
204
205     /* Store the parameters, so they're visible for other routines */
206     Lib     = F;
207     LibName = StrDup (Name);
208
209     /* Read the remaining header fields (magic is already read) */
210     Header.Magic   = LIB_MAGIC;
211     Header.Version = Read16 (Lib);
212     if (Header.Version != LIB_VERSION) {
213         Error ("Wrong data version in `%s'", Name);
214     }
215     Header.Flags   = Read16 (Lib);
216     Header.IndexOffs = Read32 (Lib);
217
218     /* Seek to the index position and read the index */
219     fseek (Lib, Header.IndexOffs, SEEK_SET);
220     ReadIndex ();
221
222     /* Walk through all library modules and check for each module if there
223      * are unresolved externals in existing modules that may be resolved
224      * by adding the module. Repeat this step until no more object files
225      * were added.
226      */
227     do {
228         Add = 0;
229         for (I = 0; I < ModuleCount; ++I) {
230             ObjData* O = Index [I];
231             if ((O->Flags & OBJ_REF) == 0) {
232                 LibCheckExports (O);
233                 if (O->Flags & OBJ_REF) {
234                     /* The routine added the file */
235                     Add = 1;
236                 }
237             }
238         }
239     } while (Add);
240
241     /* Add the files list and sections for all requested modules */
242     for (I = 0; I < ModuleCount; ++I) {
243         ObjData* O = Index [I];
244         if (O->Flags & OBJ_REF) {
245
246             /* Seek to the start of the object file and read the header */
247             fseek (Lib, O->Start, SEEK_SET);
248             LibReadObjHeader (O);
249
250             /* Seek to the start of the files list and read the files list */
251             fseek (Lib, O->Start + O->Header.FileOffs, SEEK_SET);
252             ObjReadFiles (Lib, O);
253
254             /* Seek to the start of the segment list and read the segments */
255             fseek (Lib, O->Start + O->Header.SegOffs, SEEK_SET);
256             ObjReadSections (Lib, O);
257
258             /* Seek to the start of the debug info and read the debug info */
259             fseek (Lib, O->Start + O->Header.DbgSymOffs, SEEK_SET);
260             ObjReadDbgSyms (Lib, O);
261
262             /* We have the data now */
263             O->Flags |= OBJ_HAVEDATA;
264
265         }
266
267         /* Add a pointer to the library name */
268         O->LibName = LibName;
269     }
270
271     /* Done. Close the file, release allocated memory */
272     fclose (F);
273     Xfree (Index);
274     Lib         = 0;
275     LibName     = 0;
276     ModuleCount = 0;
277     Index       = 0;
278 }
279
280
281
282
283
284
285