* elf32-arm.c (STUB_ENTRY_NAME): Define.
[deliverable/binutils-gdb.git] / bfd / elf32-arm.c
index 2f10f0284b575837f90fb3e8c66f7c7da8021141..bb0dd427af14f13d6698ff8b3518e32b0eb31873 100644 (file)
@@ -1898,6 +1898,8 @@ typedef unsigned short int insn16;
 #define ARM_BX_GLUE_SECTION_NAME ".v4_bx"
 #define ARM_BX_GLUE_ENTRY_NAME   "__bx_r%d"
 
+#define STUB_ENTRY_NAME   "__%s_veneer"
+
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
 #define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"
@@ -2024,8 +2026,8 @@ static const bfd_vma arm_thumb_thumb_long_branch_stub[] =
   {
     0x4e02b540,         /* push {r6, lr} */
                         /* ldr  r6, [pc, #8] */
-    0xe7fe46fe,         /* mov  lr, pc */
-                        /* b.n  r6 */
+    0x473046fe,         /* mov  lr, pc */
+                        /* b  r6 */
     0xbf00bd40,         /* pop  {r6, pc} */
                         /* nop */
     0x00000000,         /* dcd  R_ARM_ABS32(X) */
@@ -2046,7 +2048,7 @@ static const bfd_vma arm_pic_long_branch_stub[] =
   {
     0xe59fc000,         /* ldr   r12, [pc] */
     0xe08ff00c,         /* add   pc, pc, ip */
-    0x00000000,         /* dcd   R_ARM_ABS32(X) */
+    0x00000000,         /* dcd   R_ARM_REL32(X) */
   };
 
 /* Section name for stubs is the associated section name plus this
@@ -2090,6 +2092,11 @@ struct elf32_arm_stub_hash_entry
   /* Where this stub is being called from, or, in the case of combined
      stub sections, the first input section in the group.  */
   asection *id_sec;
+
+  /* The name for the local symbol at the start of this stub.  The
+     stub name in the hash table has to be unique; this does not, so
+     it can be friendlier.  */
+  char *output_name;
 };
 
 /* Used to build a map of a section.  This is required for mixed-endian
@@ -2233,9 +2240,9 @@ struct elf32_arm_link_hash_entry
        symbols with Arm stubs.  */
     struct elf_link_hash_entry *export_glue;
 
-  /* A pointer to the most recently used stub hash entry against this
+   /* A pointer to the most recently used stub hash entry against this
      symbol. */
-  struct elf32_arm_stub_hash_entry *stub_cache;
+    struct elf32_arm_stub_hash_entry *stub_cache;
   };
 
 /* Traverse an arm ELF linker hash table.  */
@@ -2713,6 +2720,23 @@ using_thumb2 (struct elf32_arm_link_hash_table *globals)
   return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
 }
 
+static bfd_boolean
+arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
+{
+  switch (stub_type)
+    {
+    case arm_thumb_thumb_stub_long_branch:
+    case arm_thumb_arm_v4t_stub_long_branch:
+      return TRUE;
+    case arm_stub_none:
+      BFD_FAIL ();
+      return FALSE;
+      break;
+    default:
+      return FALSE;
+    }
+}
+
 /* Determine the type of stub needed, if any, for a call.  */
 
 static enum elf32_arm_stub_type
