From 599917b82b8592664e680ac7fca4260f0160e169 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 10 Oct 2002 15:59:10 +0000 Subject: [PATCH] * ldfile.c (ldfile_try_open_bfd): When searching skip linker scripts if they have OUTPUT_FORMAT not matching actual output format. * ldlang.c (lang_get_output_target): New function. (open_output): Use it. * ldlang.h (lang_get_output_target): New prototype. --- ld/ChangeLog | 8 ++++++ ld/ldfile.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- ld/ldlang.c | 42 +++++++++++++++------------ ld/ldlang.h | 1 + 4 files changed, 126 insertions(+), 19 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 7d783ff..b5399ca 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2002-10-10 Jakub Jelinek + + * ldfile.c (ldfile_try_open_bfd): When searching skip linker scripts if + they have OUTPUT_FORMAT not matching actual output format. + * ldlang.c (lang_get_output_target): New function. + (open_output): Use it. + * ldlang.h (lang_get_output_target): New prototype. + 2002-10-10 Alan Modra * emultempl/elf32.em (output_rel_find): Prefer .rel script sections diff --git a/ld/ldfile.c b/ld/ldfile.c index 9fb2b2d..813d55e 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -131,7 +131,99 @@ ldfile_try_open_bfd (attempt, entry) if (check != NULL) { if (! bfd_check_format (check, bfd_object)) - return true; + { + if (check == entry->the_bfd + && bfd_get_error () == bfd_error_file_not_recognized + && ! ldemul_unrecognized_file (entry)) + { + int token, skip = 0; + char *arg, *arg1, *arg2, *arg3; + extern FILE *yyin; + + /* Try to interpret the file as a linker script. */ + ldfile_open_command_file (attempt); + + ldfile_assumed_script = true; + parser_input = input_selected; + ldlex_both (); + token = INPUT_SCRIPT; + while (token != 0) + { + switch (token) + { + case OUTPUT_FORMAT: + if ((token = yylex ()) != '(') + continue; + if ((token = yylex ()) != NAME) + continue; + arg1 = yylval.name; + arg2 = NULL; + arg3 = NULL; + token = yylex (); + if (token == ',') + { + if ((token = yylex ()) != NAME) + { + free (arg1); + continue; + } + arg2 = yylval.name; + if ((token = yylex ()) != ',' + || (token = yylex ()) != NAME) + { + free (arg1); + free (arg2); + continue; + } + arg3 = yylval.name; + token = yylex (); + } + if (token == ')') + { + switch (command_line.endian) + { + default: + case ENDIAN_UNSET: + arg = arg1; break; + case ENDIAN_BIG: + arg = arg2 ? arg2 : arg1; break; + case ENDIAN_LITTLE: + arg = arg3 ? arg3 : arg1; break; + } + if (strcmp (arg, lang_get_output_target ()) != 0) + skip = 1; + } + free (arg1); + if (arg2) free (arg2); + if (arg3) free (arg3); + break; + case NAME: + case LNAME: + case VERS_IDENTIFIER: + case VERS_TAG: + free (yylval.name); + break; + case INT: + if (yylval.bigint.str) + free (yylval.bigint.str); + break; + } + token = yylex (); + } + ldfile_assumed_script = false; + fclose (yyin); + yyin = NULL; + if (skip) + { + einfo (_("%P: skipping incompatible %s when searching for %s\n"), + attempt, entry->local_sym_name); + bfd_close (entry->the_bfd); + entry->the_bfd = NULL; + return false; + } + } + return true; + } if ((bfd_arch_get_compatible (check, output_bfd) == NULL) /* XCOFF archives can have 32 and 64 bit objects */ diff --git a/ld/ldlang.c b/ld/ldlang.c index 1df0532..8ebd1bd 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1787,6 +1787,29 @@ get_first_input_target () return target; } +const char * +lang_get_output_target () +{ + const char *target; + + /* Has the user told us which output format to use? */ + if (output_target != (char *) NULL) + return output_target; + + /* No - has the current target been set to something other than + the default? */ + if (current_target != default_target) + return current_target; + + /* No - can we determine the format of the first input file? */ + target = get_first_input_target (); + if (target != NULL) + return target; + + /* Failed - use the default output target. */ + return default_target; +} + /* Open the output file. */ static bfd * @@ -1795,24 +1818,7 @@ open_output (name) { bfd *output; - /* Has the user told us which output format to use? */ - if (output_target == (char *) NULL) - { - /* No - has the current target been set to something other than - the default? */ - if (current_target != default_target) - output_target = current_target; - - /* No - can we determine the format of the first input file? */ - else - { - output_target = get_first_input_target (); - - /* Failed - use the default output target. */ - if (output_target == NULL) - output_target = default_target; - } - } + output_target = lang_get_output_target (); /* Has the user requested a particular endianness on the command line? */ diff --git a/ld/ldlang.h b/ld/ldlang.h index cb4b6d3..57c8c51 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -483,5 +483,6 @@ extern void lang_register_vers_node struct bfd_elf_version_deps *)); boolean unique_section_p PARAMS ((const char *)); extern void lang_add_unique PARAMS ((const char *)); +extern const char *lang_get_output_target PARAMS ((void)); #endif -- 2.7.4