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