@@ -2731,6 +2755,11 @@ arm_type_of_stub (struct bfd_link_info *info,
   int thumb_only;
   enum elf32_arm_stub_type stub_type = arm_stub_none;
 
+  /* We don't know the actual type of destination in case it is of
+     type STT_SECTION: give up */
+  if (st_type == STT_SECTION)
+    return stub_type;
+
   globals = elf32_arm_hash_table (info);
 
   thumb_only = using_thumb_only (globals);
@@ -2915,33 +2944,13 @@ elf32_arm_get_stub_entry (const asection *input_section,
   return stub_entry;
 }
 
-static void elf32_arm_stub_add_mapping_symbol (struct bfd_link_info * link_info,
-                                              asection *stub_sec,
-                                              char* name,
-                                              bfd_vma val)
-{
-  struct bfd_link_hash_entry * bh = NULL;
-  struct elf_link_hash_entry * myh;
-
-  _bfd_generic_link_add_one_symbol (link_info,
-                                   stub_sec->owner, name,
-                                   BSF_LOCAL, stub_sec, stub_sec->size + val,
-                                   NULL, TRUE, FALSE, &bh);
-
-  myh = (struct elf_link_hash_entry *) bh;
-  myh->type = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
-  myh->forced_local = 1;
-}
-
 /* Add a new stub entry to the stub hash.  Not all fields of the new
    stub entry are initialised.  */
 
 static struct elf32_arm_stub_hash_entry *
 elf32_arm_add_stub (const char *stub_name,
                    asection *section,
-                   struct elf32_arm_link_hash_table *htab,
-                   struct bfd_link_info * link_info,
-                   enum elf32_arm_stub_type stub_type)
+                   struct elf32_arm_link_hash_table *htab)
 {
   asection *link_sec;
   asection *stub_sec;
@@ -2989,33 +2998,6 @@ elf32_arm_add_stub (const char *stub_name,
   stub_entry->stub_offset = 0;
   stub_entry->id_sec = link_sec;
 
-  switch (stub_type)
-    {
-    case arm_stub_long_branch:
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$a", 0);
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$d", 4);
-      break;
-    case arm_thumb_v4t_stub_long_branch:
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$a", 0);
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$d", 8);
-      break;
-    case arm_thumb_thumb_stub_long_branch:
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$t", 0);
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$d", 12);
-      break;
-    case arm_thumb_arm_v4t_stub_long_branch:
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$t", 0);
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$a", 8);
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$d", 16);
-      break;
-    case arm_stub_pic_long_branch:
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$a", 0);
-      elf32_arm_stub_add_mapping_symbol (link_info, stub_sec, "$d", 8);
-      break;
-    default:
-      BFD_FAIL ();
-  }
-
   return stub_entry;
 }
 
@@ -3136,32 +3118,30 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
     {
     case arm_stub_long_branch:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents + 4,
-                               stub_entry->stub_offset, sym_value, 0);
+                               stub_bfd, stub_sec, stub_sec->contents,
+                               stub_entry->stub_offset + 4, sym_value, 0);
       break;
     case arm_thumb_v4t_stub_long_branch:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents + 8,
-                               stub_entry->stub_offset, sym_value, 0);
+                               stub_bfd, stub_sec, stub_sec->contents,
+                               stub_entry->stub_offset + 8, sym_value, 0);
       break;
     case arm_thumb_thumb_stub_long_branch:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents + 12,
-                               stub_entry->stub_offset, sym_value, 0);
+                               stub_bfd, stub_sec, stub_sec->contents,
+                               stub_entry->stub_offset + 12, sym_value, 0);
       break;
     case arm_thumb_arm_v4t_stub_long_branch:
       _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents + 20,
-                               stub_entry->stub_offset, sym_value, 0);
+                               stub_bfd, stub_sec, stub_sec->contents,
+                               stub_entry->stub_offset + 16, sym_value, 0);
       break;
     case arm_stub_pic_long_branch:
       /* We want the value relative to the address 8 bytes from the
         start of the stub.  */
-      sym_value -= stub_addr + 8;
-
-      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_ABS32),
-                               stub_bfd, stub_sec, stub_sec->contents + 8,
-                               stub_entry->stub_offset, sym_value, 0);
+      _bfd_final_link_relocate (elf32_arm_howto_from_type (R_ARM_REL32),
+                               stub_bfd, stub_sec, stub_sec->contents,
+                               stub_entry->stub_offset + 8, sym_value, 0);
       break;
     default:
       break;
@@ -3509,6 +3489,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                  bfd_vma sym_value;
                  bfd_vma destination;
                  struct elf32_arm_link_hash_entry *hash;
