include/elf/
authorRichard Sandiford <rdsandiford@googlemail.com>
Mon, 14 Mar 2011 15:55:04 +0000 (15:55 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Mon, 14 Mar 2011 15:55:04 +0000 (15:55 +0000)
* internal.h (elf_internal_sym): Add st_target_internal.
* arm.h (arm_st_branch_type): New enum.
(ARM_SYM_BRANCH_TYPE): New macro.

bfd/
* elf-bfd.h (elf_link_hash_entry): Add target_internal.
* elf.c (swap_out_syms): Set st_target_internal for each
Elf_Internal_Sym.
* elfcode.h (elf_swap_symbol_in): Likewise.
* elf32-i370.c (i370_elf_finish_dynamic_sections): Likewise.
* elf32-sh-symbian.c (sh_symbian_relocate_section): Likewise.
* elf64-sparc.c (elf64_sparc_output_arch_syms): Likewise.
* elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Likewise.
* elflink.c (elf_link_output_extsym): Likewise.
(bfd_elf_final_link): Likewise.
(elf_link_add_object_symbols): Copy st_target_internal
to the hash table if we see a definition.
(_bfd_elf_copy_link_hash_symbol_type): Copy target_internal.
* elf32-arm.c (elf32_arm_stub_hash_entry): Replace st_type with
a branch_type field.
(a8_erratum_fix, a8_erratum_reloc): Likewise.
(arm_type_of_stub): Replace actual_st_type with an
actual_branch_type parameter.
(arm_build_one_stub): Use branch types rather than st_types to
determine the type of branch.
(cortex_a8_erratum_scan): Likewise.
(elf32_arm_size_stubs): Likewise.
(bfd_elf32_arm_process_before_allocation): Likewise.
(allocate_dynrelocs_for_symbol): Likewise.
(elf32_arm_finish_dynamic_sections): Likewise.
(elf32_arm_final_link_relocate): Replace sym_flags parameter with
a branch_type parameter.
(elf32_arm_relocate_section): Update call accordingly.
(elf32_arm_adjust_dynamic_symbol): Don't check STT_ARM_TFUNC.
(elf32_arm_output_map_sym): Initialize st_target_internal.
(elf32_arm_output_stub_sym): Likewise.
(elf32_arm_symbol_processing): Delete.
(elf32_arm_swap_symbol_in): Convert STT_ARM_TFUNCs into STT_FUNCs.
Use st_target_internal to record the branch type.
(elf32_arm_swap_symbol_out): Use st_target_internal to test for
Thumb functions.
(elf32_arm_is_function_type): Delete.
(elf_backend_symbol_processing): Likewise.
(elf_backend_is_function_type): Likewise.

gas/
* config/tc-arm.c (arm_adjust_symtab): Set the branch type
for Thumb symbols.

ld/
* emultempl/armelf.em (gld${EMULATION_NAME}_finish): Check
eh->target_internal.

opcodes/
* arm-dis.c (get_sym_code_type): Don't check for STT_ARM_TFUNC.
Use branch types instead.
(print_insn): Likewise.

19 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elf32-arm.c
bfd/elf32-i370.c
bfd/elf32-sh-symbian.c
bfd/elf64-sparc.c
bfd/elfcode.h
bfd/elflink.c
bfd/elfxx-sparc.c
gas/ChangeLog
gas/config/tc-arm.c
include/elf/ChangeLog
include/elf/arm.h
include/elf/internal.h
ld/ChangeLog
ld/emultempl/armelf.em
opcodes/ChangeLog
opcodes/arm-dis.c

index 481145322ff1e792cb5ba68539a6bc72f1e8276d..0bdc2adbb9fcb114f5269963ffcc42ccd27e1d15 100644 (file)
@@ -1,3 +1,45 @@
+2011-03-14  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * elf-bfd.h (elf_link_hash_entry): Add target_internal.
+       * elf.c (swap_out_syms): Set st_target_internal for each
+       Elf_Internal_Sym.
+       * elfcode.h (elf_swap_symbol_in): Likewise.
+       * elf32-i370.c (i370_elf_finish_dynamic_sections): Likewise.
+       * elf32-sh-symbian.c (sh_symbian_relocate_section): Likewise.
+       * elf64-sparc.c (elf64_sparc_output_arch_syms): Likewise.
+       * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Likewise.
+       * elflink.c (elf_link_output_extsym): Likewise.
+       (bfd_elf_final_link): Likewise.
+       (elf_link_add_object_symbols): Copy st_target_internal
+       to the hash table if we see a definition.
+       (_bfd_elf_copy_link_hash_symbol_type): Copy target_internal.
+       * elf32-arm.c (elf32_arm_stub_hash_entry): Replace st_type with
+       a branch_type field.
+       (a8_erratum_fix, a8_erratum_reloc): Likewise.
+       (arm_type_of_stub): Replace actual_st_type with an
+       actual_branch_type parameter.
+       (arm_build_one_stub): Use branch types rather than st_types to
+       determine the type of branch.
+       (cortex_a8_erratum_scan): Likewise.
+       (elf32_arm_size_stubs): Likewise.
+       (bfd_elf32_arm_process_before_allocation): Likewise.
+       (allocate_dynrelocs_for_symbol): Likewise.
+       (elf32_arm_finish_dynamic_sections): Likewise.
+       (elf32_arm_final_link_relocate): Replace sym_flags parameter with
+       a branch_type parameter.
+       (elf32_arm_relocate_section): Update call accordingly.
+       (elf32_arm_adjust_dynamic_symbol): Don't check STT_ARM_TFUNC.
+       (elf32_arm_output_map_sym): Initialize st_target_internal.
+       (elf32_arm_output_stub_sym): Likewise.
+       (elf32_arm_symbol_processing): Delete.
+       (elf32_arm_swap_symbol_in): Convert STT_ARM_TFUNCs into STT_FUNCs.
+       Use st_target_internal to record the branch type.
+       (elf32_arm_swap_symbol_out): Use st_target_internal to test for
+       Thumb functions.
+       (elf32_arm_is_function_type): Delete.
+       (elf_backend_symbol_processing): Likewise.
+       (elf_backend_is_function_type): Likewise.
+
 2011-03-14  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * elf32-arm.c (elf32_arm_check_relocs): Always assign a dynobj.
index cc835881f11140a1090bb94336286692b7153753..21ec38f2c94a5145534c2d2bec34bdf11790ad3f 100644 (file)
@@ -153,6 +153,9 @@ struct elf_link_hash_entry
   /* Symbol st_other value, symbol visibility.  */
   unsigned int other : 8;
 
+  /* The symbol's st_target_internal value (see Elf_Internal_Sym).  */
+  unsigned int target_internal : 8;
+
   /* Symbol is referenced by a non-shared object (other than the object
      in which it is defined).  */
   unsigned int ref_regular : 1;
index c77dcedc569fd165ece14e02b9e456b52a96d549..f69abf221811af2b95c1497133c8cdf3d8a08366 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -6542,6 +6542,7 @@ swap_out_syms (bfd *abfd,
     sym.st_info = 0;
     sym.st_other = 0;
     sym.st_shndx = SHN_UNDEF;
+    sym.st_target_internal = 0;
     bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
     outbound_syms += bed->s->sizeof_sym;
     if (outbound_shndx != NULL)
@@ -6741,9 +6742,16 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
        }
 
       if (type_ptr != NULL)
-       sym.st_other = type_ptr->internal_elf_sym.st_other;
+       {
+         sym.st_other = type_ptr->internal_elf_sym.st_other;
+         sym.st_target_internal
+           = type_ptr->internal_elf_sym.st_target_internal;
+       }
       else
-       sym.st_other = 0;
+       {
+         sym.st_other = 0;
+         sym.st_target_internal = 0;
+       }
 
       bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
       outbound_syms += bed->s->sizeof_sym;
index 2636052a059ae5de1a0fd9e5eb4091e92212fba4..9f2b696eb604a9d064939762aa87a98b484609da 100644 (file)
@@ -2410,8 +2410,8 @@ struct elf32_arm_stub_hash_entry
   /* The symbol table entry, if any, that this was derived from.  */
   struct elf32_arm_link_hash_entry *h;
 
-  /* Destination symbol type (STT_ARM_TFUNC, ...) */
-  unsigned char st_type;
+  /* Type of branch.  */
+  enum arm_st_branch_type branch_type;
 
   /* Where this stub is being called from, or, in the case of combined
      stub sections, the first input section in the group.  */
@@ -2531,7 +2531,7 @@ struct a8_erratum_fix {
   unsigned long orig_insn;
   char *stub_name;
   enum elf32_arm_stub_type stub_type;
-  int st_type;
+  enum arm_st_branch_type branch_type;
 };
 
 /* A table of relocs applied to branches which might trigger Cortex-A8
@@ -2543,7 +2543,7 @@ struct a8_erratum_reloc {
   struct elf32_arm_link_hash_entry *hash;
   const char *sym_name;
   unsigned int r_type;
-  unsigned char st_type;
+  enum arm_st_branch_type branch_type;
   bfd_boolean non_a8_stub;
 };
 
@@ -3189,7 +3189,7 @@ static enum elf32_arm_stub_type
 arm_type_of_stub (struct bfd_link_info *info,
                  asection *input_sec,
                  const Elf_Internal_Rela *rel,
-                 int *actual_st_type,
+                 enum arm_st_branch_type *actual_branch_type,
                  struct elf32_arm_link_hash_entry *hash,
                  bfd_vma destination,
                  asection *sym_sec,
@@ -3204,11 +3204,9 @@ arm_type_of_stub (struct bfd_link_info *info,
   int thumb_only;
   enum elf32_arm_stub_type stub_type = arm_stub_none;
   int use_plt = 0;
-  int st_type = *actual_st_type;
+  enum arm_st_branch_type branch_type = *actual_branch_type;
 
-  /* We don't know the actual type of destination in case it is of
-     type STT_SECTION: give up.  */
-  if (st_type == STT_SECTION)
+  if (branch_type == ST_BRANCH_LONG)
     return stub_type;
 
   globals = elf32_arm_hash_table (info);
@@ -3245,7 +3243,7 @@ arm_type_of_stub (struct bfd_link_info *info,
       destination = (globals->root.splt->output_section->vma
                     + globals->root.splt->output_offset
                     + hash->root.plt.offset);
-      st_type = STT_FUNC;
+      branch_type = ST_BRANCH_TO_ARM;
     }
 
   branch_offset = (bfd_signed_vma)(destination - location);
@@ -3267,13 +3265,13 @@ arm_type_of_stub (struct bfd_link_info *info,
          || (thumb2
              && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
                  || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
-         || ((st_type != STT_ARM_TFUNC)
+         || (branch_type == ST_BRANCH_TO_ARM
              && (((r_type == R_ARM_THM_CALL
                    || r_type == R_ARM_THM_TLS_CALL) && !globals->use_blx)
                  || (r_type == R_ARM_THM_JUMP24))
              && !use_plt))
        {
-         if (st_type == STT_ARM_TFUNC)
+         if (branch_type == ST_BRANCH_TO_THUMB)
            {
              /* Thumb to thumb.  */
              if (!thumb_only)
@@ -3353,7 +3351,7 @@ arm_type_of_stub (struct bfd_link_info *info,
           || r_type == R_ARM_PLT32
           || r_type == R_ARM_TLS_CALL)
     {
-      if (st_type == STT_ARM_TFUNC)
+      if (branch_type == ST_BRANCH_TO_THUMB)
        {
          /* Arm to thumb.  */
 
@@ -3412,7 +3410,7 @@ arm_type_of_stub (struct bfd_link_info *info,
 
   /* If a stub is needed, record the actual destination type.  */
   if (stub_type != arm_stub_none)
-    *actual_st_type = st_type;
+    *actual_branch_type = branch_type;
 
   return stub_type;
 }
@@ -3642,7 +3640,8 @@ elf32_arm_tls_transition (struct bfd_link_info *info, int r_type,
 static bfd_reloc_status_type elf32_arm_final_link_relocate
   (reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,
    Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *,
-   const char *, int, struct elf_link_hash_entry *, bfd_boolean *, char **);
+   const char *, enum arm_st_branch_type, struct elf_link_hash_entry *,
+   bfd_boolean *, char **);
 
 static unsigned int
 arm_stub_required_alignment (enum elf32_arm_stub_type stub_type)
@@ -3793,7 +3792,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
   BFD_ASSERT (size == stub_entry->stub_size);
 
   /* Destination is Thumb. Force bit 0 to 1 to reflect this.  */
-  if (stub_entry->st_type == STT_ARM_TFUNC)
+  if (stub_entry->branch_type == ST_BRANCH_TO_THUMB)
     sym_value |= 1;
 
   /* Assume there is at least one and at most MAXRELOCS entries to relocate
@@ -3809,9 +3808,9 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
        Elf_Internal_Rela rel;
        bfd_boolean unresolved_reloc;
        char *error_message;
-       int sym_flags
-         = (template_sequence[stub_reloc_idx[i]].r_type != R_ARM_THM_XPC22)
-           ? STT_ARM_TFUNC : 0;
+       enum arm_st_branch_type branch_type
+         = (template_sequence[stub_reloc_idx[i]].r_type != R_ARM_THM_XPC22
+            ? ST_BRANCH_TO_THUMB : ST_BRANCH_TO_ARM);
        bfd_vma points_to = sym_value + stub_entry->target_addend;
 
        rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i];
@@ -3835,7 +3834,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
        elf32_arm_final_link_relocate (elf32_arm_howto_from_type
            (template_sequence[stub_reloc_idx[i]].r_type),
          stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
-         points_to, info, stub_entry->target_section, "", sym_flags,
+         points_to, info, stub_entry->target_section, "", branch_type,
          (struct elf_link_hash_entry *) stub_entry->h, &unresolved_reloc,
          &error_message);
       }
@@ -3855,7 +3854,8 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
        elf32_arm_final_link_relocate (elf32_arm_howto_from_type
            (template_sequence[stub_reloc_idx[i]].r_type),
          stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
-         points_to, info, stub_entry->target_section, "", stub_entry->st_type,
+         points_to, info, stub_entry->target_section, "",
+         stub_entry->branch_type,
          (struct elf_link_hash_entry *) stub_entry->h, &unresolved_reloc,
          &error_message);
       }
@@ -4311,7 +4311,8 @@ cortex_a8_erratum_scan (bfd *input_bfd,
 
                      if (found->r_type == R_ARM_THM_CALL)
                        {
-                         if (found->st_type != STT_ARM_TFUNC || use_plt)
+                         if (found->branch_type == ST_BRANCH_TO_ARM
+                             || use_plt)
                            force_target_arm = TRUE;
                          else
                            force_target_thumb = TRUE;
@@ -4448,8 +4449,8 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                           a8_fixes[num_a8_fixes].orig_insn = insn;
                           a8_fixes[num_a8_fixes].stub_name = stub_name;
                           a8_fixes[num_a8_fixes].stub_type = stub_type;
-                          a8_fixes[num_a8_fixes].st_type =
-                           is_blx ? STT_FUNC : STT_ARM_TFUNC;
+                          a8_fixes[num_a8_fixes].branch_type =
+                           is_blx ? ST_BRANCH_TO_ARM : ST_BRANCH_TO_THUMB;
 
                           num_a8_fixes++;
                         }
@@ -4620,7 +4621,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                  const char *sym_name;
                  char *stub_name;
                  const asection *id_sec;
-                 int st_type;
+                 enum arm_st_branch_type branch_type;
                  bfd_boolean created_stub = FALSE;
 
                  r_type = ELF32_R_TYPE (irela->r_info);
@@ -4677,7 +4678,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                      sym_sec = htab->root.splt;
                      sym_value = htab->tls_trampoline;
                      hash = 0;
-                     st_type = STT_FUNC;
+                     branch_type = ST_BRANCH_TO_ARM;
                    }
                  else if (!hash)
                    {
@@ -4718,7 +4719,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                      destination = (sym_value + irela->r_addend
                                     + sym_sec->output_offset
                                     + sym_sec->output_section->vma);
-                     st_type = ELF_ST_TYPE (sym->st_info);
+                     branch_type = ARM_SYM_BRANCH_TYPE (sym);
                      sym_name
                        = bfd_elf_string_from_elf_section (input_bfd,
                                                           symtab_hdr->sh_link,
@@ -4792,7 +4793,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                          bfd_set_error (bfd_error_bad_value);
                          goto error_ret_free_internal;
                        }
-                     st_type = ELF_ST_TYPE (hash->root.type);
+                     branch_type = hash->root.target_internal;
                      sym_name = hash->root.root.root.string;
                    }
 
@@ -4800,7 +4801,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                    {
                      /* Determine what (if any) linker stub is needed.  */
                      stub_type = arm_type_of_stub (info, section, irela,
-                                                   &st_type, hash,
+                                                   &branch_type, hash,
                                                    destination, sym_sec,
                                                    input_bfd, sym_name);
                      if (stub_type == arm_stub_none)
@@ -4842,7 +4843,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                       stub_entry->target_section = sym_sec;
                       stub_entry->stub_type = stub_type;
                       stub_entry->h = hash;
-                      stub_entry->st_type = st_type;
+                      stub_entry->branch_type = branch_type;
 
                       if (sym_name == NULL)
                        sym_name = "unnamed";
@@ -4858,14 +4859,14 @@ elf32_arm_size_stubs (bfd *output_bfd,
 
                       /* For historical reasons, use the existing names for
                         ARM-to-Thumb and Thumb-to-ARM stubs.  */
-                      if ( ((r_type == (unsigned int) R_ARM_THM_CALL)
-                            || (r_type == (unsigned int) R_ARM_THM_JUMP24))
-                           && st_type != STT_ARM_TFUNC)
+                      if ((r_type == (unsigned int) R_ARM_THM_CALL
+                          || r_type == (unsigned int) R_ARM_THM_JUMP24)
+                         && branch_type == ST_BRANCH_TO_ARM)
                        sprintf (stub_entry->output_name,
                                 THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
-                      else if ( ((r_type == (unsigned int) R_ARM_CALL)
-                                || (r_type == (unsigned int) R_ARM_JUMP24))
-                               && st_type == STT_ARM_TFUNC)
+                      else if ((r_type == (unsigned int) R_ARM_CALL
+                              || r_type == (unsigned int) R_ARM_JUMP24)
+                              && branch_type == ST_BRANCH_TO_THUMB)
                        sprintf (stub_entry->output_name,
                                 ARM2THUMB_GLUE_ENTRY_NAME, sym_name);
                       else
@@ -4907,7 +4908,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                           a8_relocs[num_a8_relocs].from = from;
                           a8_relocs[num_a8_relocs].destination = destination;
                           a8_relocs[num_a8_relocs].r_type = r_type;
-                          a8_relocs[num_a8_relocs].st_type = st_type;
+                          a8_relocs[num_a8_relocs].branch_type = branch_type;
                           a8_relocs[num_a8_relocs].sym_name = sym_name;
                           a8_relocs[num_a8_relocs].non_a8_stub = created_stub;
                           a8_relocs[num_a8_relocs].hash = hash;
@@ -5012,7 +5013,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
           stub_entry->target_value = a8_fixes[i].offset;
           stub_entry->target_addend = a8_fixes[i].addend;
           stub_entry->orig_insn = a8_fixes[i].orig_insn;
-         stub_entry->st_type = a8_fixes[i].st_type;
+         stub_entry->branch_type = a8_fixes[i].branch_type;
 
           size = find_stub_size_and_template (a8_fixes[i].stub_type,
                                               &template_sequence,
@@ -5777,7 +5778,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
              /* This one is a call from arm code.  We need to look up
                 the target of the call.  If it is a thumb target, we
                 insert glue.  */
-             if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
+             if (h->target_internal == ST_BRANCH_TO_THUMB)
                record_arm_to_thumb_glue (link_info, h);
              break;
 
@@ -7241,7 +7242,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                               struct bfd_link_info *       info,
                               asection *                   sym_sec,
                               const char *                 sym_name,
-                              int                          sym_flags,
+                              enum arm_st_branch_type     branch_type,
                               struct elf_link_hash_entry * h,
                               bfd_boolean *                unresolved_reloc_p,
                               char **                      error_message)
@@ -7423,7 +7424,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              int symbol;
 
              /* This symbol is local, or marked to become local.  */
-             if (sym_flags == STT_ARM_TFUNC)
+             if (branch_type == ST_BRANCH_TO_THUMB)
                value |= 1;
              if (globals->symbian_p)
                {
@@ -7501,7 +7502,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              /* Check for Arm calling Arm function.  */
              /* FIXME: Should we translate the instruction into a BL
                 instruction instead ?  */
-             if (sym_flags != STT_ARM_TFUNC)
+             if (branch_type != ST_BRANCH_TO_THUMB)
                (*_bfd_error_handler)
                  (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
                   input_bfd,
@@ -7510,7 +7511,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          else if (r_type == R_ARM_PC24)
            {
              /* Check for Arm calling Thumb function.  */
-             if (sym_flags == STT_ARM_TFUNC)
+             if (branch_type == ST_BRANCH_TO_THUMB)
                {
                  if (elf32_arm_to_thumb_stub (info, sym_name, input_bfd,
                                               output_bfd, input_section,
@@ -7534,7 +7535,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
              hash = (struct elf32_arm_link_hash_entry *) h;
              stub_type = arm_type_of_stub (info, input_section, rel,
-                                           &sym_flags, hash,
+                                           &branch_type, hash,
                                            value, sym_sec,
                                            input_bfd, sym_name);
 
@@ -7566,7 +7567,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                      *unresolved_reloc_p = FALSE;
                      /* The PLT entry is in ARM mode, regardless of the
                         target function.  */
-                     sym_flags = STT_FUNC;
+                     branch_type = ST_BRANCH_TO_ARM;
                    }
                }
            }
@@ -7633,7 +7634,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              if (r_type == R_ARM_CALL)
                {
                  /* Set the H bit in the BLX instruction.  */
-                 if (sym_flags == STT_ARM_TFUNC)
+                 if (branch_type == ST_BRANCH_TO_THUMB)
                    {
                      if (addend)
                        value |= (1 << 24);
@@ -7644,7 +7645,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  /* Select the correct instruction (BL or BLX).  */
                  /* Only if we are not handling a BL to a stub. In this
                     case, mode switching is performed by the stub.  */
-                 if (sym_flags == STT_ARM_TFUNC && !stub_entry)
+                 if (branch_type == ST_BRANCH_TO_THUMB && !stub_entry)
                    value |= (1 << 28);
                  else
                    {
@@ -7658,7 +7659,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        case R_ARM_ABS32:
          value += addend;
-         if (sym_flags == STT_ARM_TFUNC)
+         if (branch_type == ST_BRANCH_TO_THUMB)
            value |= 1;
          break;
 
@@ -7668,7 +7669,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        case R_ARM_REL32:
          value += addend;
-         if (sym_flags == STT_ARM_TFUNC)
+         if (branch_type == ST_BRANCH_TO_THUMB)
            value |= 1;
          value -= (input_section->output_section->vma
                    + input_section->output_offset + rel->r_offset);
@@ -7692,7 +7693,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            }
          value &= 0x7fffffff;
          value |= (bfd_get_32 (input_bfd, hit_data) & 0x80000000);
-         if (sym_flags == STT_ARM_TFUNC)
+         if (branch_type == ST_BRANCH_TO_THUMB)
            value |= 1;
          break;
        }
@@ -7912,7 +7913,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            /* Check for Thumb to Thumb call.  */
            /* FIXME: Should we translate the instruction into a BL
               instruction instead ?  */
-           if (sym_flags == STT_ARM_TFUNC)
+           if (branch_type == ST_BRANCH_TO_THUMB)
              (*_bfd_error_handler)
                (_("%B: Warning: Thumb BLX instruction targets thumb function '%s'."),
                 input_bfd,
@@ -7924,7 +7925,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
               If it is a call relative to a section name, then it is not a
               function call at all, but rather a long jump.  Calls through
               the PLT do not require stubs.  */
-           if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION
+           if (branch_type == ST_BRANCH_TO_ARM
                && (h == NULL || splt == NULL
                    || h->plt.offset == (bfd_vma) -1))
              {
@@ -7945,7 +7946,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                      return bfd_reloc_dangerous;
                  }
              }
-           else if (sym_flags == STT_ARM_TFUNC && globals->use_blx
+           else if (branch_type == ST_BRANCH_TO_THUMB
+                    && globals->use_blx
                     && r_type == R_ARM_THM_CALL)
              {
                /* Make sure this is a BL.  */
@@ -7964,7 +7966,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            hash = (struct elf32_arm_link_hash_entry *) h;
 
            stub_type = arm_type_of_stub (info, input_section, rel,
-                                         &sym_flags, hash, value, sym_sec,
+                                         &branch_type, hash, value, sym_sec,
                                          input_bfd, sym_name);
 
            if (stub_type != arm_stub_none)
@@ -7986,7 +7988,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  {
                    if ((stub_entry
                         && !arm_stub_is_thumb (stub_entry->stub_type))
-                       || (sym_flags != STT_ARM_TFUNC))
+                       || branch_type != ST_BRANCH_TO_THUMB)
                      lower_insn = (lower_insn & ~0x1000) | 0x0800;
                  }
              }
@@ -8008,13 +8010,13 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                   the BL to a BLX instruction to call the ARM-mode
                   PLT entry.  */
                lower_insn = (lower_insn & ~0x1000) | 0x0800;
-               sym_flags = STT_FUNC;
+               branch_type = ST_BRANCH_TO_ARM;
              }
            else
              {
                /* Target the Thumb stub before the ARM PLT entry.  */
                value -= PLT_THUMB_STUB_SIZE;
-               sym_flags = STT_ARM_TFUNC;
+               branch_type = ST_BRANCH_TO_THUMB;
              }
            *unresolved_reloc_p = FALSE;
          }
@@ -8242,7 +8244,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       /* If we are addressing a Thumb function, we need to adjust the
         address by one, so that attempts to call the function pointer will
         correctly interpret it as Thumb code.  */
-      if (sym_flags == STT_ARM_TFUNC)
+      if (branch_type == ST_BRANCH_TO_THUMB)
        value += 1;
 
       /* Note that sgot->output_offset is not involved in this
@@ -8316,7 +8318,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  else
                    outrel.r_info = 0;
                  outrel.r_addend = value;
-                 if (sym_flags == STT_ARM_TFUNC)
+                 if (branch_type == ST_BRANCH_TO_THUMB)
                    outrel.r_addend |= 1;
                }
 
@@ -8361,7 +8363,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                 adjust the address by one, so that attempts to
                 call the function pointer will correctly
                 interpret it as Thumb code.  */
-             if (sym_flags == STT_ARM_TFUNC)
+             if (branch_type == ST_BRANCH_TO_THUMB)
                value |= 1;
 
              if (globals->use_rel)
@@ -8645,7 +8647,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          {
            bfd_signed_vma offset;
            enum elf32_arm_stub_type stub_type
-             = arm_type_of_stub (info, input_section, rel, &sym_flags,
+             = arm_type_of_stub (info, input_section, rel, &branch_type,
                                  (struct elf32_arm_link_hash_entry *)h,
                                  globals->tls_trampoline, globals->root.splt,
                                  input_bfd, sym_name);
@@ -8854,7 +8856,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        if (r_type == R_ARM_MOVW_BREL && value >= 0x10000)
           return bfd_reloc_overflow;
 
-       if (sym_flags == STT_ARM_TFUNC)
+       if (branch_type == ST_BRANCH_TO_THUMB)
          value |= 1;
 
        if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL
@@ -8904,7 +8906,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        if (r_type == R_ARM_THM_MOVW_BREL && value >= 0x10000)
           return bfd_reloc_overflow;
 
-       if (sym_flags == STT_ARM_TFUNC)
+       if (branch_type == ST_BRANCH_TO_THUMB)
          value |= 1;
 
        if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL
@@ -9021,7 +9023,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
         /* If the target symbol is a Thumb function, then set the
            Thumb bit in the address.  */
-       if (sym_flags == STT_ARM_TFUNC)
+       if (branch_type == ST_BRANCH_TO_THUMB)
          signed_value |= 1;
 
         /* Calculate the value of the relevant G_n, in encoded
@@ -9676,8 +9678,8 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
        r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                                          input_section, contents, rel,
                                          relocation, info, sec, name,
-                                         (h ? ELF_ST_TYPE (h->type) :
-                                          ELF_ST_TYPE (sym->st_info)), h,
+                                         (h ? h->target_internal
+                                          : ARM_SYM_BRANCH_TYPE (sym)), h,
                                          &unresolved_reloc, &error_message);
 
       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
@@ -11955,8 +11957,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later,
      when we know the address of the .got section.  */
-  if (h->type == STT_FUNC || h->type == STT_ARM_TFUNC
-      || h->needs_plt)
+  if (h->type == STT_FUNC || h->needs_plt)
     {
       if (h->plt.refcount <= 0
          || SYMBOL_CALLS_LOCAL (info, h)
@@ -12130,8 +12131,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
              /* Make sure the function is not marked as Thumb, in case
                 it is the target of an ABS32 relocation, which will
                 point to the PLT entry.  */
-             if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
-               h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC);
+             h->target_internal = ST_BRANCH_TO_ARM;
            }
 
          /* Make room for this entry.  */
@@ -12285,7 +12285,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
   /* Allocate stubs for exported Thumb functions on v4t.  */
   if (!htab->use_blx && h->dynindx != -1
       && h->def_regular
-      && ELF_ST_TYPE (h->type) == STT_ARM_TFUNC
+      && h->target_internal == ST_BRANCH_TO_THUMB
       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
     {
       struct elf_link_hash_entry * th;
@@ -12303,12 +12303,14 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
                                        NULL, TRUE, FALSE, &bh);
 
       myh = (struct elf_link_hash_entry *) bh;
-      myh->type = ELF_ST_INFO (STB_LOCAL, STT_ARM_TFUNC);
+      myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
       myh->forced_local = 1;
+      myh->target_internal = ST_BRANCH_TO_THUMB;
       eh->export_glue = myh;
       th = record_arm_to_thumb_glue (info, h);
       /* Point the symbol at the stub.  */
       h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC);
+      h->target_internal = ST_BRANCH_TO_ARM;
       h->root.u.def.section = th->root.u.def.section;
       h->root.u.def.value = th->root.u.def.value & ~1;
     }
@@ -13298,8 +13300,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
 
                  eh = elf_link_hash_lookup (elf_hash_table (info), name,
                                             FALSE, FALSE, TRUE);
-                 if (eh != NULL
-                     && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC)
+                 if (eh != NULL && eh->target_internal == ST_BRANCH_TO_THUMB)
                    {
                      dyn.d_un.d_val |= 1;
                      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
@@ -13614,6 +13615,7 @@ elf32_arm_output_map_sym (output_arch_syminfo *osi,
   sym.st_other = 0;
   sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
   sym.st_shndx = osi->sec_shndx;
+  sym.st_target_internal = 0;
   elf32_arm_section_map_add (osi->sec, names[type][1], offset);
   return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
 }
@@ -13713,6 +13715,7 @@ elf32_arm_output_stub_sym (output_arch_syminfo *osi, const char *name,
   sym.st_other = 0;
   sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
   sym.st_shndx = osi->sec_shndx;
+  sym.st_target_internal = 0;
   return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
 }
 
@@ -14459,19 +14462,6 @@ elf32_arm_write_section (bfd *output_bfd,
   return FALSE;
 }
 
-/* Display STT_ARM_TFUNC symbols as functions.  */
-
-static void
-elf32_arm_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
-                            asymbol *asym)
-{
-  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
-
-  if (ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_ARM_TFUNC)
-    elfsym->symbol.flags |= BSF_FUNCTION;
-}
-
-
 /* Mangle thumb function symbols as we read them in.  */
 
 static bfd_boolean
@@ -14484,13 +14474,23 @@ elf32_arm_swap_symbol_in (bfd * abfd,
     return FALSE;
 
   /* New EABI objects mark thumb function symbols by setting the low bit of
-     the address.  Turn these into STT_ARM_TFUNC.  */
+     the address.  */
   if ((ELF_ST_TYPE (dst->st_info) == STT_FUNC)
       && (dst->st_value & 1))
     {
-      dst->st_info = ELF_ST_INFO (ELF_ST_BIND (dst->st_info), STT_ARM_TFUNC);
       dst->st_value &= ~(bfd_vma) 1;
+      dst->st_target_internal = ST_BRANCH_TO_THUMB;
+    }
+  else if (ELF_ST_TYPE (dst->st_info) == STT_ARM_TFUNC)
+    {
+      dst->st_info = ELF_ST_INFO (ELF_ST_BIND (dst->st_info), STT_FUNC);
+      dst->st_target_internal = ST_BRANCH_TO_THUMB;
     }
+  else if (ELF_ST_TYPE (dst->st_info) == STT_SECTION)
+    dst->st_target_internal = ST_BRANCH_LONG;
+  else
+    dst->st_target_internal = ST_BRANCH_TO_ARM;
+
   return TRUE;
 }
 
@@ -14509,7 +14509,7 @@ elf32_arm_swap_symbol_out (bfd *abfd,
      of the address set, as per the new EABI.  We do this unconditionally
      because objcopy does not set the elf header flags until after
      it writes out the symbol table.  */
-  if (ELF_ST_TYPE (src->st_info) == STT_ARM_TFUNC)
+  if (src->st_target_internal == ST_BRANCH_TO_THUMB)
     {
       newsym = *src;
       newsym.st_info = ELF_ST_INFO (ELF_ST_BIND (src->st_info), STT_FUNC);
@@ -14582,14 +14582,6 @@ elf32_arm_additional_program_headers (bfd *abfd,
     return 0;
 }
 
-/* We have two function types: STT_FUNC and STT_ARM_TFUNC.  */
-
-static bfd_boolean
-elf32_arm_is_function_type (unsigned int type)
-{
-  return (type == STT_FUNC) || (type == STT_ARM_TFUNC);
-}
-
 /* We use this to override swap_symbol_in and swap_symbol_out.  */
 const struct elf_size_info elf32_arm_size_info =
 {
@@ -14670,13 +14662,11 @@ const struct elf_size_info elf32_arm_size_info =
 #define elf_backend_section_from_shdr                  elf32_arm_section_from_shdr
 #define elf_backend_final_write_processing      elf32_arm_final_write_processing
 #define elf_backend_copy_indirect_symbol        elf32_arm_copy_indirect_symbol
-#define elf_backend_symbol_processing          elf32_arm_symbol_processing
 #define elf_backend_size_info                  elf32_arm_size_info
 #define elf_backend_modify_segment_map         elf32_arm_modify_segment_map
 #define elf_backend_additional_program_headers  elf32_arm_additional_program_headers
 #define elf_backend_output_arch_local_syms      elf32_arm_output_arch_local_syms
 #define elf_backend_begin_write_processing      elf32_arm_begin_write_processing
-#define elf_backend_is_function_type           elf32_arm_is_function_type
 
 #define elf_backend_can_refcount       1
 #define elf_backend_can_gc_sections    1
index a17a0fe8be28091f56033543915e37026cab21ea..a6174c2ea20ac327c37bed2b9f787f65dfa530d8 100644 (file)
@@ -962,6 +962,7 @@ i370_elf_finish_dynamic_sections (bfd *output_bfd,
       sym.st_name = 0;
       sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
       sym.st_other = 0;
+      sym.st_target_internal = 0;
 
       for (s = output_bfd->sections; s != NULL; s = s->next)
        {
index 25e3af9e0ff2c26aec210f0a65d2512e4f00bd43..0882d52b9a4e1df3f17dd2bfea27e2941599437a 100644 (file)
@@ -492,6 +492,7 @@ sh_symbian_relocate_section (bfd *                  output_bfd,
              new_sym.st_info  = ELF_ST_INFO (STB_GLOBAL, STT_FUNC);
              new_sym.st_other = ELF_ST_VISIBILITY (STV_DEFAULT);
              new_sym.st_shndx = SHN_UNDEF;
+             new_sym.st_target_internal = 0;
 
              if (! _bfd_elf_merge_symbol (input_bfd, info,
                                           ptr->new_name, & new_sym,
index 9f05b85fa576415af32044c3ea3dc50bb448d2bd..6bb23899e8edaf6d6a86afaea899a343304ec0c1 100644 (file)
@@ -591,6 +591,7 @@ elf64_sparc_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
        sym.st_other = 0;
        sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
        sym.st_shndx = app_regs [reg].shndx;
+       sym.st_target_internal = 0;
        if ((*func) (finfo, app_regs [reg].name, &sym,
                     sym.st_shndx == SHN_ABS
                     ? bfd_abs_section_ptr : bfd_und_section_ptr,
index 509d42626224e4c5bdb8be2b4c24d12d89a2d5d7..28b6b904e5fb1c88900d1acb97e97311ea2eab2a 100644 (file)
@@ -198,6 +198,7 @@ elf_swap_symbol_in (bfd *abfd,
     }
   else if (dst->st_shndx >= (SHN_LORESERVE & 0xffff))
     dst->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
+  dst->st_target_internal = 0;
   return TRUE;
 }
 
index 983d5e0ea67878355fd4b18cc5d62be73ae2cd9e..9ccc841da215d2394a2ed7740f8ee425d01c6d72 100644 (file)
@@ -4396,6 +4396,9 @@ error_free_dyn:
              dynsym = FALSE;
            }
 
+         if (definition)
+           h->target_internal = isym->st_target_internal;
+
          /* Check to see if we need to add an indirect symbol for
             the default name.  */
          if (definition || h->root.type == bfd_link_hash_common)
@@ -8729,6 +8732,7 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
     sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
   else
     sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type);
+  sym.st_target_internal = h->target_internal;
 
   switch (h->root.type)
     {
@@ -10520,6 +10524,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       elfsym.st_info = 0;
       elfsym.st_other = 0;
       elfsym.st_shndx = SHN_UNDEF;
+      elfsym.st_target_internal = 0;
       if (elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr,
                               NULL) != 1)
        goto error_return;
@@ -10537,6 +10542,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
       elfsym.st_other = 0;
       elfsym.st_value = 0;
+      elfsym.st_target_internal = 0;
       for (i = 1; i < elf_numsections (abfd); i++)
        {
          o = bfd_section_from_elf_index (abfd, i);
@@ -10787,6 +10793,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
          sym.st_name = 0;
          sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
          sym.st_other = 0;
+         sym.st_target_internal = 0;
 
          for (s = abfd->sections; s != NULL; s = s->next)
            {
@@ -12705,6 +12712,7 @@ _bfd_elf_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED,
   struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *)hsrc;
 
   ehdest->type = ehsrc->type;
+  ehdest->target_internal = ehsrc->target_internal;
 }
 
 /* Append a RELA relocation REL to section S in BFD.  */
index 33b6f136c2b01b7e071b73afc625c6552b5ec06c..f0f79070a368f65c1608ca4a23bdc2ca3e8a74f7 100644 (file)
@@ -2743,6 +2743,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
                entry->isym.st_info = ELF_ST_INFO (app_regs [reg].bind,
                                                   STT_REGISTER);
                entry->isym.st_shndx = app_regs [reg].shndx;
+               entry->isym.st_target_internal = 0;
                entry->next = NULL;
                entry->input_bfd = output_bfd;
                entry->input_indx = -1;
index 4cffafc3def532053a6127b9a2e1bf5257ceef0f..e40a8a2832295e73a3a31da0e1598e9e017b7fa0 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-14  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * config/tc-arm.c (arm_adjust_symtab): Set the branch type
+       for Thumb symbols.
+
 2011-03-11  Nick Clifton  <nickc@redhat.com>
 
        * remap.c (remap_debug_filename): Always allocate a buffer for the
index eed48f1b29c0e3b862b0b6a13dd6758e18bcbc2a..8a70c3763993a4fb88dc77c9957e05a22bada405 100644 (file)
@@ -22011,8 +22011,8 @@ arm_adjust_symtab (void)
              /* If it's a .thumb_func, declare it as so,
                 otherwise tag label as .code 16.  */
              if (THUMB_IS_FUNC (sym))
-               elf_sym->internal_elf_sym.st_info =
-                 ELF_ST_INFO (bind, STT_ARM_TFUNC);
+               elf_sym->internal_elf_sym.st_target_internal
+                 = ST_BRANCH_TO_THUMB;
              else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
                elf_sym->internal_elf_sym.st_info =
                  ELF_ST_INFO (bind, STT_ARM_16BIT);
index ee88a5c1078b79fc4508a50e39580814b62b01f9..8fd7c5ec289a820d4ffc96a335c297e3d1b34e3d 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-14  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * internal.h (elf_internal_sym): Add st_target_internal.
+       * arm.h (arm_st_branch_type): New enum.
+       (ARM_SYM_BRANCH_TYPE): New macro.
+
 2011-03-10  Nick Clifton  <nickc@redhat.com>
 
        * common.h (EM_V850): V850s now supplied by Renesas.
index 18aa5592e6aedaae01c2e516f839531bd8cdc3d0..e3df27f969b3ea56e83b21d11f3f07929489c350 100644 (file)
@@ -323,4 +323,13 @@ enum
 #define ELF_STRING_ARM_unwind_once      ".gnu.linkonce.armexidx."
 #define ELF_STRING_ARM_unwind_info_once ".gnu.linkonce.armextab."
 
+enum arm_st_branch_type {
+  ST_BRANCH_TO_ARM,
+  ST_BRANCH_TO_THUMB,
+  ST_BRANCH_LONG
+};
+
+#define ARM_SYM_BRANCH_TYPE(SYM) \
+  ((enum arm_st_branch_type) (SYM)->st_target_internal)
+
 #endif /* _ELF_ARM_H */
index c6e57218e0bfffc5d72220b2343b89cce7e1fa27..461503783040f252da0713129f8f5b3686d04fe6 100644 (file)
@@ -124,6 +124,7 @@ struct elf_internal_sym {
   unsigned long        st_name;                /* Symbol name, index in string tbl */
   unsigned char        st_info;                /* Type and binding attributes */
   unsigned char        st_other;               /* Visibilty, and target specific */
+  unsigned char st_target_internal;    /* Internal-only information */
   unsigned int  st_shndx;              /* Associated section index */
 };
 
index 7dd9abf292e90cc3925bbb8059771102d85c08a0..2441056bbf20ce5a4b51b722bf8d218e5e3eb0ea 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-14  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * emultempl/armelf.em (gld${EMULATION_NAME}_finish): Check
+       eh->target_internal.
+
 2011-03-14  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * emultempl/armelf.em (arm_elf_before_allocation): Check dynobj
index bfc57cac7b44280e938f813f224524e8b099e4e1..948bf8d7f93c1d81460d15e4a0fefca2e9081756 100644 (file)
@@ -404,7 +404,7 @@ gld${EMULATION_NAME}_finish (void)
       h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
                                FALSE, FALSE, TRUE);
       eh = (struct elf_link_hash_entry *)h;
-      if (!h || ELF_ST_TYPE(eh->type) != STT_ARM_TFUNC)
+      if (!h || eh->target_internal != ST_BRANCH_TO_THUMB)
        return;
     }
 
index ba013b25924f98498094dee6203f9bf67945f3f5..2a6f02f5238a6c00f59335faeb9f237db25a1f50 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-14  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * arm-dis.c (get_sym_code_type): Don't check for STT_ARM_TFUNC.
+       Use branch types instead.
+       (print_insn): Likewise.
+
 2011-02-28  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * mips-opc.c (mips_builtin_opcodes): Correct register use
index 91eba51da28ba6f6480fbb3a30b50b1bd2d67c36..26e40ab98b53c49580706f9aebce544337870f50 100644 (file)
@@ -4525,9 +4525,12 @@ get_sym_code_type (struct disassemble_info *info,
   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
 
   /* If the symbol has function type then use that.  */
-  if (type == STT_FUNC || type == STT_ARM_TFUNC)
+  if (type == STT_FUNC)
     {
-      *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
+      if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
+       *map_type = MAP_THUMB;
+      else
+       *map_type = MAP_ARM;
       return TRUE;
     }
 
@@ -4807,7 +4810,9 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
          es = *(elf_symbol_type **)(info->symbols);
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
 
-         is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
+         is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
+                      == ST_BRANCH_TO_THUMB)
+                     || type == STT_ARM_16BIT);
        }
     }