diff options
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf32-arm.h | 25 | ||||
-rw-r--r-- | ld/ChangeLog | 6 | ||||
-rw-r--r-- | ld/emultempl/armelf.em | 125 |
4 files changed, 79 insertions, 82 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d3631b0..2ea53bc 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2002-08-27 Adam Nemet <anemet@lnxw.com> + + * elf32-arm.h (elf32_arm_finish_dynamic_sections): Set the last + bit of DT_INIT and DT_FINI for Thumb functions. + 2002-08-26 Alan Modra <amodra@bigpond.net.au> * coffcode.h (coff_set_arch_mach_hook): Handle W65MAGIC. diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index bfc1aa6..5cd9434 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -3546,6 +3546,31 @@ elf32_arm_finish_dynamic_sections (output_bfd, info) } bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); break; + + /* Set the bottom bit of DT_INIT/FINI if the + corresponding function is Thumb. */ + case DT_INIT: + name = info->init_function; + goto get_sym; + case DT_FINI: + name = info->fini_function; + get_sym: + /* If it wasn't set by elf_bfd_final_link + then there is nothing to ajdust. */ + if (dyn.d_un.d_val != 0) + { + struct elf_link_hash_entry * eh; + + eh = elf_link_hash_lookup (elf_hash_table (info), name, + false, false, true); + if (eh != (struct elf_link_hash_entry *) NULL + && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC) + { + dyn.d_un.d_val |= 1; + bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); + } + } + break; } } diff --git a/ld/ChangeLog b/ld/ChangeLog index 92e1872..e487f11 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2002-08-27 Nick Clifton <nickc@redhat.com> + + * emultempl/armelf.em: Revert this patch, it is not needed. + + 2002-08-22 Adam Nemet <anemet@lnxw.com> + 2002-08-20 Dan Kegel <dank@kegel.com> * configure.in: added --with-lib-path argument to ld's configure diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index d2bfb4a..0e65c04 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -24,18 +24,9 @@ # cat >>e${EMULATION_NAME}.c <<EOF -#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 int no_pipeline_knowledge = 0; +static char *thumb_entry_symbol = NULL; +static bfd *bfd_for_interwork; static void @@ -48,6 +39,8 @@ 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 () { @@ -72,15 +65,18 @@ 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); @@ -94,10 +90,12 @@ 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 (); @@ -136,27 +134,7 @@ arm_elf_before_allocation () bfd_elf32_arm_allocate_interworking_sections (& link_info); } -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 PARAMS ((void)); static void arm_elf_finish () @@ -166,61 +144,44 @@ arm_elf_finish () /* Call the elf32.em routine. */ gld${EMULATION_NAME}_finish (); - 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 (thumb_entry_symbol == NULL) + return; + + 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) - && 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; - 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]; + /* 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.fini_function = buffer; + 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; } + else + einfo (_("%P: warning: connot find thumb start symbol %s\n"), + thumb_entry_symbol); } EOF |