summaryrefslogtreecommitdiff
path: root/ld/emultempl/armelf.em
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2002-05-29 16:03:04 +0000
committerNick Clifton <nickc@redhat.com>2002-05-29 16:03:04 +0000
commit21d3e2fb9adf2fc9b0904a88d34357e58719d94a (patch)
tree101804c7a6c09763bf5bbab7594db62e1377531c /ld/emultempl/armelf.em
parentacaf8e0c84d0309a277eed01d214e2011149bc0f (diff)
downloadbinutils-redhat-21d3e2fb9adf2fc9b0904a88d34357e58719d94a.tar.gz
Fix genreation of arm <->thumb glue stubs by ensuring that they are in the last section linked.
Diffstat (limited to 'ld/emultempl/armelf.em')
-rw-r--r--ld/emultempl/armelf.em57
1 files changed, 46 insertions, 11 deletions
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 78a0c35d4b..77cd4f778d 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -1,5 +1,5 @@
# This shell script emits a C file. -*- C -*-
-# Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000
+# Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2002
# Free Software Foundation, Inc.
#
# This file is part of GLD, the Gnu Linker.
@@ -26,6 +26,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
static int no_pipeline_knowledge = 0;
static char *thumb_entry_symbol = NULL;
+static bfd *bfd_for_interwork;
static void
@@ -38,8 +39,7 @@ gld${EMULATION_NAME}_before_parse ()
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
}
-
-static void arm_elf_after_open PARAMS((void));
+static void arm_elf_after_open PARAMS ((void));
static void
arm_elf_after_open ()
@@ -57,9 +57,7 @@ arm_elf_after_open ()
{
LANG_FOR_EACH_INPUT_STATEMENT (is)
{
- /* The interworking bfd must be the last one to be processed */
- if (!is->next)
- bfd_elf32_arm_get_bfd_for_interworking (is->the_bfd, & link_info);
+ bfd_elf32_arm_add_glue_sections_to_bfd (is->the_bfd, & link_info);
}
}
@@ -67,19 +65,57 @@ arm_elf_after_open ()
gld${EMULATION_NAME}_after_open ();
}
+static void arm_elf_set_bfd_for_interworking
+ PARAMS ((lang_statement_union_type *));
+
+static void
+arm_elf_set_bfd_for_interworking (statement)
+ lang_statement_union_type *statement;
+{
+ if (statement->header.type == lang_input_section_enum
+ && statement->input_section.ifile->just_syms_flag == false)
+ {
+ asection *i = statement->input_section.section;
+ asection *output_section = i->output_section;
+
+ ASSERT (output_section->owner == output_bfd);
+
+ if ((output_section->flags & SEC_HAS_CONTENTS) != 0
+ && (i->flags & SEC_NEVER_LOAD) == 0
+ && ! i->owner->output_has_begun)
+ {
+ bfd_for_interwork = i->owner;
+ bfd_for_interwork->output_has_begun = true;
+ }
+ }
+}
static void arm_elf_before_allocation PARAMS ((void));
static void
arm_elf_before_allocation ()
{
+ bfd *tem;
+
/* Call the standard elf routine. */
gld${EMULATION_NAME}_before_allocation ();
- /* We should be able to set the size of the interworking stub section */
+ /* The interworking bfd must be the last one in the link. */
+ bfd_for_interwork = NULL;
+ for (tem = link_info.input_bfds; tem != NULL; tem = tem->link_next)
+ tem->output_has_begun = false;
+
+ lang_for_each_statement (arm_elf_set_bfd_for_interworking);
+ ASSERT (bfd_for_interwork != NULL);
+ for (tem = link_info.input_bfds; tem != NULL; tem = tem->link_next)
+ tem->output_has_begun = false;
- /* Here we rummage through the found bfds to collect glue information */
- /* FIXME: should this be based on a command line option? krk@cygnus.com */
+ bfd_elf32_arm_get_bfd_for_interworking (bfd_for_interwork, &link_info);
+
+ /* We should be able to set the size of the interworking stub section. */
+
+ /* Here we rummage through the found bfds to collect glue information. */
+ /* FIXME: should this be based on a command line option? krk@cygnus.com */
{
LANG_FOR_EACH_INPUT_STATEMENT (is)
{
@@ -92,11 +128,10 @@ arm_elf_before_allocation ()
}
}
- /* We have seen it all. Allocate it, and carry on */
+ /* We have seen it all. Allocate it, and carry on. */
bfd_elf32_arm_allocate_interworking_sections (& link_info);
}
-
static void arm_elf_finish PARAMS ((void));
static void