diff options
author | Nick Clifton <nickc@redhat.com> | 2002-08-22 19:11:51 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2002-08-22 19:11:51 +0000 |
commit | 2b1d386f90830a33279cf6d2ff05e3e2c710f8b7 (patch) | |
tree | 13d4b5bd28b0a14f88677e0ed87b8c85160a27e6 /ld/emultempl | |
parent | f86806dc4c2d99dc3184745bfd30c5b20cac31c8 (diff) | |
download | binutils-redhat-2b1d386f90830a33279cf6d2ff05e3e2c710f8b7.tar.gz |
Set the last bit of DT_INIT and DT_FINI depending on the type of the function.
Diffstat (limited to 'ld/emultempl')
-rw-r--r-- | ld/emultempl/armelf.em | 125 |
1 files changed, 82 insertions, 43 deletions
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index 0e65c04ca6..d2bfb4aba4 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -24,9 +24,18 @@ # cat >>e${EMULATION_NAME}.c <<EOF -static int no_pipeline_knowledge = 0; -static char *thumb_entry_symbol = NULL; -static bfd *bfd_for_interwork; +#include "elf-bfd.h" +#include "elf/arm.h" + +static int no_pipeline_knowledge = 0; +static char * thumb_entry_symbol = NULL; +static bfd * bfd_for_interwork; + +static void arm_elf_after_open PARAMS ((void)); +static void arm_elf_set_bfd_for_interworking PARAMS ((lang_statement_union_type *)); +static void arm_elf_before_allocation PARAMS ((void)); +static void arm_elf_stringify_thumb_address PARAMS ((struct bfd_link_hash_entry *, char *)); +static void arm_elf_finish PARAMS ((void)); static void @@ -39,8 +48,6 @@ 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 () { @@ -65,18 +72,15 @@ 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; + 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; + asection * i = statement->input_section.section; + asection * output_section = i->output_section; ASSERT (output_section->owner == output_bfd); @@ -90,12 +94,10 @@ arm_elf_set_bfd_for_interworking (statement) } } -static void arm_elf_before_allocation PARAMS ((void)); - static void arm_elf_before_allocation () { - bfd *tem; + bfd * tem; /* Call the standard elf routine. */ gld${EMULATION_NAME}_before_allocation (); @@ -134,7 +136,27 @@ arm_elf_before_allocation () bfd_elf32_arm_allocate_interworking_sections (& link_info); } -static void arm_elf_finish PARAMS ((void)); +void +arm_elf_stringify_thumb_address (h, buffer) + struct bfd_link_hash_entry * h; + char * buffer; +{ + bfd_vma val; + + /* Get the address of the symbol. */ + val = (h->u.def.value + + bfd_get_section_vma (output_bfd, + h->u.def.section->output_section) + + h->u.def.section->output_offset); + /* This is a thumb address, so the bottom bit of its address must be set. */ + val |= 1; + + /* Now convert this value into a string. */ + buffer[0] = '0'; + buffer[1] = 'x'; + + sprintf_vma (buffer + 2, val); +} static void arm_elf_finish () @@ -144,44 +166,61 @@ arm_elf_finish () /* Call the elf32.em routine. */ gld${EMULATION_NAME}_finish (); - if (thumb_entry_symbol == NULL) - return; - - h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, - false, false, true); + if (thumb_entry_symbol != NULL) + { + static char buffer[32]; + + h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, + false, false, true); + + if (h != (struct bfd_link_hash_entry *) NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak) + && h->u.def.section->output_section != NULL) + { + if (entry_symbol.name != NULL && entry_from_cmdline) + einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"), + thumb_entry_symbol, entry_symbol.name); + + arm_elf_stringify_thumb_address (h, buffer); + entry_symbol.name = buffer; + } + else + einfo (_("%P: warning: cannot find thumb start symbol %s\n"), + thumb_entry_symbol); + } + + /* If init is a Thumb function set the LSB. */ + h = bfd_link_hash_lookup (link_info.hash, link_info.init_function, false, + false, true); if (h != (struct bfd_link_hash_entry *) NULL && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak) + && ELF_ST_TYPE (((struct elf_link_hash_entry *)h)->type) == STT_ARM_TFUNC && h->u.def.section->output_section != NULL) { static char buffer[32]; - bfd_vma val; - - /* Special procesing is required for a Thumb entry symbol. The - bottom bit of its address must be set. */ - val = (h->u.def.value - + bfd_get_section_vma (output_bfd, - h->u.def.section->output_section) - + h->u.def.section->output_offset); - - val |= 1; - /* Now convert this value into a string and store it in entry_symbol - where the lang_finish() function will pick it up. */ - buffer[0] = '0'; - buffer[1] = 'x'; - - sprintf_vma (buffer + 2, val); + arm_elf_stringify_thumb_address (h, buffer); + link_info.init_function = buffer; + } + + /* If fini is a Thumb function set the LSB. */ + h = bfd_link_hash_lookup (link_info.hash, link_info.fini_function, false, + false, true); + + if (h != (struct bfd_link_hash_entry *) NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak) + && ELF_ST_TYPE (((struct elf_link_hash_entry *)h)->type) == STT_ARM_TFUNC + && h->u.def.section->output_section != NULL) + { + static char buffer[32]; - if (entry_symbol.name != NULL && entry_from_cmdline) - einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"), - thumb_entry_symbol, entry_symbol.name); - entry_symbol.name = buffer; + arm_elf_stringify_thumb_address (h, buffer); + link_info.fini_function = buffer; } - else - einfo (_("%P: warning: connot find thumb start symbol %s\n"), - thumb_entry_symbol); } EOF |