* ldfile.c (ldfile_try_open_bfd): When searching skip linker scripts if
authorJakub Jelinek <jakub@redhat.com>
Thu, 10 Oct 2002 15:59:10 +0000 (15:59 +0000)
committerJakub Jelinek <jakub@redhat.com>
Thu, 10 Oct 2002 15:59:10 +0000 (15:59 +0000)
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
ld/ldfile.c
ld/ldlang.c
ld/ldlang.h

index 7d783ff146d66d2063ba403eaa2c756857dba2da..b5399ca758697e2659c3c404f662751c9838f58c 100644 (file)
@@ -1,3 +1,11 @@
+2002-10-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * 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  <amodra@bigpond.net.au>
 
        * emultempl/elf32.em (output_rel_find): Prefer .rel script sections
index 9fb2b2dab9e4ef24a29637693d362e776eedab9b..813d55edafd1dd703cd83fef0907b71a45af0919 100644 (file)
@@ -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 */
index 1df05321fb3670a4ae39c4ceace1103ce5a2d1b6..8ebd1bd2eaad389399db5d6089b99263e30a447f 100644 (file)
@@ -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?  */
index cb4b6d332dc1faf208ecea664440107e8c22cb92..57c8c51e5f7fe32ed91352c225358ff1efd1a3f4 100644 (file)
@@ -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