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