1 /* lksdcclib.c - sdcc library format handling
3 Copyright (C) 1989-1995 Alan R. Baldwin
4 721 Berkeley St., Kent, Ohio 44240
5 Copyright (C) 2008 Borut Razem, borut dot razem at siol dot net
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 * With contributions for the
23 * object libraries from
25 * kenh@cmf.nrl.navy.mil
30 * Extensions: P. Felber
41 #define EQ(A,B) !strcmp((A),(B))
42 #define MAXLINE 254 /*when using getline */
46 is_sdcclib (FILE * libfp)
48 #define SDCCLIB_MAGIC "<SDCCLIB>"
49 #define SDCCLIB_MAGIC_LEN (sizeof ("<SDCCLIB>") - 1)
51 char buf[SDCCLIB_MAGIC_LEN];
53 if (fread (buf, 1, sizeof (buf), libfp) == sizeof (buf) && memcmp (buf, SDCCLIB_MAGIC, SDCCLIB_MAGIC_LEN) == 0)
58 if (getc (libfp) == '\n')
69 /* Load a .rel file embedded in a sdcclib file */
71 LoadRel (char *libfname, FILE * libfp, char *ModName)
76 while (getline (str, sizeof (str), libfp) != NULL)
81 if (EQ (str, "<FILE>"))
83 if (NULL != getline (str, sizeof (str), libfp) && EQ (str, ModName))
93 return EQ (str, "<REL>") ? load_rel (libfp, -1) : 0;
102 buildlibraryindex_sdcclib (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int type)
106 long IndexOffset = 0;
107 pmlibrarysymbol ThisSym = NULL;
109 while (getline (FLine, sizeof (FLine), libfp))
114 if (EQ (FLine, "<INDEX>"))
116 /*The next line has the size of the index */
117 getline (FLine, sizeof (FLine), libfp);
118 IndexOffset = atol (FLine);
124 if (EQ (FLine, "<MODULE>"))
127 char ModName[NCPS] = "";
130 /* The next line has the name of the module and the offset
131 of the corresponding embedded file in the library */
132 getline (FLine, sizeof (FLine), libfp);
133 sscanf (FLine, "%s %ld", ModName, &FileOffset);
136 /* Create a new libraryfile object for this module */
139 libr = This = (pmlibraryfile) new (sizeof (mlibraryfile));
143 This->next = (pmlibraryfile) new (sizeof (mlibraryfile));
148 This->offset = FileOffset + IndexOffset;
149 This->libspc = lbnh->libspc;
150 This->relfil = strdup (ModName);
151 sprintf (buff, "%s%s%c%s", lbnh->path, ModName, FSEPX, LKOBJEXT);
152 This->filspc = strdup (buff);
155 This->symbols = ThisSym = NULL; /* Start a new linked list of symbols */
157 else if (EQ (FLine, "</INDEX>"))
159 return This; /* Finish, get out of here */
164 if (EQ (FLine, "</MODULE>"))
167 /* Create the index for the next module */
172 /* Add the symbols */
173 if (ThisSym == NULL) /* First symbol of the current module */
175 ThisSym = This->symbols = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
179 ThisSym->next = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
180 ThisSym = ThisSym->next;
182 ThisSym->next = NULL;
183 ThisSym->name = strdup (FLine);
188 return This; /* State machine should never reach this point, but just in case... */
193 return This; /* State machine should never reach this point, but just in case... */
198 /* Load an .adb file embedded in a sdcclib file. If there is
199 something between <ADB> and </ADB> returns 1, otherwise returns 0.
200 This way the aomf51 will not have useless empty modules. */
203 LoadAdb (FILE * libfp)
209 while (getline (str, sizeof (str), libfp) != NULL)
214 if (EQ (str, "<ADB>"))
219 if (EQ (str, "</ADB>"))
221 fprintf (dfp, "%s\n", str);
229 /* Check for a symbol in a SDCC library. If found, add the embedded .rel and
230 .adb files from the library. The library must be created with the SDCC
231 librarian 'sdcclib' since the linking process depends on the correct file offsets
232 embedded in the library file. */
235 findsym_sdcclib (const char *name, struct lbname *lbnh, FILE * libfp, int type)
238 char ModName[NCPS] = "";
241 long IndexOffset = 0, FileOffset;
243 while (getline (FLine, sizeof (FLine), libfp))
245 char filspc[PATH_MAX];
247 if (lbnh->path != NULL)
249 strcpy (filspc, lbnh->path);
251 if (*filspc != '\0' && (filspc[strlen (filspc) - 1] != '/') && (filspc[strlen (filspc) - 1] != LKDIRSEP))
253 strcat (filspc, LKDIRSEPSTR);
261 if (EQ (FLine, "<INDEX>"))
263 /* The next line has the size of the index */
264 getline (FLine, sizeof (FLine), libfp);
265 IndexOffset = atol (FLine);
271 if (EQ (FLine, "<MODULE>"))
273 /* The next line has the name of the module and the offset
274 of the corresponding embedded file in the library */
275 getline (FLine, sizeof (FLine), libfp);
276 sscanf (FLine, "%s %ld", ModName, &FileOffset);
279 else if (EQ (FLine, "</INDEX>"))
281 /* Reached the end of the index. The symbol is not in this library. */
287 if (EQ (FLine, "</MODULE>"))
289 /* The symbol is not in this module, try the next one */
294 /* Check if this is the symbol we are looking for. */
295 if (strncmp (name, FLine, NCPS) == 0)
297 /* The symbol is in this module. */
299 /* As in the original library format, it is assumed that the .rel
300 files reside in the same directory as the lib files. */
301 sprintf (&filspc[strlen (filspc)], "%s%c%s", ModName, FSEPX, LKOBJEXT);
303 /* If this module has been loaded already don't load it again. */
304 if (is_module_loaded (filspc))
307 /* Add the embedded file to the list of files to be loaded in
308 the second pass. That is performed latter by the function
310 lbfh = (struct lbfile *) new (sizeof (struct lbfile));
319 for (lbf = lbfhead; lbf->next; lbf = lbf->next)
325 lbfh->libspc = lbnh->libspc;
326 lbfh->filspc = strdup (filspc);
327 lbfh->relfil = strdup (ModName);
328 /* Library embedded file, so lbfh->offset must be >=0 */
329 lbfh->offset = IndexOffset + FileOffset;
331 /* Jump to where the .rel begins and load it. */
332 fseek (libfp, lbfh->offset, SEEK_SET);
333 if (!LoadRel (lbnh->libspc, libfp, ModName))
336 fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbfh->libspc, ModName);
339 /* if cdb information required & .adb file present */
343 SaveLinkedFilePath (filspc);
345 return 1; /* Found the symbol, so success! */
351 return 0; /* It should never reach this point, but just in case... */
356 return 0; /* The symbol is not in this library */
362 loadfile_sdcclib (struct lbfile *lbfh)
368 char posix_path[PATH_MAX];
369 void cygwin_conv_to_full_posix_path (char *win_path, char *posix_path);
370 cygwin_conv_to_full_posix_path (lbfh->libspc, posix_path);
371 fp = fopen (posix_path, "rb");
373 fp = fopen (lbfh->libspc, "rb");
378 fseek (fp, lbfh->offset, SEEK_SET);
379 res = LoadRel (lbfh->libspc, fp, lbfh->relfil);
384 fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbfh->libspc, lbfh->relfil);
390 fprintf (stderr, "?ASlink-Error-Opening library '%s'\n", lbfh->libspc);
395 struct aslib_target aslib_target_sdcclib = {
398 &buildlibraryindex_sdcclib,