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 3, 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, see <http://www.gnu.org/licenses/>. */
21 * With contributions for the
22 * object libraries from
24 * kenh@cmf.nrl.navy.mil
29 * Extensions: P. Felber
40 #define EQ(A,B) !strcmp((A),(B))
41 #define MAXLINE 254 /*when using getline */
45 is_sdcclib (FILE * libfp)
47 #define SDCCLIB_MAGIC "<SDCCLIB>"
48 #define SDCCLIB_MAGIC_LEN (sizeof ("<SDCCLIB>") - 1)
50 char buf[SDCCLIB_MAGIC_LEN];
52 if (fread (buf, 1, sizeof (buf), libfp) == sizeof (buf) && memcmp (buf, SDCCLIB_MAGIC, SDCCLIB_MAGIC_LEN) == 0)
57 if (getc (libfp) == '\n')
68 /* Load a .rel file embedded in a sdcclib file */
70 LoadRel (char *libfname, FILE * libfp, char *ModName)
75 while (getline (str, sizeof (str), libfp) != NULL)
80 if (EQ (str, "<FILE>"))
82 if (NULL != getline (str, sizeof (str), libfp) && EQ (str, ModName))
92 return EQ (str, "<REL>") ? load_rel (libfp, -1) : 0;
101 buildlibraryindex_sdcclib (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int type)
105 long IndexOffset = 0;
106 pmlibrarysymbol ThisSym = NULL;
108 while (getline (FLine, sizeof (FLine), libfp))
113 if (EQ (FLine, "<INDEX>"))
115 /*The next line has the size of the index */
116 getline (FLine, sizeof (FLine), libfp);
117 IndexOffset = atol (FLine);
123 if (EQ (FLine, "<MODULE>"))
126 char ModName[NCPS] = "";
129 /* The next line has the name of the module and the offset
130 of the corresponding embedded file in the library */
131 getline (FLine, sizeof (FLine), libfp);
132 sscanf (FLine, "%s %ld", ModName, &FileOffset);
135 /* Create a new libraryfile object for this module */
138 libr = This = (pmlibraryfile) new (sizeof (mlibraryfile));
142 This->next = (pmlibraryfile) new (sizeof (mlibraryfile));
147 This->offset = FileOffset + IndexOffset;
148 This->libspc = lbnh->libspc;
149 This->relfil = strdup (ModName);
150 sprintf (buff, "%s%s%c%s", lbnh->path, ModName, FSEPX, LKOBJEXT);
151 This->filspc = strdup (buff);
154 This->symbols = ThisSym = NULL; /* Start a new linked list of symbols */
156 else if (EQ (FLine, "</INDEX>"))
158 return This; /* Finish, get out of here */
163 if (EQ (FLine, "</MODULE>"))
166 /* Create the index for the next module */
171 /* Add the symbols */
172 if (ThisSym == NULL) /* First symbol of the current module */
174 ThisSym = This->symbols = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
178 ThisSym->next = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
179 ThisSym = ThisSym->next;
181 ThisSym->next = NULL;
182 ThisSym->name = strdup (FLine);
187 return This; /* State machine should never reach this point, but just in case... */
192 return This; /* State machine should never reach this point, but just in case... */
197 /* Load an .adb file embedded in a sdcclib file. If there is
198 something between <ADB> and </ADB> returns 1, otherwise returns 0.
199 This way the aomf51 will not have useless empty modules. */
202 LoadAdb (FILE * libfp)
208 while (getline (str, sizeof (str), libfp) != NULL)
213 if (EQ (str, "<ADB>"))
218 if (EQ (str, "</ADB>"))
220 fprintf (dfp, "%s\n", str);
228 /* Check for a symbol in a SDCC library. If found, add the embedded .rel and
229 .adb files from the library. The library must be created with the SDCC
230 librarian 'sdcclib' since the linking process depends on the correct file offsets
231 embedded in the library file. */
234 findsym_sdcclib (const char *name, struct lbname *lbnh, FILE * libfp, int type)
237 char ModName[NCPS] = "";
240 long IndexOffset = 0, FileOffset;
242 while (getline (FLine, sizeof (FLine), libfp))
244 char filspc[PATH_MAX];
246 if (lbnh->path != NULL)
248 strcpy (filspc, lbnh->path);
250 if (*filspc != '\0' && (filspc[strlen (filspc) - 1] != '/') && (filspc[strlen (filspc) - 1] != LKDIRSEP))
252 strcat (filspc, LKDIRSEPSTR);
260 if (EQ (FLine, "<INDEX>"))
262 /* The next line has the size of the index */
263 getline (FLine, sizeof (FLine), libfp);
264 IndexOffset = atol (FLine);
270 if (EQ (FLine, "<MODULE>"))
272 /* The next line has the name of the module and the offset
273 of the corresponding embedded file in the library */
274 getline (FLine, sizeof (FLine), libfp);
275 sscanf (FLine, "%s %ld", ModName, &FileOffset);
278 else if (EQ (FLine, "</INDEX>"))
280 /* Reached the end of the index. The symbol is not in this library. */
286 if (EQ (FLine, "</MODULE>"))
288 /* The symbol is not in this module, try the next one */
293 /* Check if this is the symbol we are looking for. */
294 if (strncmp (name, FLine, NCPS) == 0)
296 /* The symbol is in this module. */
298 /* As in the original library format, it is assumed that the .rel
299 files reside in the same directory as the lib files. */
300 sprintf (&filspc[strlen (filspc)], "%s%c%s", ModName, FSEPX, LKOBJEXT);
302 /* If this module has been loaded already don't load it again. */
303 if (is_module_loaded (filspc))
306 /* Add the embedded file to the list of files to be loaded in
307 the second pass. That is performed latter by the function
309 lbfh = (struct lbfile *) new (sizeof (struct lbfile));
318 for (lbf = lbfhead; lbf->next; lbf = lbf->next)
324 lbfh->libspc = lbnh->libspc;
325 lbfh->filspc = strdup (filspc);
326 lbfh->relfil = strdup (ModName);
327 /* Library embedded file, so lbfh->offset must be >=0 */
328 lbfh->offset = IndexOffset + FileOffset;
330 /* Jump to where the .rel begins and load it. */
331 fseek (libfp, lbfh->offset, SEEK_SET);
332 if (!LoadRel (lbnh->libspc, libfp, ModName))
335 fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbfh->libspc, ModName);
338 /* if cdb information required & .adb file present */
342 SaveLinkedFilePath (filspc);
344 return 1; /* Found the symbol, so success! */
350 return 0; /* It should never reach this point, but just in case... */
355 return 0; /* The symbol is not in this library */
361 loadfile_sdcclib (struct lbfile *lbfh)
367 char posix_path[PATH_MAX];
368 void cygwin_conv_to_full_posix_path (char *win_path, char *posix_path);
369 cygwin_conv_to_full_posix_path (lbfh->libspc, posix_path);
370 fp = fopen (posix_path, "rb");
372 fp = fopen (lbfh->libspc, "rb");
377 fseek (fp, lbfh->offset, SEEK_SET);
378 res = LoadRel (lbfh->libspc, fp, lbfh->relfil);
383 fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbfh->libspc, lbfh->relfil);
389 fprintf (stderr, "?ASlink-Error-Opening library '%s'\n", lbfh->libspc);
394 struct aslib_target aslib_target_sdcclib = {
397 &buildlibraryindex_sdcclib,