/* lklib.c Copyright (C) 1989-1995 Alan R. Baldwin 721 Berkeley St., Kent, Ohio 44240 Copyright (C) 2008-2009 Borut Razem, borut dot razem at siol dot net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * With contributions for the * object libraries from * Ken Hornstein * kenh@cmf.nrl.navy.mil * */ /* * Extensions: P. Felber */ #include #include "sdld.h" #include "lk_readnl.h" #include "aslink.h" #include "lklibr.h" #include "lkrel.h" static int is_lib (FILE * libfp) { return 1; } #ifdef INDEXLIB /* buildlibraryindex - build an in-memory cache of the symbols contained in * the libraries */ static pmlibraryfile buildlibraryindex_lib (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int type) { char relfil[NINPUT]; while (lk_readnl (relfil, sizeof (relfil), libfp) != NULL) { FILE *fp; char str[PATH_MAX]; if (lbnh->path != NULL) { strcpy (str, lbnh->path); #ifdef OTHERSYSTEM if ((*str != '\0') && (str[strlen (str) - 1] != '/') && (str[strlen (str) - 1] != LKDIRSEP)) { strcat (str, LKDIRSEPSTR); } #endif } else str[0] = '\0'; if ((relfil[0] == '/') || (relfil[0] == LKDIRSEP)) { strcat (str, relfil + 1); } else { strcat (str, relfil); } if (strchr (relfil, FSEPX) == NULL) { sprintf (&str[strlen (str)], "%c%s", FSEPX, LKOBJEXT); } if ((fp = fopen (str, "rb")) != NULL) { /* Opened OK - create a new libraryfile object for it */ if (libr == NULL) { libr = This = (pmlibraryfile) new (sizeof (mlibraryfile)); } else { This->next = (pmlibraryfile) new (sizeof (mlibraryfile)); This = This->next; } This->next = NULL; This->loaded = -1; This->libspc = lbnh->libspc; This->relfil = strdup (relfil); This->filspc = strdup (str); This->type = type; /* Start a new linked list of symbols for this module: */ This->symbols = NULL; add_rel_index (fp, -1, This); fclose (fp); } /* Closes if object file opened OK */ else { fprintf (stderr, "?ASlink-Warning-Cannot open library module %s\n", str); } } /* Ends while - processing all in libr */ return This; } #else static int fndsym_lib (const char *name, struct lbname *lbnh, FILE * libfp, int type) { char relfil[NINPUT]; D ("Searching symbol: %s\n", name); while (lk_readnl (relfil, sizeof (relfil), libfp) != NULL) { char str[PATH_MAX]; FILE *fp; if (lbnh->path != NULL) { strcpy (str, lbnh->path); #ifdef OTHERSYSTEM if ((*str != '\0') && (str[strlen (str) - 1] != '/') && (str[strlen (str) - 1] != LKDIRSEP)) { strcat (str, LKDIRSEPSTR); } #endif } else str[0] = '\0'; if ((relfil[0] == '/') || (relfil[0] == LKDIRSEP)) { strcat (str, relfil + 1); } else { strcat (str, relfil); } if (strchr (relfil, FSEPX) == NULL) { sprintf (&str[strlen (str)], "%c%s", FSEPX, LKOBJEXT); } if ((fp = fopen (str, "rb")) != NULL) { /* Opened OK - create a new libraryfile object for it */ int ret = add_rel_file (name, lbnh, relfil, str, -1, fp, -1, type); fclose (fp); if (ret) { D ("Loaded module %s from file %s.\n", str, str); /* if cdb information required & adb file present */ if (yflag && yfp) { FILE *xfp = afile (str, "adb", 0); //JCF: Nov 30, 2002 if (xfp) { SaveLinkedFilePath (str); copyfile (yfp, xfp); fclose (xfp); } } return 1; /* Found the symbol, so success! */ } } /* Closes if object file opened OK */ else { fprintf (stderr, "?ASlink-Warning-Cannot open library module %s\n", str); } } /* Ends while - processing all in libr */ return 0; /* The symbol is not in this library */ } #endif /*)Function VOID loadfile_lib(filspc) * * char *filspc library object file specification * * The function loadfile() links the library object module. * * local variables: * FILE *fp file handle * int i input line length * char str[] file input line * * global variables: * char *ip pointer to linker input string * * functions called: * int fclose() c_library * char *lk_readnl() lk_readnl.c * FILE * fopen() c_library * VOID link_main() lkmain.c * int strlen() c_library * * side effects: * If file exists it is linked. */ static VOID loadfile_lib (struct lbfile *lbfh) { FILE *fp; fp = fopen (lbfh->filspc, "rb"); if (fp != NULL) { load_rel (fp, -1); fclose (fp); } else { fprintf (stderr, "?ASlink-Error-Opening library '%s'\n", lbfh->filspc); fclose (fp); lkexit (1); } } struct aslib_target aslib_target_lib = { &is_lib, #ifdef INDEXLIB &buildlibraryindex_lib, #else &fndsym_lib, #endif &loadfile_lib, };