summaryrefslogtreecommitdiff
path: root/ld/ldfile.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-10-10 15:59:10 +0000
committerJakub Jelinek <jakub@redhat.com>2002-10-10 15:59:10 +0000
commit04b30e0ee827ea919828907cf33ae874725f02d9 (patch)
treefbe226a591e283b62a0e128e6c60969744fb8d8a /ld/ldfile.c
parent20fe2ce5fcaf59bf01c7e296264b1e8e3590c90e (diff)
downloadbinutils-redhat-04b30e0ee827ea919828907cf33ae874725f02d9.tar.gz
* 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.
Diffstat (limited to 'ld/ldfile.c')
-rw-r--r--ld/ldfile.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/ld/ldfile.c b/ld/ldfile.c
index 9fb2b2dab9..813d55edaf 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 */