1 /* Linker file opening and searching.
2 Copyright (C) 1991, 92, 93, 94, 95, 98, 99, 2000
3 Free Software Foundation, Inc.
5 This file is part of GLD, the Gnu Linker.
7 GLD is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GLD 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.
17 You should have received a copy of the GNU General Public License
18 along with GLD; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 look after all the file stuff
44 const char *ldfile_input_filename
;
45 boolean ldfile_assumed_script
= false;
46 const char *ldfile_output_machine_name
= "";
47 unsigned long ldfile_output_machine
;
48 enum bfd_architecture ldfile_output_architecture
;
49 search_dirs_type
*search_head
;
55 #if defined (_WIN32) && ! defined (__CYGWIN32__)
62 /* The MPW path char is a colon. */
68 static search_dirs_type
**search_tail_ptr
= &search_head
;
70 typedef struct search_arch
73 struct search_arch
*next
;
76 static search_arch_type
*search_arch_head
;
77 static search_arch_type
**search_arch_tail_ptr
= &search_arch_head
;
79 static FILE *try_open
PARAMS ((const char *name
, const char *exten
));
82 ldfile_add_library_path (name
, cmdline
)
86 search_dirs_type
*new;
88 new = (search_dirs_type
*) xmalloc (sizeof (search_dirs_type
));
91 new->cmdline
= cmdline
;
92 *search_tail_ptr
= new;
93 search_tail_ptr
= &new->next
;
96 /* Try to open a BFD for a lang_input_statement. */
99 ldfile_try_open_bfd (attempt
, entry
)
101 lang_input_statement_type
*entry
;
103 entry
->the_bfd
= bfd_openr (attempt
, entry
->target
);
105 if (trace_file_tries
)
107 if (entry
->the_bfd
== NULL
)
108 info_msg (_("attempt to open %s failed\n"), attempt
);
110 info_msg (_("attempt to open %s succeeded\n"), attempt
);
113 if (entry
->the_bfd
== NULL
)
115 if (bfd_get_error () == bfd_error_invalid_target
)
116 einfo (_("%F%P: invalid BFD target `%s'\n"), entry
->target
);
120 /* If we are searching for this file, see if the architecture is
121 compatible with the output file. If it isn't, keep searching.
122 If we can't open the file as an object file, stop the search
125 if (entry
->search_dirs_flag
)
129 if (bfd_check_format (entry
->the_bfd
, bfd_archive
))
130 check
= bfd_openr_next_archived_file (entry
->the_bfd
, NULL
);
132 check
= entry
->the_bfd
;
136 if (! bfd_check_format (check
, bfd_object
))
138 if (bfd_arch_get_compatible (check
, output_bfd
) == NULL
)
140 einfo (_("%P: skipping incompatible %s when searching for %s"),
141 attempt
, entry
->local_sym_name
);
142 bfd_close (entry
->the_bfd
);
143 entry
->the_bfd
= NULL
;
152 /* Search for and open the file specified by ENTRY. If it is an
153 archive, use ARCH, LIB and SUFFIX to modify the file name. */
156 ldfile_open_file_search (arch
, entry
, lib
, suffix
)
158 lang_input_statement_type
*entry
;
162 search_dirs_type
*search
;
164 /* If this is not an archive, try to open it in the current
166 if (! entry
->is_archive
)
168 if (ldfile_try_open_bfd (entry
->filename
, entry
))
172 for (search
= search_head
;
173 search
!= (search_dirs_type
*)NULL
;
174 search
= search
->next
)
178 if (entry
->dynamic
&& ! link_info
.relocateable
)
180 if (ldemul_open_dynamic_archive (arch
, search
, entry
))
184 string
= (char *) xmalloc (strlen (search
->name
)
187 + strlen (entry
->filename
)
192 if (entry
->is_archive
)
193 sprintf (string
, "%s%s%s%s%s%s", search
->name
, slash
,
194 lib
, entry
->filename
, arch
, suffix
);
195 else if (entry
->filename
[0] == '/' || entry
->filename
[0] == '.'
196 #if defined (__MSDOS__) || defined (_WIN32)
197 || entry
->filename
[0] == '\\'
198 || (isalpha (entry
->filename
[0])
199 && entry
->filename
[1] == ':')
202 strcpy (string
, entry
->filename
);
204 sprintf (string
, "%s%s%s", search
->name
, slash
, entry
->filename
);
206 if (ldfile_try_open_bfd (string
, entry
))
208 entry
->filename
= string
;
218 /* Open the input file specified by ENTRY. */
221 ldfile_open_file (entry
)
222 lang_input_statement_type
*entry
;
224 if (entry
->the_bfd
!= NULL
)
227 if (! entry
->search_dirs_flag
)
229 if (ldfile_try_open_bfd (entry
->filename
, entry
))
231 if (strcmp (entry
->filename
, entry
->local_sym_name
) != 0)
232 einfo (_("%F%P: cannot open %s for %s: %E\n"),
233 entry
->filename
, entry
->local_sym_name
);
235 einfo(_("%F%P: cannot open %s: %E\n"), entry
->local_sym_name
);
239 search_arch_type
*arch
;
241 /* Try to open <filename><suffix> or lib<filename><suffix>.a */
242 for (arch
= search_arch_head
;
243 arch
!= (search_arch_type
*) NULL
;
246 if (ldfile_open_file_search (arch
->name
, entry
, "lib", ".a"))
249 if (ldfile_open_file_search (arch
->name
, entry
, ":lib", ".a"))
252 if (ldemul_find_potential_libraries (arch
->name
, entry
))
255 einfo (_("%F%P: cannot find %s\n"), entry
->local_sym_name
);
259 /* Try to open NAME; if that fails, try NAME with EXTEN appended to it. */
262 try_open (name
, exten
)
269 result
= fopen (name
, "r");
270 if (trace_file_tries
)
273 info_msg (_("cannot find script file %s\n"), name
);
275 info_msg (_("opened script file %s\n"), name
);
283 sprintf (buff
, "%s%s", name
, exten
);
284 result
= fopen (buff
, "r");
285 if (trace_file_tries
)
288 info_msg (_("cannot find script file %s\n"), buff
);
290 info_msg (_("opened script file %s\n"), buff
);
297 /* Try to open NAME; if that fails, look for it in any directories
298 specified with -L, without and with EXTEND apppended. */
301 ldfile_find_command_file (name
, extend
)
305 search_dirs_type
*search
;
309 /* First try raw name */
310 result
= try_open(name
,"");
311 if (result
== (FILE *)NULL
) {
312 /* Try now prefixes */
313 for (search
= search_head
;
314 search
!= (search_dirs_type
*)NULL
;
315 search
= search
->next
) {
316 sprintf(buffer
,"%s%s%s", search
->name
, slash
, name
);
317 result
= try_open(buffer
, extend
);
325 ldfile_open_command_file (name
)
328 FILE *ldlex_input_stack
;
329 ldlex_input_stack
= ldfile_find_command_file(name
, "");
331 if (ldlex_input_stack
== (FILE *)NULL
) {
332 bfd_set_error (bfd_error_system_call
);
333 einfo(_("%P%F: cannot open linker script file %s: %E\n"),name
);
335 lex_push_file(ldlex_input_stack
, name
);
337 ldfile_input_filename
= name
;
349 gnu960_map_archname( name
)
352 struct tabentry
{ char *cmd_switch
; char *arch
; };
353 static struct tabentry arch_tab
[] = {
357 "KC", "mc", /* Synonym for MC */
360 "SA", "ka", /* Functionally equivalent to KA */
361 "SB", "kb", /* Functionally equivalent to KB */
367 for ( tp
= arch_tab
; tp
->cmd_switch
!= NULL
; tp
++ ){
368 if ( !strcmp(name
,tp
->cmd_switch
) ){
373 if ( tp
->cmd_switch
== NULL
){
374 einfo(_("%P%F: unknown architecture: %s\n"),name
);
382 ldfile_add_arch(name
)
385 search_arch_type
*new =
386 (search_arch_type
*)xmalloc((bfd_size_type
)(sizeof(search_arch_type
)));
390 if (ldfile_output_machine_name
[0] != '\0') {
391 einfo(_("%P%F: target architecture respecified\n"));
394 ldfile_output_machine_name
= name
;
397 new->next
= (search_arch_type
*)NULL
;
398 new->name
= gnu960_map_archname( name
);
399 *search_arch_tail_ptr
= new;
400 search_arch_tail_ptr
= &new->next
;
404 #else /* not GNU960 */
408 ldfile_add_arch (in_name
)
409 CONST
char * in_name
;
411 char *name
= buystring(in_name
);
412 search_arch_type
*new =
413 (search_arch_type
*) xmalloc (sizeof (search_arch_type
));
415 ldfile_output_machine_name
= in_name
;
418 new->next
= (search_arch_type
*)NULL
;
421 if (isupper ((unsigned char) *name
))
422 *name
= tolower ((unsigned char) *name
);
425 *search_arch_tail_ptr
= new;
426 search_arch_tail_ptr
= &new->next
;
431 /* Set the output architecture */
433 ldfile_set_output_arch (string
)
436 const bfd_arch_info_type
*arch
= bfd_scan_arch(string
);
439 ldfile_output_architecture
= arch
->arch
;
440 ldfile_output_machine
= arch
->mach
;
441 ldfile_output_machine_name
= arch
->printable_name
;
444 einfo(_("%P%F: cannot represent machine `%s'\n"), string
);