Fix the thread-pool.c compilation
[deliverable/binutils-gdb.git] / bfd / elfxx-sparc.c
index 83ead7570b3495fd11f418a7205d71e1442743c5..735e83f3de5cc9866d4ed34240aec001626c5136 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.
 
@@ -311,7 +311,7 @@ static reloc_howto_type sparc_rev32_howto =
   HOWTO(R_SPARC_REV32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_REV32", FALSE,0,0xffffffff,TRUE);
 
 reloc_howto_type *
-_bfd_sparc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+_bfd_sparc_elf_reloc_type_lookup (bfd *abfd,
                                  bfd_reloc_code_real_type code)
 {
   /* We explicitly handle each relocation type in the switch
@@ -585,8 +585,10 @@ _bfd_sparc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     default:
       break;
     }
-    bfd_set_error (bfd_error_bad_value);
-    return NULL;
+  /* xgettext:c-format */
+  _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code);
+  bfd_set_error (bfd_error_bad_value);
+  return NULL;
 }
 
 reloc_howto_type *
@@ -595,10 +597,7 @@ _bfd_sparc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 {
   unsigned int i;
 
-  for (i = 0;
-       i < (sizeof (_bfd_sparc_elf_howto_table)
-           / sizeof (_bfd_sparc_elf_howto_table[0]));
-       i++)
+  for (i = 0; i < ARRAY_SIZE (_bfd_sparc_elf_howto_table); i++)
     if (_bfd_sparc_elf_howto_table[i].name != NULL
        && strcasecmp (_bfd_sparc_elf_howto_table[i].name, r_name) == 0)
       return &_bfd_sparc_elf_howto_table[i];
@@ -614,7 +613,8 @@ _bfd_sparc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 }
 
 reloc_howto_type *
-_bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type)
+_bfd_sparc_elf_info_to_howto_ptr (bfd *abfd ATTRIBUTE_UNUSED,
+                                 unsigned int r_type)
 {
   switch (r_type)
     {
@@ -636,8 +636,10 @@ _bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type)
     default:
       if (r_type >= (unsigned int) R_SPARC_max_std)
        {
-         _bfd_error_handler (_("invalid relocation type %d"), (int) r_type);
-         r_type = R_SPARC_NONE;
+         _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                             abfd, r_type);
+         bfd_set_error (bfd_error_bad_value);
+         return NULL;
        }
       return &_bfd_sparc_elf_howto_table[r_type];
     }
@@ -648,13 +650,18 @@ _bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type)
 #define SPARC_ELF_R_TYPE(r_info)       \
        ((r_info) & 0xff)
 
-void
-_bfd_sparc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+bfd_boolean
+_bfd_sparc_elf_info_to_howto (bfd *abfd, arelent *cache_ptr,
                              Elf_Internal_Rela *dst)
 {
   unsigned int r_type = SPARC_ELF_R_TYPE (dst->r_info);
 
-  cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
+  if ((cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (abfd, r_type)) == NULL)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+  return TRUE;
 }
 \f
 
@@ -692,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;
 
@@ -1253,15 +1263,14 @@ create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
 
   s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
   if (s == NULL
-      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+      || !bfd_set_section_alignment (s, bed->plt_alignment))
     return FALSE;
   htab->iplt = s;
 
   s = bfd_make_section_with_flags (abfd, ".rela.iplt",
                                   flags | SEC_READONLY);
   if (s == NULL
-      || ! bfd_set_section_alignment (abfd, s,
-                                     bed->s->log_file_align))
+      || !bfd_set_section_alignment (s, bed->s->log_file_align))
     return FALSE;
   htab->irelplt = s;
 
@@ -1409,7 +1418,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
        {
          /* xgettext:c-format */
-         _bfd_error_handler (_("%B: bad symbol index: %d"), abfd, r_symndx);
+         _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
          return FALSE;
        }
 