+                 const char *sym_name;
                  char *stub_name;
                  const asection *id_sec;
                  unsigned char st_type;
@@ -3536,6 +3517,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                  sym_value = 0;
                  destination = 0;
                  hash = NULL;
+                 sym_name = NULL;
                  if (r_indx < symtab_hdr->sh_info)
                    {
                      /* It's a local symbol.  */
@@ -3564,6 +3546,10 @@ elf32_arm_size_stubs (bfd *output_bfd,
                                     + sym_sec->output_offset
                                     + sym_sec->output_section->vma);
                      st_type = ELF_ST_TYPE (sym->st_info);
+                     sym_name
+                       = bfd_elf_string_from_elf_section (input_bfd,
+                                                          symtab_hdr->sh_link,
+                                                          sym->st_name);
                    }
                  else
                    {
@@ -3601,6 +3587,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                          goto error_ret_free_internal;
                        }
                      st_type = ELF_ST_TYPE (hash->root.type);
+                     sym_name = hash->root.root.root.string;
                    }
 
                  /* Determine what (if any) linker stub is needed.  */
@@ -3627,7 +3614,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                      continue;
                    }
 
-                 stub_entry = elf32_arm_add_stub (stub_name, section, htab, info, stub_type);
+                 stub_entry = elf32_arm_add_stub (stub_name, section, htab);
                  if (stub_entry == NULL)
                    {
                      free (stub_name);
@@ -3639,6 +3626,33 @@ elf32_arm_size_stubs (bfd *output_bfd,
                  stub_entry->stub_type = stub_type;
                  stub_entry->h = hash;
                  stub_entry->st_type = st_type;
+
+                 if (sym_name == NULL)
+                   sym_name = "unnamed";
+                 stub_entry->output_name
+                   = bfd_alloc (htab->stub_bfd,
+                                sizeof (THUMB2ARM_GLUE_ENTRY_NAME)
+                                + strlen (sym_name));
+                 if (stub_entry->output_name == NULL)
+                   {
+                     free (stub_name);
+                     goto error_ret_free_internal;
+                   }
+
+                 /* 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
+                     && st_type != STT_ARM_TFUNC)
+                   sprintf (stub_entry->output_name, THUMB2ARM_GLUE_ENTRY_NAME,
+                            sym_name);
+                 else if (r_type == (unsigned int) R_ARM_CALL
+                          && st_type == STT_ARM_TFUNC)
+                   sprintf (stub_entry->output_name, ARM2THUMB_GLUE_ENTRY_NAME,
+                            sym_name);
+                 else
+                   sprintf (stub_entry->output_name, STUB_ENTRY_NAME,
+                            sym_name);
+
                  stub_changed = TRUE;
                }
 
@@ -6413,7 +6427,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                    /* Convert BL to BLX.  */
                    lower_insn = (lower_insn & ~0x1000) | 0x0800;
                  }
-               else if (elf32_thumb_to_arm_stub
+               else if (r_type != R_ARM_THM_CALL) {
+                 if (elf32_thumb_to_arm_stub
                    (info, sym_name, input_bfd, output_bfd, input_section,
                     hit_data, sym_sec, rel->r_offset, signed_addend, value,
                     error_message))
@@ -6421,6 +6436,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                else
                  return bfd_reloc_dangerous;
              }
+             }
            else if (sym_flags == STT_ARM_TFUNC && globals->use_blx
                     && r_type == R_ARM_THM_CALL)
              {
@@ -6466,7 +6482,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                ||
                (thumb2
                 && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
-                    || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET))))
+                    || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
+               || ((sym_flags != STT_ARM_TFUNC) && !globals->use_blx))
              {
                /* The target is out of reach or we are changing modes, so
                   redirect the branch to the local stub for this
@@ -6479,8 +6496,14 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                           + stub_entry->stub_sec->output_offset
                           + stub_entry->stub_sec->output_section->vma);
 
-               /* This call becomes a call to Arm for sure. Force BLX.  */
-               lower_insn = (lower_insn & ~0x1000) | 0x0800;
+               /* If this call becomes a call to Arm, force BLX.  */
+               if (globals->use_blx)
+                 {
+                   if ((stub_entry
+                        && !arm_stub_is_thumb (stub_entry->stub_type))
+                       || (sym_flags != STT_ARM_TFUNC))
+                     lower_insn = (lower_insn & ~0x1000) | 0x0800;
+                 }
              }
          }
 
