Rev 5211 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5199 | serge | 1 | /* Linker file opening and searching. |
6324 | serge | 2 | Copyright (C) 1991-2015 Free Software Foundation, Inc. |
5199 | serge | 3 | |
4 | This file is part of the GNU Binutils. |
||
5 | |||
6 | This program is free software; you can redistribute it and/or modify |
||
7 | it under the terms of the GNU General Public License as published by |
||
8 | the Free Software Foundation; either version 3 of the License, or |
||
9 | (at your option) any later version. |
||
10 | |||
11 | This program is distributed in the hope that it will be useful, |
||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | GNU General Public License for more details. |
||
15 | |||
16 | You should have received a copy of the GNU General Public License |
||
17 | along with this program; if not, write to the Free Software |
||
18 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
||
19 | MA 02110-1301, USA. */ |
||
20 | |||
21 | #include "sysdep.h" |
||
22 | #include "bfd.h" |
||
23 | #include "bfdlink.h" |
||
24 | #include "safe-ctype.h" |
||
25 | #include "ld.h" |
||
26 | #include "ldmisc.h" |
||
27 | #include "ldexp.h" |
||
28 | #include "ldlang.h" |
||
29 | #include "ldfile.h" |
||
30 | #include "ldmain.h" |
||
31 | #include |
||
32 | #include "ldlex.h" |
||
33 | #include "ldemul.h" |
||
34 | #include "libiberty.h" |
||
35 | #include "filenames.h" |
||
36 | #ifdef ENABLE_PLUGINS |
||
37 | #include "plugin-api.h" |
||
38 | #include "plugin.h" |
||
39 | #endif /* ENABLE_PLUGINS */ |
||
40 | |||
41 | bfd_boolean ldfile_assumed_script = FALSE; |
||
42 | const char * ldfile_output_machine_name = ""; |
||
43 | unsigned long ldfile_output_machine; |
||
44 | enum bfd_architecture ldfile_output_architecture; |
||
45 | search_dirs_type * search_head; |
||
46 | |||
47 | #ifdef VMS |
||
48 | static char * slash = ""; |
||
49 | #else |
||
50 | #if defined (_WIN32) && ! defined (__CYGWIN32__) |
||
51 | static char * slash = "\\"; |
||
52 | #else |
||
53 | static char * slash = "/"; |
||
54 | #endif |
||
55 | #endif |
||
56 | |||
57 | typedef struct search_arch |
||
58 | { |
||
59 | char *name; |
||
60 | struct search_arch *next; |
||
61 | } search_arch_type; |
||
62 | |||
63 | static search_dirs_type **search_tail_ptr = &search_head; |
||
64 | static search_arch_type *search_arch_head; |
||
65 | static search_arch_type **search_arch_tail_ptr = &search_arch_head; |
||
66 | |||
67 | /* Test whether a pathname, after canonicalization, is the same or a |
||
68 | sub-directory of the sysroot directory. */ |
||
69 | |||
70 | static bfd_boolean |
||
71 | is_sysrooted_pathname (const char *name) |
||
72 | { |
||
73 | char *realname; |
||
74 | int len; |
||
75 | bfd_boolean result; |
||
76 | |||
77 | if (ld_canon_sysroot == NULL) |
||
78 | return FALSE; |
||
79 | |||
80 | realname = lrealpath (name); |
||
81 | len = strlen (realname); |
||
82 | result = FALSE; |
||
83 | if (len > ld_canon_sysroot_len |
||
84 | && IS_DIR_SEPARATOR (realname[ld_canon_sysroot_len])) |
||
85 | { |
||
86 | realname[ld_canon_sysroot_len] = '\0'; |
||
87 | result = FILENAME_CMP (ld_canon_sysroot, realname) == 0; |
||
88 | } |
||
89 | |||
90 | free (realname); |
||
91 | return result; |
||
92 | } |
||
93 | |||
94 | /* Adds NAME to the library search path. |
||
95 | Makes a copy of NAME using xmalloc(). */ |
||
96 | |||
97 | void |
||
98 | ldfile_add_library_path (const char *name, bfd_boolean cmdline) |
||
99 | { |
||
100 | search_dirs_type *new_dirs; |
||
101 | |||
102 | if (!cmdline && config.only_cmd_line_lib_dirs) |
||
103 | return; |
||
104 | |||
105 | new_dirs = (search_dirs_type *) xmalloc (sizeof (search_dirs_type)); |
||
106 | new_dirs->next = NULL; |
||
107 | new_dirs->cmdline = cmdline; |
||
108 | *search_tail_ptr = new_dirs; |
||
109 | search_tail_ptr = &new_dirs->next; |
||
110 | |||
111 | /* If a directory is marked as honoring sysroot, prepend the sysroot path |
||
112 | now. */ |
||
113 | if (name[0] == '=') |
||
114 | new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); |
||
115 | else |
||
116 | new_dirs->name = xstrdup (name); |
||
117 | } |
||
118 | |||
119 | /* Try to open a BFD for a lang_input_statement. */ |
||
120 | |||
121 | bfd_boolean |
||
122 | ldfile_try_open_bfd (const char *attempt, |
||
123 | lang_input_statement_type *entry) |
||
124 | { |
||
125 | entry->the_bfd = bfd_openr (attempt, entry->target); |
||
126 | |||
127 | if (verbose) |
||
128 | { |
||
129 | if (entry->the_bfd == NULL) |
||
130 | info_msg (_("attempt to open %s failed\n"), attempt); |
||
131 | else |
||
132 | info_msg (_("attempt to open %s succeeded\n"), attempt); |
||
133 | } |
||
134 | |||
135 | if (entry->the_bfd == NULL) |
||
136 | { |
||
137 | if (bfd_get_error () == bfd_error_invalid_target) |
||
138 | einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target); |
||
139 | return FALSE; |
||
140 | } |
||
141 | |||
142 | /* Linker needs to decompress sections. */ |
||
143 | entry->the_bfd->flags |= BFD_DECOMPRESS; |
||
144 | |||
6324 | serge | 145 | /* This is a linker input BFD. */ |
146 | entry->the_bfd->is_linker_input = 1; |
||
147 | |||
148 | #ifdef ENABLE_PLUGINS |
||
149 | if (entry->flags.lto_output) |
||
150 | entry->the_bfd->lto_output = 1; |
||
151 | #endif |
||
152 | |||
5199 | serge | 153 | /* If we are searching for this file, see if the architecture is |
154 | compatible with the output file. If it isn't, keep searching. |
||
155 | If we can't open the file as an object file, stop the search |
||
156 | here. If we are statically linking, ensure that we don't link |
||
157 | a dynamic object. |
||
158 | |||
159 | In the code below, it's OK to exit early if the check fails, |
||
160 | closing the checked BFD and returning FALSE, but if the BFD |
||
161 | checks out compatible, do not exit early returning TRUE, or |
||
162 | the plugins will not get a chance to claim the file. */ |
||
163 | |||
164 | if (entry->flags.search_dirs || !entry->flags.dynamic) |
||
165 | { |
||
166 | bfd *check; |
||
167 | |||
168 | if (bfd_check_format (entry->the_bfd, bfd_archive)) |
||
169 | check = bfd_openr_next_archived_file (entry->the_bfd, NULL); |
||
170 | else |
||
171 | check = entry->the_bfd; |
||
172 | |||
173 | if (check != NULL) |
||
174 | { |
||
175 | if (! bfd_check_format (check, bfd_object)) |
||
176 | { |
||
177 | if (check == entry->the_bfd |
||
178 | && entry->flags.search_dirs |
||
179 | && bfd_get_error () == bfd_error_file_not_recognized |
||
180 | && ! ldemul_unrecognized_file (entry)) |
||
181 | { |
||
182 | int token, skip = 0; |
||
183 | char *arg, *arg1, *arg2, *arg3; |
||
184 | extern FILE *yyin; |
||
185 | |||
186 | /* Try to interpret the file as a linker script. */ |
||
187 | ldfile_open_command_file (attempt); |
||
188 | |||
189 | ldfile_assumed_script = TRUE; |
||
190 | parser_input = input_selected; |
||
191 | ldlex_both (); |
||
192 | token = INPUT_SCRIPT; |
||
193 | while (token != 0) |
||
194 | { |
||
195 | switch (token) |
||
196 | { |
||
197 | case OUTPUT_FORMAT: |
||
198 | if ((token = yylex ()) != '(') |
||
199 | continue; |
||
200 | if ((token = yylex ()) != NAME) |
||
201 | continue; |
||
202 | arg1 = yylval.name; |
||
203 | arg2 = NULL; |
||
204 | arg3 = NULL; |
||
205 | token = yylex (); |
||
206 | if (token == ',') |
||
207 | { |
||
208 | if ((token = yylex ()) != NAME) |
||
209 | { |
||
210 | free (arg1); |
||
211 | continue; |
||
212 | } |
||
213 | arg2 = yylval.name; |
||
214 | if ((token = yylex ()) != ',' |
||
215 | || (token = yylex ()) != NAME) |
||
216 | { |
||
217 | free (arg1); |
||
218 | free (arg2); |
||
219 | continue; |
||
220 | } |
||
221 | arg3 = yylval.name; |
||
222 | token = yylex (); |
||
223 | } |
||
224 | if (token == ')') |
||
225 | { |
||
226 | switch (command_line.endian) |
||
227 | { |
||
228 | default: |
||
229 | case ENDIAN_UNSET: |
||
230 | arg = arg1; break; |
||
231 | case ENDIAN_BIG: |
||
232 | arg = arg2 ? arg2 : arg1; break; |
||
233 | case ENDIAN_LITTLE: |
||
234 | arg = arg3 ? arg3 : arg1; break; |
||
235 | } |
||
236 | if (strcmp (arg, lang_get_output_target ()) != 0) |
||
237 | skip = 1; |
||
238 | } |
||
239 | free (arg1); |
||
240 | if (arg2) free (arg2); |
||
241 | if (arg3) free (arg3); |
||
242 | break; |
||
243 | case NAME: |
||
244 | case LNAME: |
||
245 | case VERS_IDENTIFIER: |
||
246 | case VERS_TAG: |
||
247 | free (yylval.name); |
||
248 | break; |
||
249 | case INT: |
||
250 | if (yylval.bigint.str) |
||
251 | free (yylval.bigint.str); |
||
252 | break; |
||
253 | } |
||
254 | token = yylex (); |
||
255 | } |
||
256 | ldlex_popstate (); |
||
257 | ldfile_assumed_script = FALSE; |
||
258 | fclose (yyin); |
||
259 | yyin = NULL; |
||
260 | if (skip) |
||
261 | { |
||
262 | if (command_line.warn_search_mismatch) |
||
263 | einfo (_("%P: skipping incompatible %s " |
||
264 | "when searching for %s\n"), |
||
265 | attempt, entry->local_sym_name); |
||
266 | bfd_close (entry->the_bfd); |
||
267 | entry->the_bfd = NULL; |
||
268 | return FALSE; |
||
269 | } |
||
270 | } |
||
271 | goto success; |
||
272 | } |
||
273 | |||
274 | if (!entry->flags.dynamic && (entry->the_bfd->flags & DYNAMIC) != 0) |
||
275 | { |
||
276 | einfo (_("%F%P: attempted static link of dynamic object `%s'\n"), |
||
277 | attempt); |
||
278 | bfd_close (entry->the_bfd); |
||
279 | entry->the_bfd = NULL; |
||
280 | return FALSE; |
||
281 | } |
||
282 | |||
283 | if (entry->flags.search_dirs |
||
284 | && !bfd_arch_get_compatible (check, link_info.output_bfd, |
||
285 | command_line.accept_unknown_input_arch) |
||
286 | /* XCOFF archives can have 32 and 64 bit objects. */ |
||
287 | && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour |
||
288 | && bfd_get_flavour (link_info.output_bfd) == bfd_target_xcoff_flavour |
||
289 | && bfd_check_format (entry->the_bfd, bfd_archive))) |
||
290 | { |
||
291 | if (command_line.warn_search_mismatch) |
||
292 | einfo (_("%P: skipping incompatible %s " |
||
293 | "when searching for %s\n"), |
||
294 | attempt, entry->local_sym_name); |
||
295 | bfd_close (entry->the_bfd); |
||
296 | entry->the_bfd = NULL; |
||
297 | return FALSE; |
||
298 | } |
||
299 | } |
||
300 | } |
||
301 | success: |
||
302 | #ifdef ENABLE_PLUGINS |
||
303 | /* If plugins are active, they get first chance to claim |
||
304 | any successfully-opened input file. We skip archives |
||
305 | here; the plugin wants us to offer it the individual |
||
306 | members when we enumerate them, not the whole file. We |
||
307 | also ignore corefiles, because that's just weird. It is |
||
308 | a needed side-effect of calling bfd_check_format with |
||
309 | bfd_object that it sets the bfd's arch and mach, which |
||
310 | will be needed when and if we want to bfd_create a new |
||
311 | one using this one as a template. */ |
||
6324 | serge | 312 | if (link_info.lto_plugin_active |
313 | && !no_more_claiming |
||
314 | && bfd_check_format (entry->the_bfd, bfd_object)) |
||
315 | plugin_maybe_claim (entry); |
||
5199 | serge | 316 | #endif /* ENABLE_PLUGINS */ |
317 | |||
318 | /* It opened OK, the format checked out, and the plugins have had |
||
319 | their chance to claim it, so this is success. */ |
||
320 | return TRUE; |
||
321 | } |
||
322 | |||
323 | /* Search for and open the file specified by ENTRY. If it is an |
||
324 | archive, use ARCH, LIB and SUFFIX to modify the file name. */ |
||
325 | |||
326 | bfd_boolean |
||
327 | ldfile_open_file_search (const char *arch, |
||
328 | lang_input_statement_type *entry, |
||
329 | const char *lib, |
||
330 | const char *suffix) |
||
331 | { |
||
332 | search_dirs_type *search; |
||
333 | |||
334 | /* If this is not an archive, try to open it in the current |
||
335 | directory first. */ |
||
336 | if (! entry->flags.maybe_archive) |
||
337 | { |
||
338 | if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) |
||
339 | { |
||
340 | char *name = concat (ld_sysroot, entry->filename, |
||
341 | (const char *) NULL); |
||
342 | if (ldfile_try_open_bfd (name, entry)) |
||
343 | { |
||
344 | entry->filename = name; |
||
345 | return TRUE; |
||
346 | } |
||
347 | free (name); |
||
348 | } |
||
349 | else if (ldfile_try_open_bfd (entry->filename, entry)) |
||
350 | return TRUE; |
||
351 | |||
352 | if (IS_ABSOLUTE_PATH (entry->filename)) |
||
353 | return FALSE; |
||
354 | } |
||
355 | |||
356 | for (search = search_head; search != NULL; search = search->next) |
||
357 | { |
||
358 | char *string; |
||
359 | |||
6324 | serge | 360 | if (entry->flags.dynamic && !bfd_link_relocatable (&link_info)) |
5199 | serge | 361 | { |
362 | if (ldemul_open_dynamic_archive (arch, search, entry)) |
||
363 | return TRUE; |
||
364 | } |
||
365 | |||
6324 | serge | 366 | if (entry->flags.maybe_archive && !entry->flags.full_name_provided) |
5199 | serge | 367 | string = concat (search->name, slash, lib, entry->filename, |
368 | arch, suffix, (const char *) NULL); |
||
369 | else |
||
370 | string = concat (search->name, slash, entry->filename, |
||
371 | (const char *) 0); |
||
372 | |||
373 | if (ldfile_try_open_bfd (string, entry)) |
||
374 | { |
||
375 | entry->filename = string; |
||
376 | return TRUE; |
||
377 | } |
||
378 | |||
379 | free (string); |
||
380 | } |
||
381 | |||
382 | return FALSE; |
||
383 | } |
||
384 | |||
385 | /* Open the input file specified by ENTRY. |
||
386 | PR 4437: Do not stop on the first missing file, but |
||
387 | continue processing other input files in case there |
||
388 | are more errors to report. */ |
||
389 | |||
390 | void |
||
391 | ldfile_open_file (lang_input_statement_type *entry) |
||
392 | { |
||
393 | if (entry->the_bfd != NULL) |
||
394 | return; |
||
395 | |||
396 | if (! entry->flags.search_dirs) |
||
397 | { |
||
398 | if (ldfile_try_open_bfd (entry->filename, entry)) |
||
399 | return; |
||
400 | |||
401 | if (filename_cmp (entry->filename, entry->local_sym_name) != 0) |
||
402 | einfo (_("%P: cannot find %s (%s): %E\n"), |
||
403 | entry->filename, entry->local_sym_name); |
||
404 | else |
||
405 | einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name); |
||
406 | |||
407 | entry->flags.missing_file = TRUE; |
||
408 | input_flags.missing_file = TRUE; |
||
409 | } |
||
410 | else |
||
411 | { |
||
412 | search_arch_type *arch; |
||
413 | bfd_boolean found = FALSE; |
||
414 | |||
415 | /* Try to open |
||
416 | for (arch = search_arch_head; arch != NULL; arch = arch->next) |
||
417 | { |
||
418 | found = ldfile_open_file_search (arch->name, entry, "lib", ".a"); |
||
419 | if (found) |
||
420 | break; |
||
421 | #ifdef VMS |
||
422 | found = ldfile_open_file_search (arch->name, entry, ":lib", ".a"); |
||
423 | if (found) |
||
424 | break; |
||
425 | #endif |
||
426 | found = ldemul_find_potential_libraries (arch->name, entry); |
||
427 | if (found) |
||
428 | break; |
||
429 | } |
||
430 | |||
431 | /* If we have found the file, we don't need to search directories |
||
432 | again. */ |
||
433 | if (found) |
||
434 | entry->flags.search_dirs = FALSE; |
||
435 | else |
||
436 | { |
||
437 | if (entry->flags.sysrooted |
||
438 | && ld_sysroot |
||
439 | && IS_ABSOLUTE_PATH (entry->local_sym_name)) |
||
440 | einfo (_("%P: cannot find %s inside %s\n"), |
||
441 | entry->local_sym_name, ld_sysroot); |
||
442 | else |
||
443 | einfo (_("%P: cannot find %s\n"), entry->local_sym_name); |
||
444 | entry->flags.missing_file = TRUE; |
||
445 | input_flags.missing_file = TRUE; |
||
446 | } |
||
447 | } |
||
448 | } |
||
449 | |||
450 | /* Try to open NAME. */ |
||
451 | |||
452 | static FILE * |
||
453 | try_open (const char *name, bfd_boolean *sysrooted) |
||
454 | { |
||
455 | FILE *result; |
||
456 | |||
457 | result = fopen (name, "r"); |
||
458 | |||
459 | if (result != NULL) |
||
460 | *sysrooted = is_sysrooted_pathname (name); |
||
461 | |||
462 | if (verbose) |
||
463 | { |
||
464 | if (result == NULL) |
||
465 | info_msg (_("cannot find script file %s\n"), name); |
||
466 | else |
||
467 | info_msg (_("opened script file %s\n"), name); |
||
468 | } |
||
469 | |||
470 | return result; |
||
471 | } |
||
472 | |||
473 | /* Return TRUE iff directory DIR contains an "ldscripts" subdirectory. */ |
||
474 | |||
475 | static bfd_boolean |
||
476 | check_for_scripts_dir (char *dir) |
||
477 | { |
||
478 | char *buf; |
||
479 | struct stat s; |
||
480 | bfd_boolean res; |
||
481 | |||
482 | buf = concat (dir, "/ldscripts", (const char *) NULL); |
||
483 | res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); |
||
484 | free (buf); |
||
485 | return res; |
||
486 | } |
||
487 | |||
488 | /* Return the default directory for finding script files. |
||
489 | We look for the "ldscripts" directory in: |
||
490 | |||
491 | SCRIPTDIR (passed from Makefile) |
||
492 | (adjusted according to the current location of the binary) |
||
493 | the dir where this program is (for using it from the build tree). */ |
||
494 | |||
495 | static char * |
||
496 | find_scripts_dir (void) |
||
497 | { |
||
498 | char *dir; |
||
499 | |||
500 | dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR); |
||
501 | if (dir) |
||
502 | { |
||
503 | if (check_for_scripts_dir (dir)) |
||
504 | return dir; |
||
505 | free (dir); |
||
506 | } |
||
507 | |||
508 | dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR); |
||
509 | if (dir) |
||
510 | { |
||
511 | if (check_for_scripts_dir (dir)) |
||
512 | return dir; |
||
513 | free (dir); |
||
514 | } |
||
515 | |||
516 | /* Look for "ldscripts" in the dir where our binary is. */ |
||
517 | dir = make_relative_prefix (program_name, ".", "."); |
||
518 | if (dir) |
||
519 | { |
||
520 | if (check_for_scripts_dir (dir)) |
||
521 | return dir; |
||
522 | free (dir); |
||
523 | } |
||
524 | |||
525 | return NULL; |
||
526 | } |
||
527 | |||
528 | /* If DEFAULT_ONLY is false, try to open NAME; if that fails, look for |
||
529 | it in directories specified with -L, then in the default script |
||
530 | directory. If DEFAULT_ONLY is true, the search is restricted to |
||
531 | the default script location. */ |
||
532 | |||
533 | static FILE * |
||
534 | ldfile_find_command_file (const char *name, |
||
535 | bfd_boolean default_only, |
||
536 | bfd_boolean *sysrooted) |
||
537 | { |
||
538 | search_dirs_type *search; |
||
539 | FILE *result = NULL; |
||
540 | char *path; |
||
541 | static search_dirs_type *script_search; |
||
542 | |||
543 | if (!default_only) |
||
544 | { |
||
545 | /* First try raw name. */ |
||
546 | result = try_open (name, sysrooted); |
||
547 | if (result != NULL) |
||
548 | return result; |
||
549 | } |
||
550 | |||
551 | if (!script_search) |
||
552 | { |
||
553 | char *script_dir = find_scripts_dir (); |
||
554 | if (script_dir) |
||
555 | { |
||
556 | search_dirs_type **save_tail_ptr = search_tail_ptr; |
||
557 | search_tail_ptr = &script_search; |
||
558 | ldfile_add_library_path (script_dir, TRUE); |
||
559 | search_tail_ptr = save_tail_ptr; |
||
560 | } |
||
561 | } |
||
562 | |||
563 | /* Temporarily append script_search to the path list so that the |
||
564 | paths specified with -L will be searched first. */ |
||
565 | *search_tail_ptr = script_search; |
||
566 | |||
567 | /* Try now prefixes. */ |
||
568 | for (search = default_only ? script_search : search_head; |
||
569 | search != NULL; |
||
570 | search = search->next) |
||
571 | { |
||
572 | path = concat (search->name, slash, name, (const char *) NULL); |
||
573 | result = try_open (path, sysrooted); |
||
574 | free (path); |
||
575 | if (result) |
||
576 | break; |
||
577 | } |
||
578 | |||
579 | /* Restore the original path list. */ |
||
580 | *search_tail_ptr = NULL; |
||
581 | |||
582 | return result; |
||
583 | } |
||
584 | |||
585 | /* Open command file NAME. */ |
||
586 | |||
587 | static void |
||
588 | ldfile_open_command_file_1 (const char *name, bfd_boolean default_only) |
||
589 | { |
||
590 | FILE *ldlex_input_stack; |
||
591 | bfd_boolean sysrooted; |
||
592 | |||
593 | ldlex_input_stack = ldfile_find_command_file (name, default_only, &sysrooted); |
||
594 | |||
595 | if (ldlex_input_stack == NULL) |
||
596 | { |
||
597 | bfd_set_error (bfd_error_system_call); |
||
598 | einfo (_("%P%F: cannot open linker script file %s: %E\n"), name); |
||
599 | return; |
||
600 | } |
||
601 | |||
602 | lex_push_file (ldlex_input_stack, name, sysrooted); |
||
603 | |||
604 | lineno = 1; |
||
605 | |||
606 | saved_script_handle = ldlex_input_stack; |
||
607 | } |
||
608 | |||
609 | /* Open command file NAME in the current directory, -L directories, |
||
610 | the default script location, in that order. */ |
||
611 | |||
612 | void |
||
613 | ldfile_open_command_file (const char *name) |
||
614 | { |
||
615 | ldfile_open_command_file_1 (name, FALSE); |
||
616 | } |
||
617 | |||
618 | /* Open command file NAME at the default script location. */ |
||
619 | |||
620 | void |
||
621 | ldfile_open_default_command_file (const char *name) |
||
622 | { |
||
623 | ldfile_open_command_file_1 (name, TRUE); |
||
624 | } |
||
625 | |||
626 | void |
||
627 | ldfile_add_arch (const char *in_name) |
||
628 | { |
||
629 | char *name = xstrdup (in_name); |
||
630 | search_arch_type *new_arch = (search_arch_type *) |
||
631 | xmalloc (sizeof (search_arch_type)); |
||
632 | |||
633 | ldfile_output_machine_name = in_name; |
||
634 | |||
635 | new_arch->name = name; |
||
636 | new_arch->next = NULL; |
||
637 | while (*name) |
||
638 | { |
||
639 | *name = TOLOWER (*name); |
||
640 | name++; |
||
641 | } |
||
642 | *search_arch_tail_ptr = new_arch; |
||
643 | search_arch_tail_ptr = &new_arch->next; |
||
644 | |||
645 | } |
||
646 | |||
647 | /* Set the output architecture. */ |
||
648 | |||
649 | void |
||
650 | ldfile_set_output_arch (const char *string, enum bfd_architecture defarch) |
||
651 | { |
||
652 | const bfd_arch_info_type *arch = bfd_scan_arch (string); |
||
653 | |||
654 | if (arch) |
||
655 | { |
||
656 | ldfile_output_architecture = arch->arch; |
||
657 | ldfile_output_machine = arch->mach; |
||
658 | ldfile_output_machine_name = arch->printable_name; |
||
659 | } |
||
660 | else if (defarch != bfd_arch_unknown) |
||
661 | ldfile_output_architecture = defarch; |
||
662 | else |
||
663 | einfo (_("%P%F: cannot represent machine `%s'\n"), string); |
||
664 | } |