From d9a7f7ab85d9eb1760aec9575b213294b1bcd9dd Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 22 Aug 2002 19:11:51 +0000 Subject: [PATCH] Set the last bit of DT_INIT and DT_FINI depending on the type of the function. --- ld/ChangeLog | 7 +++ ld/emultempl/armelf.em | 127 +++++++++++++++++++++++++++-------------- 2 files changed, 90 insertions(+), 44 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 6ee0729243..f7c61f305c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2002-08-22 Adam Nemet + + * emultempl/armelf.em: Include elf-bfd.h and elf/arm.h. + (arm_elf_finish): Set the last bit of DT_INIT and DT_FINI + depending on the type of the function. + (arm_elf_convert_thumb_symbol_to_address): New function. + 2002-08-22 Graeme Peterson * Makefile.am: Add esh{l}elf_nto.o files. 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 <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); - - 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.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]; + + 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