@@ -8418,6 +8441,18 @@ elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
   in_flags  = elf_elfheader (ibfd)->e_flags;
   out_flags = elf_elfheader (obfd)->e_flags;
 
+  /* In theory there is no reason why we couldn't handle this.  However
+     in practice it isn't even close to working and there is no real
+     reason to want it.  */
+  if (EF_ARM_EABI_VERSION (in_flags) >= EF_ARM_EABI_VER4
+      && !(ibfd->flags & DYNAMIC)
+      && (in_flags & EF_ARM_BE8))
+    {
+      _bfd_error_handler (_("ERROR: %B is already in final BE8 format"), 
+                         ibfd);
+      return FALSE;
+    }
+
   if (!elf_flags_init (obfd))
     {
       /* If the input is the default architecture and had the default
@@ -11034,12 +11069,12 @@ enum map_symbol_type
 };
 
 
-/* Output a single PLT mapping symbol.  */
+/* Output a single mapping symbol.  */
 
 static bfd_boolean
-elf32_arm_ouput_plt_map_sym (output_arch_syminfo *osi,
-                            enum map_symbol_type type,
-                            bfd_vma offset)
+elf32_arm_output_map_sym (output_arch_syminfo *osi,
+                         enum map_symbol_type type,
+                         bfd_vma offset)
 {
   static const char *names[3] = {"$a", "$t", "$d"};
   struct elf32_arm_link_hash_table *htab;
@@ -11087,20 +11122,20 @@ elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf)
   addr = h->plt.offset;
   if (htab->symbian_p)
     {
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
        return FALSE;
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 4))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 4))
        return FALSE;
     }
   else if (htab->vxworks_p)
     {
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
        return FALSE;
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 8))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
        return FALSE;
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr + 12))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 12))
        return FALSE;
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 20))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 20))
        return FALSE;
     }
   else
@@ -11113,13 +11148,13 @@ elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf)
 
       if (thumb_refs > 0)
        {
-         if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_THUMB, addr - 4))
+         if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4))
            return FALSE;
        }
 #ifdef FOUR_WORD_PLT
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
        return FALSE;
-      if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_DATA, addr + 12))
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
        return FALSE;
 #else
       /* A three-word PLT with no Thumb thunk contains only Arm code,
@@ -11127,7 +11162,7 @@ elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf)
         entries with thumb thunks.  */
       if (thumb_refs > 0 || addr == 20)
        {
-         if (!elf32_arm_ouput_plt_map_sym (osi, ARM_MAP_ARM, addr))
+         if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
            return FALSE;
        }
 #endif
@@ -11136,6 +11171,106 @@ elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf)
   return TRUE;
 }
 
