import gdb-2000-01-17 snapshot
[external/binutils.git] / ld / ldfile.c
1 /* Copyright (C) 1991, 92, 93, 94, 95, 98, 1999 Free Software Foundation, Inc.
2
3 This file is part of GLD, the Gnu Linker.
4
5 GLD is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 GLD is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GLD; see the file COPYING.  If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
18 02111-1307, USA.  */
19
20 /*
21  ldfile.c
22
23  look after all the file stuff
24
25  */
26
27 #include "bfd.h"
28 #include "sysdep.h"
29 #include "bfdlink.h"
30 #include "ld.h"
31 #include "ldmisc.h"
32 #include "ldexp.h"
33 #include "ldlang.h"
34 #include "ldfile.h"
35 #include "ldmain.h"
36 #include "ldgram.h"
37 #include "ldlex.h"
38 #include "ldemul.h"
39
40 #include <ctype.h>
41
42 const char *ldfile_input_filename;
43 boolean ldfile_assumed_script = false;
44 const char *ldfile_output_machine_name = "";
45 unsigned long ldfile_output_machine;
46 enum bfd_architecture ldfile_output_architecture;
47 search_dirs_type *search_head;
48
49 #ifndef MPW
50 #ifdef VMS
51 char *slash = "";
52 #else
53 #if defined (_WIN32) && ! defined (__CYGWIN32__)
54 char *slash = "\\";
55 #else
56 char *slash = "/";
57 #endif
58 #endif
59 #else /* MPW */
60 /* The MPW path char is a colon. */
61 char *slash = ":";
62 #endif /* MPW */
63
64 /* LOCAL */
65
66 static search_dirs_type **search_tail_ptr = &search_head;
67
68 typedef struct search_arch 
69 {
70   char *name; 
71   struct search_arch *next;
72 } search_arch_type;
73
74 static search_arch_type *search_arch_head;
75 static search_arch_type **search_arch_tail_ptr = &search_arch_head;
76  
77 static boolean ldfile_open_file_search
78   PARAMS ((const char *arch, lang_input_statement_type *,
79            const char *lib, const char *suffix));
80 static FILE *try_open PARAMS ((const char *name, const char *exten));
81
82 void
83 ldfile_add_library_path (name, cmdline)
84      const char *name;
85      boolean cmdline;
86 {
87   search_dirs_type *new;
88
89   new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type));
90   new->next = NULL;
91   new->name = name;
92   new->cmdline = cmdline;
93   *search_tail_ptr = new;
94   search_tail_ptr = &new->next;
95 }
96
97 /* Try to open a BFD for a lang_input_statement.  */
98
99 boolean
100 ldfile_try_open_bfd (attempt, entry)
101      const char *attempt;
102      lang_input_statement_type *entry;
103 {
104   entry->the_bfd = bfd_openr (attempt, entry->target);
105
106   if (trace_file_tries)
107     {
108       if (entry->the_bfd == NULL)
109         info_msg (_("attempt to open %s failed\n"), attempt);
110       else
111         info_msg (_("attempt to open %s succeeded\n"), attempt);
112     }
113
114   if (entry->the_bfd == NULL)
115     {
116       if (bfd_get_error () == bfd_error_invalid_target)
117         einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
118       return false;
119     }
120
121   /* If we are searching for this file, see if the architecture is
122      compatible with the output file.  If it isn't, keep searching.
123      If we can't open the file as an object file, stop the search
124      here.  */
125
126   if (entry->search_dirs_flag)
127     {
128       bfd *check;
129
130       if (bfd_check_format (entry->the_bfd, bfd_archive))
131         check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
132       else
133         check = entry->the_bfd;
134
135       if (! bfd_check_format (check, bfd_object))
136         return true;
137       if (bfd_arch_get_compatible (check, output_bfd) == NULL)
138         {
139           einfo (_("%P: skipping incompatible %s when searching for %s"),
140                  attempt, entry->local_sym_name);
141           bfd_close (entry->the_bfd);
142           entry->the_bfd = NULL;
143           return false;
144         }
145     }
146
147   return true;
148 }
149
150 /* Search for and open the file specified by ENTRY.  If it is an
151    archive, use ARCH, LIB and SUFFIX to modify the file name.  */
152
153 static boolean
154 ldfile_open_file_search (arch, entry, lib, suffix)
155      const char *arch;
156      lang_input_statement_type *entry;
157      const char *lib;
158      const char *suffix;
159 {
160   search_dirs_type *search;
161
162   /* If this is not an archive, try to open it in the current
163      directory first.  */
164   if (! entry->is_archive)
165     {
166       if (ldfile_try_open_bfd (entry->filename, entry))
167         return true;
168     }
169
170   for (search = search_head;
171        search != (search_dirs_type *)NULL;
172        search = search->next) 
173     {
174       char *string;
175
176       if (entry->dynamic && ! link_info.relocateable)
177         {
178           if (ldemul_open_dynamic_archive (arch, search, entry))
179             return true;
180         }
181
182       string = (char *) xmalloc (strlen (search->name)
183                                  + strlen (slash)
184                                  + strlen (lib)
185                                  + strlen (entry->filename)
186                                  + strlen (arch)
187                                  + strlen (suffix)
188                                  + 1);
189
190       if (entry->is_archive)
191         sprintf (string, "%s%s%s%s%s%s", search->name, slash,
192                  lib, entry->filename, arch, suffix);
193       else if (entry->filename[0] == '/' || entry->filename[0] == '.'
194 #if defined (__MSDOS__) || defined (_WIN32)
195                || entry->filename[0] == '\\' 
196                || (isalpha (entry->filename[0]) 
197                    && entry->filename[1] == ':')
198 #endif
199           )
200         strcpy (string, entry->filename);
201       else
202         sprintf (string, "%s%s%s", search->name, slash, entry->filename);
203
204       if (ldfile_try_open_bfd (string, entry))
205         {
206           entry->filename = string;
207           return true;
208         }
209
210       free (string);
211     }
212
213   return false;
214 }
215
216 /* Open the input file specified by ENTRY.  */
217
218 void
219 ldfile_open_file (entry)
220      lang_input_statement_type *entry;
221 {
222   if (entry->the_bfd != NULL)
223     return;
224
225   if (! entry->search_dirs_flag)
226     {
227       if (ldfile_try_open_bfd (entry->filename, entry))
228         return;
229       if (strcmp (entry->filename, entry->local_sym_name) != 0)
230         einfo (_("%F%P: cannot open %s for %s: %E\n"),
231                entry->filename, entry->local_sym_name);
232       else
233         einfo(_("%F%P: cannot open %s: %E\n"), entry->local_sym_name);
234     }
235   else
236     {
237       search_arch_type *arch;
238
239       /* Try to open <filename><suffix> or lib<filename><suffix>.a */
240       for (arch = search_arch_head;
241            arch != (search_arch_type *) NULL;
242            arch = arch->next)
243         {
244           if (ldfile_open_file_search (arch->name, entry, "lib", ".a"))
245             return;
246 #ifdef VMS
247           if (ldfile_open_file_search (arch->name, entry, ":lib", ".a"))
248             return;
249 #endif
250         }
251       einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
252     }
253 }
254
255 /* Try to open NAME; if that fails, try NAME with EXTEN appended to it.  */
256
257 static FILE *
258 try_open (name, exten)
259      const char *name;
260      const char *exten;
261 {
262   FILE *result;
263   char buff[1000];
264
265   result = fopen (name, "r");
266   if (trace_file_tries)
267     {
268       if (result == NULL)
269         info_msg (_("cannot find script file %s\n"), name);
270       else
271         info_msg (_("opened script file %s\n"), name);
272     }
273
274   if (result != NULL)
275     return result;
276
277   if (*exten)
278     {
279       sprintf (buff, "%s%s", name, exten);
280       result = fopen (buff, "r");
281       if (trace_file_tries)
282         {
283           if (result == NULL)
284             info_msg (_("cannot find script file %s\n"), buff);
285           else
286             info_msg (_("opened script file %s\n"), buff);
287         }
288     }
289
290   return result;
291 }
292
293 /* Try to open NAME; if that fails, look for it in any directories
294    specified with -L, without and with EXTEND apppended.  */
295
296 FILE *
297 ldfile_find_command_file (name, extend)
298      const char *name;
299      const char *extend;
300 {
301   search_dirs_type *search;
302   FILE *result;
303   char buffer[1000];
304
305   /* First try raw name */
306   result = try_open(name,"");
307   if (result == (FILE *)NULL) {
308     /* Try now prefixes */
309     for (search = search_head;
310          search != (search_dirs_type *)NULL;
311          search = search->next) {
312       sprintf(buffer,"%s%s%s", search->name, slash, name);
313       result = try_open(buffer, extend);
314       if (result)break;
315     }
316   }
317   return result;
318 }
319
320 void
321 ldfile_open_command_file (name)
322      const char *name;
323 {
324   FILE *ldlex_input_stack;
325   ldlex_input_stack = ldfile_find_command_file(name, "");
326
327   if (ldlex_input_stack == (FILE *)NULL) {
328     bfd_set_error (bfd_error_system_call);
329     einfo(_("%P%F: cannot open linker script file %s: %E\n"),name);
330   }
331   lex_push_file(ldlex_input_stack, name);
332   
333   ldfile_input_filename = name;
334   lineno = 1;
335   had_script = true;
336 }
337
338
339
340
341
342 #ifdef GNU960
343 static
344 char *
345 gnu960_map_archname( name )
346 char *name;
347 {
348   struct tabentry { char *cmd_switch; char *arch; };
349   static struct tabentry arch_tab[] = {
350         "",   "",
351         "KA", "ka",
352         "KB", "kb",
353         "KC", "mc",     /* Synonym for MC */
354         "MC", "mc",
355         "CA", "ca",
356         "SA", "ka",     /* Functionally equivalent to KA */
357         "SB", "kb",     /* Functionally equivalent to KB */
358         NULL, ""
359   };
360   struct tabentry *tp;
361   
362
363   for ( tp = arch_tab; tp->cmd_switch != NULL; tp++ ){
364     if ( !strcmp(name,tp->cmd_switch) ){
365       break;
366     }
367   }
368
369   if ( tp->cmd_switch == NULL ){
370     einfo(_("%P%F: unknown architecture: %s\n"),name);
371   }
372   return tp->arch;
373 }
374
375
376
377 void
378 ldfile_add_arch(name)
379 char *name;
380 {
381   search_arch_type *new =
382     (search_arch_type *)xmalloc((bfd_size_type)(sizeof(search_arch_type)));
383
384
385   if (*name != '\0') {
386     if (ldfile_output_machine_name[0] != '\0') {
387       einfo(_("%P%F: target architecture respecified\n"));
388       return;
389     }
390     ldfile_output_machine_name = name;
391   }
392
393   new->next = (search_arch_type*)NULL;
394   new->name = gnu960_map_archname( name );
395   *search_arch_tail_ptr = new;
396   search_arch_tail_ptr = &new->next;
397
398 }
399
400 #else   /* not GNU960 */
401
402
403 void
404 ldfile_add_arch (in_name)
405      CONST char * in_name;
406 {
407   char *name = buystring(in_name);
408   search_arch_type *new =
409     (search_arch_type *) xmalloc (sizeof (search_arch_type));
410
411   ldfile_output_machine_name = in_name;
412
413   new->name = name;
414   new->next = (search_arch_type*)NULL;
415   while (*name)
416     {
417       if (isupper ((unsigned char) *name))
418         *name = tolower ((unsigned char) *name);
419       name++;
420     }
421   *search_arch_tail_ptr = new;
422   search_arch_tail_ptr = &new->next;
423
424 }
425 #endif
426
427 /* Set the output architecture */
428 void
429 ldfile_set_output_arch (string)
430      CONST char *string;
431 {
432   const bfd_arch_info_type *arch = bfd_scan_arch(string);
433
434   if (arch) {
435     ldfile_output_architecture = arch->arch;
436     ldfile_output_machine = arch->mach;
437     ldfile_output_machine_name = arch->printable_name;
438   }
439   else {
440     einfo(_("%P%F: cannot represent machine `%s'\n"), string);
441   }
442 }