Fix genreation of arm <->thumb glue stubs by ensuring that they are in the last section linked.

This commit is contained in:
Nick Clifton 2002-05-29 16:03:04 +00:00
parent a95653f53e
commit 8afb0e028c
6 changed files with 124 additions and 50 deletions

View file

@ -1,3 +1,11 @@
2002-05-29 Adam Nemet <anemet@lnxw.com>
* elf32-arm.h (bfd_elf32_arm_get_bfd_for_interworking): Don't add glue
sections only record bfd.
(bfd_elf32_arm_add_glue_sections_to_bfd): New function.
* bfd-in.h (bfd_elf32_arm_add_glue_sections_to_bfd): Declare it.
* bfd-in2.h: Regenerate.
2002-05-28 Nick Clifton <nickc@cambridge.redhat.com> 2002-05-28 Nick Clifton <nickc@cambridge.redhat.com>
* syms.c (_bfd_stab_section_find_nearest_line): Move * syms.c (_bfd_stab_section_find_nearest_line): Move

View file

@ -803,6 +803,9 @@ extern boolean bfd_elf32_arm_process_before_allocation
extern boolean bfd_elf32_arm_get_bfd_for_interworking extern boolean bfd_elf32_arm_get_bfd_for_interworking
PARAMS ((bfd *, struct bfd_link_info *)); PARAMS ((bfd *, struct bfd_link_info *));
extern boolean bfd_elf32_arm_add_glue_sections_to_bfd
PARAMS ((bfd *, struct bfd_link_info *));
/* TI COFF load page support. */ /* TI COFF load page support. */
extern void bfd_ticoff_set_section_load_page extern void bfd_ticoff_set_section_load_page
PARAMS ((struct sec *, int)); PARAMS ((struct sec *, int));

View file

@ -809,6 +809,9 @@ extern boolean bfd_elf32_arm_process_before_allocation
extern boolean bfd_elf32_arm_get_bfd_for_interworking extern boolean bfd_elf32_arm_get_bfd_for_interworking
PARAMS ((bfd *, struct bfd_link_info *)); PARAMS ((bfd *, struct bfd_link_info *));
extern boolean bfd_elf32_arm_add_glue_sections_to_bfd
PARAMS ((bfd *, struct bfd_link_info *));
/* TI COFF load page support. */ /* TI COFF load page support. */
extern void bfd_ticoff_set_section_load_page extern void bfd_ticoff_set_section_load_page
PARAMS ((struct sec *, int)); PARAMS ((struct sec *, int));

View file

@ -547,31 +547,22 @@ record_thumb_to_arm_glue (link_info, h)
return; return;
} }
/* Select a BFD to be used to hold the sections used by the glue code. /* Add the glue sections to ABFD. This function is called from the
This function is called from the linker scripts in ld/emultempl/ linker scripts in ld/emultempl/{armelf}.em. */
{armelf/pe}.em */
boolean boolean
bfd_elf32_arm_get_bfd_for_interworking (abfd, info) bfd_elf32_arm_add_glue_sections_to_bfd (abfd, info)
bfd *abfd; bfd *abfd;
struct bfd_link_info *info; struct bfd_link_info *info;
{ {
struct elf32_arm_link_hash_table *globals;
flagword flags; flagword flags;
asection *sec; asection *sec;
/* If we are only performing a partial link do not bother /* If we are only performing a partial
getting a bfd to hold the glue. */ link do not bother adding the glue. */
if (info->relocateable) if (info->relocateable)
return true; return true;
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
if (globals->bfd_of_glue_owner != NULL)
return true;
sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME); sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
if (sec == NULL) if (sec == NULL)
@ -609,6 +600,32 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
sec->gc_mark = 1; sec->gc_mark = 1;
} }
return true;
}
/* Select a BFD to be used to hold the sections used by the glue code.
This function is called from the linker scripts in ld/emultempl/
{armelf/pe}.em */
boolean
bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
struct elf32_arm_link_hash_table *globals;
/* If we are only performing a partial link
do not bother getting a bfd to hold the glue. */
if (info->relocateable)
return true;
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
if (globals->bfd_of_glue_owner != NULL)
return true;
/* Save the bfd for later use. */ /* Save the bfd for later use. */
globals->bfd_of_glue_owner = abfd; globals->bfd_of_glue_owner = abfd;

View file

@ -1,3 +1,11 @@
2002-05-29 Adam Nemet <anemet@lnxw.com>
* emultempl/armelf.em (arm_elf_after_open): Don't determine
bfd_for_interwork, instead add glue sections to each input bfd.
(bfd_for_interwork): New global.
(arm_elf_set_bfd_for_interworking): New function.
(arm_elf_before_allocation): Use it.
2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net> 2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net>
* Makefile.am: Add DLX make target. * Makefile.am: Add DLX make target.

View file

@ -1,5 +1,5 @@
# This shell script emits a C file. -*- C -*- # 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. # Free Software Foundation, Inc.
# #
# This file is part of GLD, the Gnu Linker. # 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 int no_pipeline_knowledge = 0;
static char *thumb_entry_symbol = NULL; static char *thumb_entry_symbol = NULL;
static bfd *bfd_for_interwork;
static void static void
@ -38,7 +39,6 @@ gld${EMULATION_NAME}_before_parse ()
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`; 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 static void
@ -57,9 +57,7 @@ arm_elf_after_open ()
{ {
LANG_FOR_EACH_INPUT_STATEMENT (is) LANG_FOR_EACH_INPUT_STATEMENT (is)
{ {
/* The interworking bfd must be the last one to be processed */ bfd_elf32_arm_add_glue_sections_to_bfd (is->the_bfd, & link_info);
if (!is->next)
bfd_elf32_arm_get_bfd_for_interworking (is->the_bfd, & link_info);
} }
} }
@ -67,18 +65,56 @@ arm_elf_after_open ()
gld${EMULATION_NAME}_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 PARAMS ((void));
static void static void
arm_elf_before_allocation () arm_elf_before_allocation ()
{ {
bfd *tem;
/* Call the standard elf routine. */ /* Call the standard elf routine. */
gld${EMULATION_NAME}_before_allocation (); 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;
/* Here we rummage through the found bfds to collect glue information */ 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;
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 */ /* FIXME: should this be based on a command line option? krk@cygnus.com */
{ {
LANG_FOR_EACH_INPUT_STATEMENT (is) 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); bfd_elf32_arm_allocate_interworking_sections (& link_info);
} }
static void arm_elf_finish PARAMS ((void)); static void arm_elf_finish PARAMS ((void));
static void static void