* gdb.arch/i386-sse.exp, gdb.arch/i386-sse.c: New tests.
[deliverable/binutils-gdb.git] / bfd / elf-m10300.c
index 8277bae301cb6d42b42ae2661c1fa23d1722a4ee..d61df4635703063828bdcbb3c1e56456bd9e5ec5 100644 (file)
@@ -616,7 +616,7 @@ _bfd_mn10300_elf_create_got_section (abfd, info)
       h->type = STT_OBJECT;
 
       if (info->shared
-         && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+         && ! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
     }
 
@@ -650,7 +650,7 @@ _bfd_mn10300_elf_create_got_section (abfd, info)
   h->type = STT_OBJECT;
 
   if (info->shared
-      && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+      && ! bfd_elf_link_record_dynamic_symbol (info, h))
     return FALSE;
 
   elf_hash_table (info)->hgot = h;
@@ -770,14 +770,14 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
        /* This relocation describes the C++ object vtable hierarchy.
           Reconstruct it for later use during GC.  */
        case R_MN10300_GNU_VTINHERIT:
-         if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+         if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
 
        /* This relocation describes which C++ vtable entries are actually
           used.  Record for later use during GC.  */
        case R_MN10300_GNU_VTENTRY:
-         if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
        case R_MN10300_GOT32:
@@ -822,7 +822,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs)
              /* Make sure this symbol is output as a dynamic symbol.  */
              if (h->dynindx == -1)
                {
-                 if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+                 if (! bfd_elf_link_record_dynamic_symbol (info, h))
                    return FALSE;
                }
 
@@ -1705,9 +1705,10 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 static bfd_boolean
 elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
      struct bfd_hash_entry *gen_entry;
-     PTR in_args ATTRIBUTE_UNUSED;
+     PTR in_args;
 {
   struct elf32_mn10300_link_hash_entry *entry;
+  struct bfd_link_info *link_info = (struct bfd_link_info *)in_args;
   unsigned int byte_count = 0;
 
   entry = (struct elf32_mn10300_link_hash_entry *) gen_entry;
@@ -1721,11 +1722,16 @@ elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
     return TRUE;
 
   /* If there are no named calls to this symbol, or there's nothing we
-     can move from the function itself into the "call" instruction, then
-     note that all "call" instructions should be converted into "calls"
-     instructions and return.  */
+     can move from the function itself into the "call" instruction,
+     then note that all "call" instructions should be converted into
+     "calls" instructions and return.  If a symbol is available for
+     dynamic symbol resolution (overridable or overriding), avoid
+     custom calling conventions.  */
   if (entry->direct_calls == 0
-      || (entry->stack_size == 0 && entry->movm_args == 0))
+      || (entry->stack_size == 0 && entry->movm_args == 0)
+      || (elf_hash_table (link_info)->dynamic_sections_created
+         && ELF_ST_VISIBILITY (entry->root.other) != STV_INTERNAL
+         && ELF_ST_VISIBILITY (entry->root.other) != STV_HIDDEN))
     {
       /* Make a note that we should convert "call" instructions to "calls"
         instructions for calls to this symbol.  */
@@ -2000,6 +2006,11 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                  sec_shndx = _bfd_elf_section_from_bfd_section (input_bfd,
                                                                 section);
 
+                 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+                             - symtab_hdr->sh_info);
+                 hashes = elf_sym_hashes (input_bfd);
+                 end_hashes = hashes + symcount;
+
                  /* Look at each function defined in this section and
                     update info for that function.  */
                  isymend = isymbuf + symtab_hdr->sh_info;
@@ -2010,6 +2021,22 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                        {
                          struct elf_link_hash_table *elftab;
                          bfd_size_type amt;
+                         struct elf_link_hash_entry **lhashes = hashes;
+
+                         /* Skip a local symbol if it aliases a
+                            global one.  */
+                         for (; lhashes < end_hashes; lhashes++)
+                           {
+                             hash = (struct elf32_mn10300_link_hash_entry *) *lhashes;
+                             if ((hash->root.root.type == bfd_link_hash_defined
+                                  || hash->root.root.type == bfd_link_hash_defweak)
+                                 && hash->root.root.u.def.section == section
+                                 && hash->root.type == STT_FUNC
+                                 && hash->root.root.u.def.value == isym->st_value)
+                               break;
+                           }
+                         if (lhashes != end_hashes)
+                           continue;
 
                          if (isym->st_shndx == SHN_UNDEF)
                            sym_sec = bfd_und_section_ptr;
@@ -2047,17 +2074,13 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
                        }
                    }
 
-                 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
-                             - symtab_hdr->sh_info);
-                 hashes = elf_sym_hashes (input_bfd);
-                 end_hashes = hashes + symcount;
                  for (; hashes < end_hashes; hashes++)
                    {
                      hash = (struct elf32_mn10300_link_hash_entry *) *hashes;
                      if ((hash->root.root.type == bfd_link_hash_defined
                           || hash->root.root.type == bfd_link_hash_defweak)
                          && hash->root.root.u.def.section == section
-                         && ELF_ST_TYPE (isym->st_info) == STT_FUNC)
+                         && hash->root.type == STT_FUNC)
                        compute_function_info (input_bfd, hash,
                                               (hash)->root.root.u.def.value,
                                               contents);
@@ -2104,10 +2127,10 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
         the final initialization steps on each.  */
       elf32_mn10300_link_hash_traverse (hash_table,
                                        elf32_mn10300_finish_hash_table_entry,
-                                       NULL);
+                                       link_info);
       elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
                                        elf32_mn10300_finish_hash_table_entry,
-                                       NULL);
+                                       link_info);
 
       /* All entries in the hash table are fully initialized.  */
       hash_table->flags |= MN10300_HASH_ENTRIES_INITIALIZED;
@@ -2439,6 +2462,7 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          asection *sym_sec = NULL;
          const char *sym_name;
          char *new_name;
+         bfd_vma saved_addend;
 
          /* A local symbol.  */
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
@@ -2451,13 +2475,25 @@ mn10300_elf_relax_section (abfd, sec, link_info, again)
          else
            sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
 
-         symval = (isym->st_value
-                   + sym_sec->output_section->vma
-                   + sym_sec->output_offset);
          sym_name = bfd_elf_string_from_elf_section (abfd,
                                                      symtab_hdr->sh_link,
                                                      isym->st_name);
 
+         if ((sym_sec->flags & SEC_MERGE)
+             && ELF_ST_TYPE (isym->st_info) == STT_SECTION
+             && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
+           {
+             saved_addend = irel->r_addend;
+             symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
+             symval += irel->r_addend;
+             irel->r_addend = saved_addend;
+           }
+         else
+           {
+             symval = (isym->st_value
+                       + sym_sec->output_section->vma
+                       + sym_sec->output_offset);
+           }
          /* Tack on an ID so we can uniquely identify this
             local symbol in the global hash table.  */
          new_name = bfd_malloc ((bfd_size_type) strlen (sym_name) + 10);
@@ -4186,7 +4222,7 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (info, h)
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (h->dynindx == -1)
        {
-         if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
 
This page took 0.026634 seconds and 4 git commands to generate.