* asranlib/asranlib.c, link/lkar.h, link/lkar.c:
[fw/sdcc] / as / link / lklib.c
1 /* lklib.c
2
3    Copyright (C) 1989-1995 Alan R. Baldwin
4    721 Berkeley St., Kent, Ohio 44240
5    Copyright (C) 2008-2009 Borut Razem, borut dot razem at siol dot net
6
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
10 later version.
11
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.
16
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/>. */
19
20 /*
21  * With contributions for the
22  * object libraries from
23  * Ken Hornstein
24  * kenh@cmf.nrl.navy.mil
25  *
26  */
27
28 /*
29  * Extensions: P. Felber
30  */
31
32 #include <string.h>
33
34 #include "getline.h"
35 #include "aslink.h"
36 #include "lklibr.h"
37 #include "lkrel.h"
38
39 static int
40 is_lib (FILE * libfp)
41 {
42   return 1;
43 }
44
45 #ifdef INDEXLIB
46 /* buildlibraryindex - build an in-memory cache of the symbols contained in
47  *                     the libraries
48  */
49 static pmlibraryfile
50 buildlibraryindex_lib (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int type)
51 {
52   char relfil[NINPUT];
53
54   while (getline (relfil, sizeof (relfil), libfp) != NULL)
55     {
56       FILE *fp;
57       char str[PATH_MAX];
58
59       if (lbnh->path != NULL)
60         {
61           strcpy (str, lbnh->path);
62 #ifdef  OTHERSYSTEM
63           if ((*str != '\0') && (str[strlen (str) - 1] != '/') && (str[strlen (str) - 1] != LKDIRSEP))
64             {
65               strcat (str, LKDIRSEPSTR);
66             }
67 #endif
68         }
69       else
70         str[0] = '\0';
71
72       if ((relfil[0] == '/') || (relfil[0] == LKDIRSEP))
73         {
74           strcat (str, relfil + 1);
75         }
76       else
77         {
78           strcat (str, relfil);
79         }
80
81       if (strchr (relfil, FSEPX) == NULL)
82         {
83           sprintf (&str[strlen (str)], "%c%s", FSEPX, LKOBJEXT);
84         }
85
86       if ((fp = fopen (str, "rb")) != NULL)
87         {
88           /* Opened OK - create a new libraryfile object for it */
89           if (libr == NULL)
90             {
91               libr = This = (pmlibraryfile) new (sizeof (mlibraryfile));
92             }
93           else
94             {
95               This->next = (pmlibraryfile) new (sizeof (mlibraryfile));
96               This = This->next;
97             }
98           This->next = NULL;
99           This->loaded = -1;
100           This->libspc = lbnh->libspc;
101           This->relfil = strdup (relfil);
102           This->filspc = strdup (str);
103           This->type = type;
104
105           /* Start a new linked list of symbols for this module: */
106           This->symbols = NULL;
107
108           add_rel_index (fp, -1, This);
109           fclose (fp);
110         }                       /* Closes if object file opened OK */
111       else
112         {
113           fprintf (stderr, "?ASlink-Warning-Cannot open library module %s\n", str);
114         }
115     }                           /* Ends while - processing all in libr */
116
117   return This;
118 }
119
120 #else
121
122 static int
123 fndsym_lib (const char *name, struct lbname *lbnh, FILE * libfp, int type)
124 {
125   char relfil[NINPUT];
126
127   D ("Searching symbol: %s\n", name);
128
129   while (getline (relfil, sizeof (relfil), libfp) != NULL)
130     {
131       char str[PATH_MAX];
132       FILE *fp;
133
134       if (lbnh->path != NULL)
135         {
136           strcpy (str, lbnh->path);
137 #ifdef  OTHERSYSTEM
138           if ((*str != '\0') && (str[strlen (str) - 1] != '/') && (str[strlen (str) - 1] != LKDIRSEP))
139             {
140               strcat (str, LKDIRSEPSTR);
141             }
142 #endif
143         }
144       else
145         str[0] = '\0';
146
147       if ((relfil[0] == '/') || (relfil[0] == LKDIRSEP))
148         {
149           strcat (str, relfil + 1);
150         }
151       else
152         {
153           strcat (str, relfil);
154         }
155
156       if (strchr (relfil, FSEPX) == NULL)
157         {
158           sprintf (&str[strlen (str)], "%c%s", FSEPX, LKOBJEXT);
159         }
160
161       if ((fp = fopen (str, "rb")) != NULL)
162         {
163           /* Opened OK - create a new libraryfile object for it */
164           int ret = add_rel_file (name, lbnh, relfil, str, -1, fp, -1, type);
165           fclose (fp);
166           if (ret)
167             {
168               D ("Loaded module %s from file %s.\n", str, str);
169               /* if cdb information required & adb file present */
170               if (dflag && dfp)
171                 {
172                   FILE *xfp = afile (str, "adb", 0);    //JCF: Nov 30, 2002
173                   if (xfp)
174                     {
175                       SaveLinkedFilePath (str);
176                       copyfile (dfp, xfp);
177                       fclose (xfp);
178                     }
179                 }
180               return 1;         /* Found the symbol, so success! */
181             }
182         }                       /* Closes if object file opened OK */
183       else
184         {
185           fprintf (stderr, "?ASlink-Warning-Cannot open library module %s\n", str);
186         }
187     }                           /* Ends while - processing all in libr */
188
189   return 0;                     /* The symbol is not in this library */
190 }
191 #endif
192
193 /*)Function VOID    loadfile_lib(filspc)
194  *
195  *      char    *filspc     library object file specification
196  *
197  *  The function loadfile() links the library object module.
198  *
199  *  local variables:
200  *      FILE    *fp         file handle
201  *      int     i           input line length
202  *      char    str[]       file input line
203  *
204  *  global variables:
205  *      char    *ip         pointer to linker input string
206  *
207  *   functions called:
208  *      int     fclose()    c_library
209  *      char    *getline()  getline.c
210  *      FILE *  fopen()     c_library
211  *      VOID    link_main() lkmain.c
212  *      int     strlen()    c_library
213  *
214  *  side effects:
215  *      If file exists it is linked.
216  */
217
218 static VOID
219 loadfile_lib (struct lbfile *lbfh)
220 {
221   FILE *fp;
222 #ifdef __CYGWIN__
223   char posix_path[PATH_MAX];
224   void cygwin_conv_to_full_posix_path (char *win_path, char *posix_path);
225   cygwin_conv_to_full_posix_path (lbfh->filspc, posix_path);
226   fp = fopen (posix_path, "rb");
227 #else
228   fp = fopen (lbfh->filspc, "rb");
229 #endif
230
231   if (fp != NULL)
232     {
233       load_rel (fp, -1);
234       fclose (fp);
235     }
236   else
237     {
238       fprintf (stderr, "?ASlink-Error-Opening library '%s'\n", lbfh->filspc);
239       fclose (fp);
240       lkexit (1);
241     }
242 }
243
244 struct aslib_target aslib_target_lib = {
245   &is_lib,
246 #ifdef INDEXLIB
247   &buildlibraryindex_lib,
248 #else
249   &fndsym_lib,
250 #endif
251   &loadfile_lib,
252 };