+/* Output a single local symbol for a generated stub.  */
+
+static bfd_boolean
+elf32_arm_output_stub_sym (output_arch_syminfo *osi, const char *name,
+                          bfd_vma offset, bfd_vma size)
+{
+  struct elf32_arm_link_hash_table *htab;
+  Elf_Internal_Sym sym;
+
+  htab = elf32_arm_hash_table (osi->info);
+  sym.st_value = osi->sec->output_section->vma
+                + osi->sec->output_offset
+                + offset;
+  sym.st_size = size;
+  sym.st_other = 0;
+  sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+  sym.st_shndx = osi->sec_shndx;
+  if (!osi->func (osi->finfo, name, &sym, osi->sec, NULL))
+    return FALSE;
+  return TRUE;
+}
+
+static bfd_boolean
+arm_map_one_stub (struct bfd_hash_entry *gen_entry,
+                 PTR in_arg)
+{
+  struct elf32_arm_stub_hash_entry *stub_entry;
+  struct bfd_link_info *info;
+  struct elf32_arm_link_hash_table *htab;
+  asection *stub_sec;
+  bfd_vma addr;
+  char *stub_name;
+
+  /* Massage our args to the form they really have.  */
+  stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+
+  output_arch_syminfo *osi = (output_arch_syminfo *) in_arg;
+  info = osi->info;
+
+  htab = elf32_arm_hash_table (info);
+  stub_sec = stub_entry->stub_sec;
+
+  /* Ensure this stub is attached to the current section being
+     processed.  */
+  if (stub_sec != osi->sec)
+    return TRUE;
+
+  addr = (bfd_vma) stub_entry->stub_offset;
+  stub_name = stub_entry->output_name;
+
+  switch (stub_entry->stub_type)
+    {
+    case arm_stub_long_branch:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 8))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 4))
+       return FALSE;
+      break;
+    case arm_thumb_v4t_stub_long_branch:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 12))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
+       return FALSE;
+      break;
+    case arm_thumb_thumb_stub_long_branch:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr + 1, 16))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
+       return FALSE;
+      break;
+    case arm_thumb_arm_v4t_stub_long_branch:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr + 1, 20))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 8))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
+       return FALSE;
+      break;
+    case arm_stub_pic_long_branch:
+      if (!elf32_arm_output_stub_sym (osi, stub_name, addr, 12))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+       return FALSE;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
+       return FALSE;
+      break;
+    default:
+      BFD_FAIL ();
+    }
+
+  return TRUE;
+}
 
 /* Output mapping symbols for linker generated sections.  */
 
@@ -11178,8 +11313,8 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
 
       for (offset = 0; offset < htab->arm_glue_size; offset += size)
        {
-         elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, offset);
-         elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_DATA, offset + size - 4);
+         elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset);
+         elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, offset + size - 4);
        }
     }
 
@@ -11195,8 +11330,8 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
 
       for (offset = 0; offset < htab->thumb_glue_size; offset += size)
        {
-         elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_THUMB, offset);
-         elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, offset + 4);
+         elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, offset);
+         elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset + 4);
        }
     }
 
@@ -11209,9 +11344,29 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
       osi.sec_shndx = _bfd_elf_section_from_bfd_section
          (output_bfd, osi.sec->output_section);
 
-      elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0);
+      elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0);
     }
 
+  /* Long calls stubs. */
+  if (htab->stub_bfd && htab->stub_bfd->sections) {
+      asection* stub_sec;
+      for (stub_sec = htab->stub_bfd->sections;
+          stub_sec != NULL;
+          stub_sec = stub_sec->next) {
+
+       /* Ignore non-stub sections */
+       if (!strstr(stub_sec->name, STUB_SUFFIX))
+         continue;
+
+       osi.sec = stub_sec;
+
+       osi.sec_shndx = _bfd_elf_section_from_bfd_section
+         (output_bfd, osi.sec->output_section);
+
+       bfd_hash_traverse (&htab->stub_hash_table, arm_map_one_stub, &osi);
+      }
+  }
+
   /* Finally, output mapping symbols for the PLT.  */
   if (!htab->splt || htab->splt->size == 0)
     return TRUE;
@@ -11226,18 +11381,18 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
       /* VxWorks shared libraries have no PLT header.  */
       if (!info->shared)
        {
-         if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0))
+         if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
            return FALSE;
-         if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_DATA, 12))
+         if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12))
            return FALSE;
        }
     }
   else if (!htab->symbian_p)
     {
-      if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0))
+      if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
        return FALSE;
 #ifndef FOUR_WORD_PLT
-      if (!elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_DATA, 16))
+      if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 16))
        return FALSE;
 #endif
     }
This page took 0.033019 seconds and 4 git commands to generate.