diff options
author | Nick Clifton <nickc@redhat.com> | 2002-05-29 16:03:04 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2002-05-29 16:03:04 +0000 |
commit | 8afb0e028ca79a7b870a0293c8e584529adfbe9f (patch) | |
tree | 9e0bf16982ec047849fbf58a1d85b70ea8769bb6 /ld/emultempl/armelf.em | |
parent | a95653f53ef6967a458777b5709ed09b76577b47 (diff) | |
download | gdb-8afb0e028ca79a7b870a0293c8e584529adfbe9f.zip gdb-8afb0e028ca79a7b870a0293c8e584529adfbe9f.tar.gz gdb-8afb0e028ca79a7b870a0293c8e584529adfbe9f.tar.bz2 |
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.em | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index 78a0c35..77cd4f7 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 |