@@ -1560,11 +1569,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)
@@ -1577,7 +1587,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  {
                    _bfd_error_handler
                      /* xgettext:c-format */
-                     (_("%B: `%s' accessed both as normal and thread local symbol"),
+                     (_("%pB: `%s' accessed both as normal and thread local symbol"),
                       abfd, h ? h->root.root.string : "<local>");
                    return FALSE;
                  }
@@ -1594,7 +1604,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:
@@ -1604,8 +1620,9 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
          /* Essentially R_SPARC_WPLT30 relocs against __tls_get_addr.  */
          h = (struct elf_link_hash_entry *)
-              bfd_link_hash_lookup (info->hash, "__tls_get_addr", TRUE,
+              bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE,
                                     FALSE, TRUE);
+         BFD_ASSERT (h != NULL);
          /* Fall through */
 
        case R_SPARC_WPLT30:
@@ -1819,9 +1836,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;
 
@@ -2414,7 +2429,7 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 
       info->flags |= DF_TEXTREL;
       info->callbacks->minfo
-       (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"),
+       (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
         sec->owner, h->root.root.string, sec);
 
       /* Not an error, just cut short the traversal.  */
@@ -2437,7 +2452,7 @@ _bfd_sparc_elf_omit_section_dynsym (bfd *output_bfd,
   if (strcmp (p->name, ".got") == 0)
     return FALSE;
 
-  return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
+  return _bfd_elf_omit_section_dynsym_default (output_bfd, info, p);
 }
 
 /* Set the sizes of the dynamic sections.  */
@@ -2513,7 +2528,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
                  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
                    {
                      info->flags |= DF_TEXTREL;
-                     info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"),
+                     info->callbacks->minfo (_("%pB: dynamic relocation in read-only section `%pA'\n"),
                                              p->sec->owner, p->sec);
                    }
                }
@@ -2991,7 +3006,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)
@@ -3086,7 +3107,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                                         NULL);
              _bfd_error_handler
                /* xgettext:c-format */
-               (_("%B: relocation %s against STT_GNU_IFUNC "
+               (_("%pB: relocation %s against STT_GNU_IFUNC "
                   "symbol `%s' isn't handled by %s"), input_bfd,
                 _bfd_sparc_elf_howto_table[r_type].name,
                 name, __FUNCTION__);
@@ -3095,6 +3116,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);
 
@@ -3121,12 +3143,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))
                {
@@ -3508,7 +3532,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                            {
                              BFD_FAIL ();
                              _bfd_error_handler
-                               (_("%B: probably compiled without -fPIC?"),
+                               (_("%pB: probably compiled without -fPIC?"),
                                 input_bfd);
                              bfd_set_error (bfd_error_bad_value);
                              return FALSE;
@@ -3876,10 +3900,11 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                                      rel->r_offset) != (bfd_vma) -1)
        _bfd_error_handler
          /* xgettext:c-format */
-         (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
+         (_("%pB(%pA+%#" PRIx64 "): "
+            "unresolvable %s relocation against symbol `%s'"),
           input_bfd,
           input_section,
-          rel->r_offset,
+          (uint64_t) rel->r_offset,
           howto->name,
           h->root.root.string);
 
@@ -4138,8 +4163,7 @@ do_relocation:
                     || r_type == R_SPARC_UA32
                     || r_type == R_SPARC_DISP32)
                    && (((input_section->flags & SEC_DEBUGGING) != 0
-                        && strcmp (bfd_section_name (input_bfd,
-                                                     input_section),
+                        && strcmp (bfd_section_name (input_section),
                                    ".stab") == 0)
                        || _bfd_elf_section_offset (output_bfd, info,
                                                    input_section,
@@ -4168,7 +4192,7 @@ do_relocation:
                    if (name == NULL)
                      return FALSE;
                    if (*name == '\0')
-                     name = bfd_section_name (input_bfd, sec);
+                     name = bfd_section_name (sec);
                  }
                (*info->callbacks->reloc_overflow)
                  (info, (h ? &h->root : NULL), name, howto->name,
@@ -4765,6 +4789,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.043026 seconds and 4 git commands to generate.