/bfd/ChangeLog
[deliverable/binutils-gdb.git] / bfd / elf64-sh64.c
index e0bc8df7e5d0fd9e3f1e6e01ca9808ac18c4fb34..ad6ca1c503773a46435631c5a7a75c5176d5eba6 100644 (file)
@@ -1,5 +1,5 @@
 /* SuperH SH64-specific support for 64-bit ELF
-   Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -141,11 +141,11 @@ static bfd_boolean sh_elf64_check_relocs
 static int sh64_elf64_get_symbol_type
   (Elf_Internal_Sym *, int);
 static bfd_boolean sh64_elf64_add_symbol_hook
-  (bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **,
+  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
    flagword *, asection **, bfd_vma *);
 static bfd_boolean sh64_elf64_link_output_symbol_hook
-  (bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
-   asection *);
+  (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
+   struct elf_link_hash_entry *);
 static bfd_boolean sh64_elf64_fake_sections
   (bfd *, Elf_Internal_Shdr *, asection *);
 static void sh64_elf64_final_write_processing
@@ -1532,8 +1532,10 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
              && r_type <= (int) R_SH_LAST_INVALID_RELOC)
          || (r_type >= (int) R_SH_DIR8WPN
-             && r_type <= (int) R_SH_LAST_INVALID_RELOC_2)
-         || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_3
+             && r_type <= (int) R_SH_LAST_INVALID_RELOC)
+         || (r_type >= (int) R_SH_GNU_VTINHERIT
+             && r_type <= (int) R_SH_PSHL)
+         || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
              && r_type <= R_SH_GOTPLT32)
          || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
              && r_type <= (int) R_SH_LAST_INVALID_RELOC_4))
@@ -1580,7 +1582,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
            }
          else if (! howto->partial_inplace)
            {
-             relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+             relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
              relocation |= ((sym->st_other & STO_SH5_ISA32) != 0);
            }
          else if ((sec->flags & SEC_MERGE)
@@ -1701,15 +1703,16 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
            }
          else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
-         else if (info->shared
-                  && !info->symbolic
-                  && info->unresolved_syms_in_objects == RM_IGNORE)
+         else if (info->unresolved_syms_in_objects == RM_IGNORE
+                  && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
            relocation = 0;
          else
            {
              if (! ((*info->callbacks->undefined_symbol)
                     (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset, TRUE)))
+                     input_section, rel->r_offset,
+                     (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+                      || ELF_ST_VISIBILITY (h->other)))))
                return FALSE;
              relocation = 0;
            }
@@ -2559,14 +2562,14 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
         case R_SH_GNU_VTINHERIT:
-          if (!_bfd_elf64_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_SH_GNU_VTENTRY:
-          if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
             return FALSE;
           break;
 
@@ -2631,7 +2634,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
              /* Make sure this symbol is output as a dynamic symbol.  */
              if (h->dynindx == -1)
                {
-                 if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+                 if (! bfd_elf_link_record_dynamic_symbol (info, h))
                    return FALSE;
                }
 
@@ -2714,7 +2717,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
          /* Make sure this symbol is output as a dynamic symbol.  */
          if (h->dynindx == -1)
            {
-             if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+             if (! bfd_elf_link_record_dynamic_symbol (info, h))
                return FALSE;
            }
 
@@ -2884,13 +2887,13 @@ sh64_elf64_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
 
 static bfd_boolean
 sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
-                           const Elf_Internal_Sym *sym, const char **namep,
+                           Elf_Internal_Sym *sym, const char **namep,
                            flagword *flagsp ATTRIBUTE_UNUSED,
                            asection **secp, bfd_vma *valp)
 {
   /* We want to do this for relocatable as well as final linking.  */
   if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
-      && info->hash->creator->flavour == bfd_target_elf_flavour)
+      && is_elf_hash_table (info->hash))
     {
       struct elf_link_hash_entry *h;
 
@@ -2980,11 +2983,11 @@ sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
    DataLabel symbol.  */
 
 static bfd_boolean
-sh64_elf64_link_output_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED,
-                                   struct bfd_link_info *info,
+sh64_elf64_link_output_symbol_hook (struct bfd_link_info *info,
                                    const char *cname,
                                    Elf_Internal_Sym *sym,
-                                   asection *input_sec ATTRIBUTE_UNUSED)
+                                   asection *input_sec ATTRIBUTE_UNUSED,
+                                   struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
 {
   char *name = (char *) cname;
 
@@ -3296,7 +3299,7 @@ sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *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;
     }
 
@@ -3422,7 +3425,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (h->dynindx == -1)
        {
-         if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
 
@@ -3725,31 +3728,31 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
         dynamic linker and used by the debugger.  */
       if (info->executable)
        {
-         if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
            return FALSE;
        }
 
       if (plt)
        {
-         if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+             || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
            return FALSE;
        }
 
       if (relocs)
        {
-         if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
-                                               sizeof (Elf64_External_Rela)))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+                                             sizeof (Elf64_External_Rela)))
            return FALSE;
        }
 
       if (reltext)
        {
-         if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
            return FALSE;
        }
     }
@@ -4116,12 +4119,31 @@ sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
   return TRUE;
 }
 
+/* Merge non visibility st_other attribute when the symbol comes from
+   a dynamic object.  */
+static void
+sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h,
+                                  const Elf_Internal_Sym *isym,
+                                  bfd_boolean definition,
+                                  bfd_boolean dynamic)
+{
+  if (isym->st_other != 0 && dynamic)
+    {
+      unsigned char other;
+
+      /* Take the balance of OTHER from the definition.  */
+      other = (definition ? isym->st_other : h->other);
+      other &= ~ ELF_ST_VISIBILITY (-1);
+      h->other = other | ELF_ST_VISIBILITY (h->other);
+    }
+
+  return;
+}
+
 static struct bfd_elf_special_section const sh64_elf64_special_sections[]=
 {
-  { ".cranges",                0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { NULL,              0,      NULL,   0,
-    0,                 0 }
+  { ".cranges", 8, 0, SHT_PROGBITS, 0 },
+  { NULL,       0, 0, 0,            0 }
 };
 
 #define TARGET_BIG_SYM         bfd_elf64_sh64_vec
@@ -4164,6 +4186,9 @@ static struct bfd_elf_special_section const sh64_elf64_special_sections[]=
 #define elf_backend_link_output_symbol_hook \
        sh64_elf64_link_output_symbol_hook
 
+#define        elf_backend_merge_symbol_attribute \
+       sh64_elf64_merge_symbol_attribute
+
 #define elf_backend_final_write_processing \
        sh64_elf64_final_write_processing
 
@@ -4185,7 +4210,6 @@ static struct bfd_elf_special_section const sh64_elf64_special_sections[]=
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    24
-#define elf_backend_plt_header_size    PLT_ENTRY_SIZE
 
 #include "elf64-target.h"
 
This page took 0.026854 seconds and 4 git commands to generate.