Convert symfile-debug.c to type-safe registry API
[deliverable/binutils-gdb.git] / bfd / elfxx-sparc.c
index 30e7bd3c31a1c4b9bd31e4365e875fb9e5334e38..e479884071da97f308d1b6068c33928e8f4e9659 100644 (file)
@@ -1,5 +1,5 @@
 /* SPARC-specific support for ELF
-   Copyright (C) 2005-2018 Free Software Foundation, Inc.
+   Copyright (C) 2005-2019 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -658,8 +658,6 @@ _bfd_sparc_elf_info_to_howto (bfd *abfd, arelent *cache_ptr,
 
   if ((cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (abfd, r_type)) == NULL)
     {
-      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
-                         abfd, r_type);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -701,9 +699,12 @@ struct _bfd_sparc_elf_link_hash_entry
 #define GOT_TLS_IE      3
   unsigned char tls_type;
 
-    /* Symbol has GOT or PLT relocations.  */
+  /* Symbol has GOT or PLT relocations.  */
   unsigned int has_got_reloc : 1;
 
+  /* Symbol has old-style, non-relaxable GOT relocations.  */
+  unsigned int has_old_style_got_reloc : 1;
+
   /* Symbol has non-GOT/non-PLT relocations in text sections.  */
   unsigned int has_non_got_reloc : 1;
 
@@ -1569,11 +1570,12 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    && r_type != R_SPARC_GOTDATA_OP_LOX10)
                  local_got_refcounts[r_symndx] += 1;
 
-               old_tls_type = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
+               old_tls_type
+                 = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
              }
 
-           /* If a TLS symbol is accessed using IE at least once, there is no point
-              in using the dynamic model for it.  */
+           /* If a TLS symbol is accessed using IE at least once, there is no
+              point in using the dynamic model for it.  */
            if (old_tls_type != tls_type)
              {
                if (old_tls_type == GOT_UNKNOWN)
@@ -1603,7 +1605,13 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
            return FALSE;
 
          if (eh != NULL)
-           eh->has_got_reloc = 1;
+           {
+             eh->has_got_reloc = 1;
+             if (r_type == R_SPARC_GOT10
+                 || r_type == R_SPARC_GOT13
+                 || r_type == R_SPARC_GOT22)
+               eh->has_old_style_got_reloc = 1;
+           }
          break;
 
        case R_SPARC_TLS_GD_CALL:
@@ -1829,9 +1837,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
          break;
 
        case R_SPARC_GNU_VTENTRY:
-         BFD_ASSERT (h != NULL);
-         if (h != NULL
-             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
 
@@ -3001,7 +3007,13 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
          if ((input_section->flags & SEC_ALLOC) == 0
              || h->plt.offset == (bfd_vma) -1)
-           abort ();
+           {
+             /* If this is a SHT_NOTE section without SHF_ALLOC, treat
+                STT_GNU_IFUNC symbol as STT_FUNC.  */
+             if (elf_section_type (input_section) == SHT_NOTE)
+               goto skip_ifunc;
+             abort ();
+           }
 
          plt_sec = htab->elf.splt;
          if (! plt_sec)
@@ -3105,6 +3117,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
            }
        }
 
+    skip_ifunc:
       eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
       resolved_to_zero = eh && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
 
@@ -3131,12 +3144,14 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
              bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
 
              /* If the symbol is global but not dynamic, an .rela.* slot has
-                been allocated for it in the GOT so output R_SPARC_NONE here.
-                See also the handling of other GOT relocations just below.  */
+                been allocated for it in the GOT so output R_SPARC_NONE here,
+                if it isn't also subject to another, old-style GOT relocation.
+                See also the handling of these GOT relocations just below.  */
              if (h != NULL
                  && h->dynindx == -1
                  && !h->forced_local
                  && h->root.type != bfd_link_hash_undefweak
+                 && !eh->has_old_style_got_reloc
                  && (h->got.offset & 1) == 0
                  && bfd_link_pic (info))
                {
@@ -4776,6 +4791,24 @@ _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i
   BFD_ASSERT (htab != NULL);
   dynobj = htab->elf.dynobj;
 
+  /* We arranged in size_dynamic_sections to put the STT_REGISTER
+     entries at the end of the dynlocal list, so they came at the end
+     of the local symbols in the symtab.  Except that they aren't
+     STB_LOCAL, so we need to back up symtab->sh_info.  */
+  if (ABI_64_P (output_bfd)
+      && elf_hash_table (info)->dynlocal)
+    {
+      asection *dynsymsec = bfd_get_linker_section (dynobj, ".dynsym");
+      struct elf_link_local_dynamic_entry *e;
+
+      for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
+       if (e->input_indx == -1)
+         break;
+      if (e)
+       elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
+         = e->dynindx;
+    }
+
   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
This page took 0.027656 seconds and 4 git commands to generate.