* elflink.h (elf_gc_mark): Pass in the section whose relocs we are
[deliverable/binutils-gdb.git] / bfd / elf64-sh64.c
index 143a560fb40e9b089bb0716afb1f3364c6a9ba91..1e5e12b19374cfde9fa84015fb901ac671facef9 100644 (file)
@@ -84,7 +84,7 @@ struct elf_sh64_link_hash_entry
   bfd_vma datalabel_got_offset;
 
   /* Number of PC relative relocs copied for this symbol.  */
-  struct elf_sh_pcrel_relocs_copied *pcrel_relocs_copied;
+  struct elf_sh64_pcrel_relocs_copied *pcrel_relocs_copied;
 };
 
 /* sh ELF linker hash table.  */
@@ -127,7 +127,7 @@ static bfd_byte *sh_elf64_get_relocated_section_contents
 static boolean sh_elf64_set_mach_from_flags PARAMS ((bfd *));
 static boolean sh_elf64_set_private_flags PARAMS ((bfd *, flagword));
 static asection *sh_elf64_gc_mark_hook
-  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
           struct elf_link_hash_entry *, Elf_Internal_Sym *));
 static boolean sh_elf64_gc_sweep_hook
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -139,12 +139,31 @@ static int sh64_elf64_get_symbol_type PARAMS ((Elf_Internal_Sym *, int));
 static boolean sh64_elf64_add_symbol_hook
   PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
           const char **, flagword *, asection **, bfd_vma *));
-extern boolean sh64_elf64_link_output_symbol_hook
+static boolean sh64_elf64_link_output_symbol_hook
   PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
           asection *));
 static boolean sh64_elf64_fake_sections
   PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
 static void sh64_elf64_final_write_processing PARAMS ((bfd *, boolean));
+static struct bfd_hash_entry *sh64_elf64_link_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *sh64_elf64_link_hash_table_create
+  PARAMS ((bfd *));
+inline static void movi_shori_putval PARAMS ((bfd *, unsigned long, char *));
+inline static void movi_3shori_putval PARAMS ((bfd *, bfd_vma, char *));
+static boolean sh64_elf64_create_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
+static boolean sh64_elf64_adjust_dynamic_symbol
+  PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *));
+static boolean sh64_elf64_discard_copies
+  PARAMS ((struct elf_sh64_link_hash_entry *, PTR));
+static boolean sh64_elf64_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
+static boolean sh64_elf64_finish_dynamic_symbol
+  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+          Elf_Internal_Sym *));
+static boolean sh64_elf64_finish_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
 
 static reloc_howto_type sh_elf64_howto_table[] = {
   /* No relocation.  */
@@ -1323,8 +1342,8 @@ sh_elf64_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
     return bfd_reloc_undefined;
 
   if (bfd_is_com_section (symbol_in->section))
-    sym_value = 0;                           
-  else 
+    sym_value = 0;
+  else
     sym_value = (symbol_in->value +
                 symbol_in->section->output_section->vma +
                 symbol_in->section->output_offset);
@@ -1595,7 +1614,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
              sec = h->root.u.def.section;
              /* In these cases, we don't need the relocation value.
                 We check specially because in some obscure cases
-                sec->output_section will be NULL. */
+                sec->output_section will be NULL.  */
              if (r_type == R_SH_GOTPC_LOW16
                  || r_type == R_SH_GOTPC_MEDLOW16
                  || r_type == R_SH_GOTPC_MEDHI16
@@ -1727,28 +1746,25 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                }
 
              skip = false;
+             relocate = false;
 
              outrel.r_offset
-               = _bfd_elf_section_offset (output_bfd,
-                                          &elf_hash_table (info)->stab_info,
-                                          input_section,
-                                          rel->r_offset);
+               = _bfd_elf_section_offset (output_bfd, info,
+                                          input_section, rel->r_offset);
 
              if (outrel.r_offset == (bfd_vma) -1)
                skip = true;
-             
+             else if (outrel.r_offset == (bfd_vma) -2)
+               skip = true, relocate = true;
+
              outrel.r_offset += (input_section->output_section->vma
                                  + input_section->output_offset);
 
              if (skip)
-               {
-                 memset (&outrel, 0, sizeof outrel);
-                 relocate = false;
-               }
+               memset (&outrel, 0, sizeof outrel);
              else if (r_type == R_SH_64_PCREL)
                {
                  BFD_ASSERT (h != NULL && h->dynindx != -1);
-                 relocate = false;
                  outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64_PCREL);
                  outrel.r_addend = rel->r_addend;
                }
