aboutsummaryrefslogtreecommitdiff
path: root/ld
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
commit599917b82b8592664e680ac7fca4260f0160e169 (patch)
treee3ea9c21b833848b833549fa6130c3ee0a63a850 /ld
parentac62e7a36867559d7a8a31a73328ff27278bb122 (diff)
downloadfsf-binutils-gdb-599917b82b8592664e680ac7fca4260f0160e169.zip
fsf-binutils-gdb-599917b82b8592664e680ac7fca4260f0160e169.tar.gz
fsf-binutils-gdb-599917b82b8592664e680ac7fca4260f0160e169.tar.bz2
* 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')
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/ldfile.c94
-rw-r--r--ld/ldlang.c42
-rw-r--r--ld/ldlang.h1
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 <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
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