source: trunk/src/binutils/ld/ldfile.c@ 100

Last change on this file since 100 was 100, checked in by bird, 22 years ago

review. Added some comments and #ifs.

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