@@ -1768,7 +1784,6 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                  else
                    {
                      BFD_ASSERT (h->dynindx != -1);
-                     relocate = false;
                      outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64);
                      outrel.r_addend = relocation + rel->r_addend;
                    }
@@ -2219,7 +2234,8 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
        {
          asection *isec;
 
-         bfd_elf64_swap_symbol_in (input_bfd, esym, shndx, isymp);
+         bfd_elf64_swap_symbol_in (input_bfd, (const PTR) esym,
+                                   (const PTR) shndx, isymp);
 
          if (isymp->st_shndx == SHN_UNDEF)
            isec = bfd_und_section_ptr;
@@ -2375,7 +2391,7 @@ sh_elf64_merge_private_data (ibfd, obfd)
 {
   flagword old_flags, new_flags;
 
-  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
     return false;
 
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
@@ -2434,12 +2450,12 @@ sh_elf64_merge_private_data (ibfd, obfd)
    relocation.  */
 
 static asection *
-sh_elf64_gc_mark_hook (abfd, info, rel, h, sym)
-       bfd *abfd;
-       struct bfd_link_info *info ATTRIBUTE_UNUSED;
-       Elf_Internal_Rela *rel;
-       struct elf_link_hash_entry *h;
-       Elf_Internal_Sym *sym;
+sh_elf64_gc_mark_hook (sec, info, rel, h, sym)
+     asection *sec;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
+     Elf_Internal_Rela *rel;
+     struct elf_link_hash_entry *h;
+     Elf_Internal_Sym *sym;
 {
   if (h != NULL)
     {
@@ -2465,13 +2481,7 @@ sh_elf64_gc_mark_hook (abfd, info, rel, h, sym)
        }
     }
   else
-    {
-      if (!(elf_bad_symtab (abfd)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-               && sym->st_shndx != SHN_COMMON))
-       return bfd_section_from_elf_index (abfd, sym->st_shndx);
-    }
+    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
 
   return NULL;
 }
@@ -2492,7 +2502,7 @@ sh_elf64_gc_sweep_hook (abfd, info, sec, relocs)
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.  */
+
 static boolean
 sh_elf64_check_relocs (abfd, info, sec, relocs)
      bfd *abfd;
@@ -2522,7 +2532,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf64_External_Sym);
   if (!elf_bad_symtab (abfd))
     sym_hashes_end -= symtab_hdr->sh_info;
+
   dynobj = elf_hash_table (info)->dynobj;
   local_got_offsets = elf_local_got_offsets (abfd);
 
@@ -2531,13 +2541,13 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
     {
       struct elf_link_hash_entry *h;
       unsigned long r_symndx;
+
       r_symndx = ELF64_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
         h = NULL;
       else
         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
       /* Some relocs require a global offset table.  */
       if (dynobj == NULL)
        {
@@ -2581,7 +2591,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
           if (!_bfd_elf64_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:
@@ -2866,7 +2876,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
          break;
         }
     }
+
   return true;
 }
 
@@ -2914,7 +2924,8 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
      bfd_vma *valp;
 {
   /* We want to do this for relocatable as well as final linking.  */
-  if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
+  if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
+      && info->hash->creator->flavour == bfd_target_elf_flavour)
     {
       struct elf_link_hash_entry *h;
 
@@ -3000,7 +3011,7 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
    we don't need to look up and make sure to emit the main symbol for each
    DataLabel symbol.  */
 
-boolean
+static boolean
 sh64_elf64_link_output_symbol_hook (abfd, info, cname, sym, input_sec)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
@@ -3212,14 +3223,14 @@ sh64_elf64_link_hash_table_create (abfd)
   struct elf_sh64_link_hash_table *ret;
 
   ret = ((struct elf_sh64_link_hash_table *)
-        bfd_alloc (abfd, sizeof (struct elf_sh64_link_hash_table)));
+        bfd_malloc (sizeof (struct elf_sh64_link_hash_table)));
   if (ret == (struct elf_sh64_link_hash_table *) NULL)
     return NULL;
 
   if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
                                       sh64_elf64_link_hash_newfunc))
     {
-      bfd_release (abfd, ret);
+      free (ret);
       return NULL;
     }
 
@@ -3592,6 +3603,9 @@ sh64_elf64_discard_copies (h, ignore)
 {
   struct elf_sh64_pcrel_relocs_copied *s;
 
+  if (h->root.root.type == bfd_link_hash_warning)
+    h = (struct elf_sh64_link_hash_entry *) h->root.root.u.i.link;
+
   /* We only discard relocs for symbols defined in a regular object.  */
   if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
     return true;
This page took 0.027157 seconds and 4 git commands to generate.