readonly_dynrelocs
[deliverable/binutils-gdb.git] / bfd / elfxx-tilegx.c
index 59a2f7ef2882790c4e7fc4ce54c791e3fe66e17b..19c55417ab24301bb02e7e5faa2ce66de4e7bae3 100644 (file)
@@ -1,5 +1,5 @@
 /* TILE-Gx-specific support for ELF.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -855,10 +855,6 @@ struct tilegx_elf_link_hash_table
   void (*put_word) (bfd *, bfd_vma, void *);
   const char *dynamic_interpreter;
 
-  /* Short-cuts to get to dynamic linker sections.  */
-  asection *sdynbss;
-  asection *srelbss;
-
   /* Whether LE transition has been disabled for some of the
      sections.  */
   bfd_boolean disable_le_transition;
@@ -1439,8 +1435,7 @@ tilegx_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
   struct elf_link_hash_table *htab = elf_hash_table (info);
 
   /* This function may be called more than once.  */
-  s = bfd_get_linker_section (abfd, ".got");
-  if (s != NULL)
+  if (htab->sgot != NULL)
     return TRUE;
 
   flags = bed->dynamic_sec_flags;
@@ -1501,26 +1496,10 @@ bfd_boolean
 tilegx_elf_create_dynamic_sections (bfd *dynobj,
                                    struct bfd_link_info *info)
 {
-  struct tilegx_elf_link_hash_table *htab;
-
-  htab = tilegx_elf_hash_table (info);
-  BFD_ASSERT (htab != NULL);
-
   if (!tilegx_elf_create_got_section (dynobj, info))
     return FALSE;
 
-  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
-    return FALSE;
-
-  htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!bfd_link_pic (info))
-    htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-
-  if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
-      || (!bfd_link_pic (info) && !htab->srelbss))
-    abort ();
-
-  return TRUE;
+  return _bfd_elf_create_dynamic_sections (dynobj, info);
 }
 
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
@@ -1643,7 +1622,7 @@ static int
 tilegx_elf_tls_transition (struct bfd_link_info *info, int r_type,
                           int is_local, bfd_boolean disable_le_transition)
 {
-  if (bfd_link_pic (info))
+  if (!bfd_link_executable (info))
     return r_type;
 
   if (is_local && !disable_le_transition)
@@ -1716,7 +1695,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   for (rel = relocs; rel < rel_end; rel++)
     {
       unsigned int r_type;
-      unsigned long r_symndx;
+      unsigned int r_symndx;
       struct elf_link_hash_entry *h;
       int tls_type;
 
@@ -1725,8 +1704,9 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
        {
-         (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
-                                abfd, r_symndx);
+         /* xgettext:c-format */
+         _bfd_error_handler (_("%B: bad symbol index: %d"),
+                             abfd, r_symndx);
          return FALSE;
        }
 
@@ -1738,10 +1718,6 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
-         /* PR15323, ref flags aren't set for references in the same
-            object.  */
-         h->root.non_ir_ref = 1;
        }
 
       r_type = tilegx_elf_tls_transition (info, r_type, h == NULL,
@@ -1754,7 +1730,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
        case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
        case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
-         if (bfd_link_pic (info))
+         if (!bfd_link_executable (info))
            goto r_tilegx_plt32;
          break;
 
@@ -1775,7 +1751,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
        case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
           tls_type = GOT_TLS_IE;
-          if (bfd_link_pic (info))
+          if (!bfd_link_executable (info))
             info->flags |= DF_STATIC_TLS;
           goto have_got_reference;
 
@@ -1832,7 +1808,8 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                   tls_type = old_tls_type;
                 else
                   {
-                    (*_bfd_error_handler)
+                   _bfd_error_handler
+                     /* xgettext:c-format */
                       (_("%B: `%s' accessed both as normal and thread local symbol"),
                        abfd, h ? h->root.root.string : "<local>");
                     return FALSE;
@@ -1856,7 +1833,7 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
          break;
 
        case R_TILEGX_TLS_GD_CALL:
-         if (bfd_link_pic (info))
+         if (!bfd_link_executable (info))
            {
              /* These are basically R_TILEGX_JUMPOFF_X1_PLT relocs
                 against __tls_get_addr.  */
@@ -2122,6 +2099,8 @@ tilegx_elf_gc_mark_hook (asection *sec,
      dealing with TLS optimization, ought to be !bfd_link_executable (info).  */
   if (bfd_link_pic (info))
     {
+      struct bfd_link_hash_entry *bh;
+
       switch (TILEGX_ELF_R_TYPE (rel->r_info))
        {
        case R_TILEGX_TLS_GD_CALL:
@@ -2130,12 +2109,18 @@ tilegx_elf_gc_mark_hook (asection *sec,
             on this reloc, so the real symbol and section will be
             gc marked when processing the other reloc.  That lets
             us handle __tls_get_addr here.  */
-         h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
-                                   FALSE, FALSE, TRUE);
+         bh = NULL;
+         if (! _bfd_generic_link_add_one_symbol (info, sec->owner,
+                                                 "__tls_get_addr", 0,
+                                                 bfd_und_section_ptr,
+                                                 0, NULL, FALSE,
+                                                 FALSE, &bh))
+           return NULL;
+         h = (struct elf_link_hash_entry *) bh;
          BFD_ASSERT (h != NULL);
          h->mark = 1;
-         if (h->u.weakdef != NULL)
-           h->u.weakdef->mark = 1;
+         if (h->is_weakalias)
+           weakdef (h)->mark = 1;
          sym = NULL;
        }
     }
@@ -2143,193 +2128,21 @@ tilegx_elf_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
-/* Update the got entry reference counts for the section being removed.  */
-bfd_boolean
-tilegx_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
-                         asection *sec, const Elf_Internal_Rela *relocs)
-{
-  struct tilegx_elf_link_hash_table *htab;
-  Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes;
-  bfd_signed_vma *local_got_refcounts;
-  const Elf_Internal_Rela *rel, *relend;
+/* Find dynamic relocs for H that apply to read-only sections.  */
 
-  if (bfd_link_relocatable (info))
-    return TRUE;
-
-  BFD_ASSERT (is_tilegx_elf (abfd) || sec->reloc_count == 0);
-
-  elf_section_data (sec)->local_dynrel = NULL;
-
-  htab = tilegx_elf_hash_table (info);
-  BFD_ASSERT (htab != NULL);
-  symtab_hdr = &elf_symtab_hdr (abfd);
-  sym_hashes = elf_sym_hashes (abfd);
-  local_got_refcounts = elf_local_got_refcounts (abfd);
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct tilegx_elf_dyn_relocs *p;
 
-  relend = relocs + sec->reloc_count;
-  for (rel = relocs; rel < relend; rel++)
+  for (p = tilegx_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
     {
-      unsigned long r_symndx;
-      unsigned int r_type;
-      struct elf_link_hash_entry *h = NULL;
-
-      r_symndx = TILEGX_ELF_R_SYMNDX (htab, rel->r_info);
-      if (r_symndx >= symtab_hdr->sh_info)
-       {
-         struct tilegx_elf_link_hash_entry *eh;
-         struct tilegx_elf_dyn_relocs **pp;
-         struct tilegx_elf_dyn_relocs *p;
-
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-         eh = (struct tilegx_elf_link_hash_entry *) h;
-         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-           if (p->sec == sec)
-             {
-               /* Everything must go for SEC.  */
-               *pp = p->next;
-               break;
-             }
-       }
-
-      r_type = TILEGX_ELF_R_TYPE (rel->r_info);
-      r_type = tilegx_elf_tls_transition (info, r_type, h != NULL,
-                                         sec->sec_flg0);
-      switch (r_type)
-       {
-       case R_TILEGX_IMM16_X0_HW0_GOT:
-       case R_TILEGX_IMM16_X1_HW0_GOT:
-       case R_TILEGX_IMM16_X0_HW0_LAST_GOT:
-       case R_TILEGX_IMM16_X1_HW0_LAST_GOT:
-       case R_TILEGX_IMM16_X0_HW1_LAST_GOT:
-       case R_TILEGX_IMM16_X1_HW1_LAST_GOT:
-       case R_TILEGX_IMM16_X0_HW0_TLS_GD:
-       case R_TILEGX_IMM16_X1_HW0_TLS_GD:
-       case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
-       case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
-       case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
-       case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
-       case R_TILEGX_IMM16_X0_HW0_TLS_IE:
-       case R_TILEGX_IMM16_X1_HW0_TLS_IE:
-       case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
-       case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
-       case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
-       case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
-         if (h != NULL)
-           {
-             if (h->got.refcount > 0)
-               h->got.refcount--;
-           }
-         else
-           {
-             if (local_got_refcounts &&
-                 local_got_refcounts[r_symndx] > 0)
-               local_got_refcounts[r_symndx]--;
-           }
-         break;
-
-        case R_TILEGX_64_PCREL:
-        case R_TILEGX_32_PCREL:
-        case R_TILEGX_16_PCREL:
-        case R_TILEGX_8_PCREL:
-       case R_TILEGX_IMM16_X0_HW0_PCREL:
-       case R_TILEGX_IMM16_X1_HW0_PCREL:
-       case R_TILEGX_IMM16_X0_HW1_PCREL:
-       case R_TILEGX_IMM16_X1_HW1_PCREL:
-       case R_TILEGX_IMM16_X0_HW2_PCREL:
-       case R_TILEGX_IMM16_X1_HW2_PCREL:
-       case R_TILEGX_IMM16_X0_HW3_PCREL:
-       case R_TILEGX_IMM16_X1_HW3_PCREL:
-       case R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
-       case R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
-       case R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
-       case R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
-       case R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
-       case R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
-         if (h != NULL
-             && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
-           break;
-         /* Fall through.  */
-
-        case R_TILEGX_64:
-        case R_TILEGX_32:
-        case R_TILEGX_16:
-        case R_TILEGX_8:
-       case R_TILEGX_HW0:
-       case R_TILEGX_HW1:
-       case R_TILEGX_HW2:
-       case R_TILEGX_HW3:
-       case R_TILEGX_HW0_LAST:
-       case R_TILEGX_HW1_LAST:
-       case R_TILEGX_HW2_LAST:
-        case R_TILEGX_COPY:
-        case R_TILEGX_GLOB_DAT:
-        case R_TILEGX_JMP_SLOT:
-        case R_TILEGX_RELATIVE:
-        case R_TILEGX_BROFF_X1:
-        case R_TILEGX_JUMPOFF_X1:
-        case R_TILEGX_IMM8_X0:
-        case R_TILEGX_IMM8_Y0:
-        case R_TILEGX_IMM8_X1:
-        case R_TILEGX_IMM8_Y1:
-        case R_TILEGX_DEST_IMM8_X1:
-        case R_TILEGX_MT_IMM14_X1:
-        case R_TILEGX_MF_IMM14_X1:
-        case R_TILEGX_MMSTART_X0:
-        case R_TILEGX_MMEND_X0:
-        case R_TILEGX_SHAMT_X0:
-        case R_TILEGX_SHAMT_X1:
-        case R_TILEGX_SHAMT_Y0:
-        case R_TILEGX_SHAMT_Y1:
-       case R_TILEGX_IMM16_X0_HW0:
-       case R_TILEGX_IMM16_X1_HW0:
-       case R_TILEGX_IMM16_X0_HW1:
-       case R_TILEGX_IMM16_X1_HW1:
-       case R_TILEGX_IMM16_X0_HW2:
-       case R_TILEGX_IMM16_X1_HW2:
-       case R_TILEGX_IMM16_X0_HW3:
-       case R_TILEGX_IMM16_X1_HW3:
-       case R_TILEGX_IMM16_X0_HW0_LAST:
-       case R_TILEGX_IMM16_X1_HW0_LAST:
-       case R_TILEGX_IMM16_X0_HW1_LAST:
-       case R_TILEGX_IMM16_X1_HW1_LAST:
-       case R_TILEGX_IMM16_X0_HW2_LAST:
-       case R_TILEGX_IMM16_X1_HW2_LAST:
-         if (bfd_link_pic (info))
-           break;
-         /* Fall through.  */
-
-        case R_TILEGX_JUMPOFF_X1_PLT:
-       case R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
-       case R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
-       case R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
-       case R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
-       case R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
-       case R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
-       case R_TILEGX_IMM16_X0_HW3_PLT_PCREL:
-       case R_TILEGX_IMM16_X1_HW3_PLT_PCREL:
-       case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
-       case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
-       case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
-       case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
-       case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
-       case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
-         if (h != NULL)
-           {
-             if (h->plt.refcount > 0)
-               h->plt.refcount--;
-           }
-         break;
+      asection *s = p->sec->output_section;
 
-       default:
-         break;
-       }
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+       return p->sec;
     }
-
-  return TRUE;
+  return NULL;
 }
 
 /* Adjust a symbol defined by a dynamic object and referenced by a
@@ -2346,7 +2159,7 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct tilegx_elf_link_hash_entry * eh;
   struct tilegx_elf_dyn_relocs *p;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
 
   htab = tilegx_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
@@ -2356,7 +2169,7 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
              && (h->needs_plt
-                 || h->u.weakdef != NULL
+                 || h->is_weakalias
                  || (h->def_dynamic
                      && h->ref_regular
                      && !h->def_regular)));
@@ -2389,12 +2202,12 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (h->u.weakdef != NULL)
+  if (h->is_weakalias)
     {
-      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
-                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->u.weakdef->root.u.def.section;
-      h->root.u.def.value = h->u.weakdef->root.u.def.value;
+      struct elf_link_hash_entry *def = weakdef (h);
+      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+      h->root.u.def.section = def->root.u.def.section;
+      h->root.u.def.value = def->root.u.def.value;
       return TRUE;
     }
 
@@ -2450,13 +2263,23 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rel.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->srelbss->size += TILEGX_ELF_RELA_BYTES (htab);
+      srel->size += TILEGX_ELF_RELA_BYTES (htab);
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (info, h, htab->sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
@@ -2538,7 +2361,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
      requiring no TLS entry.  */
   if (h->got.refcount > 0
       && !htab->disable_le_transition
-      && !bfd_link_pic (info)
+      && bfd_link_executable (info)
       && h->dynindx == -1
       && tilegx_elf_hash_entry(h)->tls_type == GOT_TLS_IE)
     h->got.offset = (bfd_vma) -1;
@@ -2608,7 +2431,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       if (eh->dyn_relocs != NULL
          && h->root.type == bfd_link_hash_undefweak)
        {
-         if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+         if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+             || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
            eh->dyn_relocs = NULL;
 
          /* Make sure undefined weak symbols are output as a dynamic
@@ -2664,28 +2488,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   return TRUE;
 }
 
-/* Find any dynamic relocs that apply to read-only sections.  */
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+   read-only sections.  */
 
 static bfd_boolean
-readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 {
-  struct tilegx_elf_link_hash_entry *eh;
-  struct tilegx_elf_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct tilegx_elf_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-       {
-         struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
+    {
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-         info->flags |= DF_TEXTREL;
+      info->flags |= DF_TEXTREL;
+      info->callbacks->minfo
+       (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"),
+        sec->owner, h->root.root.string, sec);
 
-         /* Not an error, just cut short the traversal.  */
-         return FALSE;
-       }
+      /* Not an error, just cut short the traversal.  */
+      return FALSE;
     }
   return TRUE;
 }
@@ -2724,7 +2549,7 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (bfd_link_executable (info))
+      if (bfd_link_executable (info) && !info->nointerp)
        {
          s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
@@ -2766,7 +2591,12 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                  srel = elf_section_data (p->sec)->sreloc;
                  srel->size += p->count * TILEGX_ELF_RELA_BYTES (htab);
                  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
-                   info->flags |= DF_TEXTREL;
+                   {
+                     info->flags |= DF_TEXTREL;
+
+                     info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"),
+                                             p->sec->owner, p->sec);
+                   }
                }
            }
        }
@@ -2845,7 +2675,8 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
-         || s == htab->sdynbss)
+         || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -2924,7 +2755,7 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       /* If any dynamic relocs apply to a read-only section,
         then we need a DT_TEXTREL entry.  */
       if ((info->flags & DF_TEXTREL) == 0)
-       elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
+       elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
 
       if (info->flags & DF_TEXTREL)
        {
@@ -3159,7 +2990,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       const char *name;
       bfd_vma off;
       bfd_boolean is_plt = FALSE;
-
+      bfd_boolean resolved_to_zero;
       bfd_boolean unresolved_reloc;
 
       r_type = TILEGX_ELF_R_TYPE (rel->r_info);
@@ -3168,14 +2999,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
        continue;
 
       if ((unsigned int)r_type >= ARRAY_SIZE (tilegx_elf_howto_table))
-       {
-          /* Not clear if we need to check here, but just be paranoid. */
-         (*_bfd_error_handler)
-           (_("%B: unrecognized relocation (0x%x) in section `%A'"),
-            input_bfd, r_type, input_section);
-         bfd_set_error (bfd_error_bad_value);
-         return FALSE;
-       }
+       return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
 
       howto = tilegx_elf_howto_table + r_type;
 
@@ -3247,9 +3071,9 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          else if (h != NULL)
            tls_type = tilegx_elf_hash_entry(h)->tls_type;
 
-         is_tls_iele = (! bfd_link_pic (info) || tls_type == GOT_TLS_IE);
+         is_tls_iele = (bfd_link_executable (info) || tls_type == GOT_TLS_IE);
          is_tls_le = is_tls_iele && (!input_section->sec_flg0
-                                     && !bfd_link_pic (info)
+                                     && bfd_link_executable (info)
                                      && (h == NULL || h->dynindx == -1));
 
          if (r_type == R_TILEGX_TLS_GD_CALL)
@@ -3394,7 +3218,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          break;
        case R_TILEGX_TLS_IE_LOAD:
          if (!input_section->sec_flg0
-             && !bfd_link_pic (info)
+             && bfd_link_executable (info)
              && (h == NULL || h->dynindx == -1))
            {
              /* IE -> LE */
@@ -3420,6 +3244,9 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          break;
        }
 
+      resolved_to_zero = (h != NULL
+                         && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+
       switch (r_type)
        {
        case R_TILEGX_IMM16_X0_HW0_GOT:
@@ -3617,7 +3444,8 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
          if ((bfd_link_pic (info)
               && (h == NULL
-                  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                  || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                      && !resolved_to_zero)
                   || h->root.type != bfd_link_hash_undefweak)
               && (! howto->pc_relative
                   || !SYMBOL_CALLS_LOCAL (info, h)))
@@ -3729,7 +3557,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                          if (indx == 0)
                            {
                              BFD_FAIL ();
-                             (*_bfd_error_handler)
+                             _bfd_error_handler
                                (_("%B: probably compiled without -fPIC?"),
                                 input_bfd);
                              bfd_set_error (bfd_error_bad_value);
@@ -3757,7 +3585,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
         case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
         case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
         case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
-         if (bfd_link_pic (info))
+         if (!bfd_link_executable (info))
            {
              Elf_Internal_Rela outrel;
              bfd_boolean skip;
@@ -3809,7 +3637,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          else if (h != NULL)
            {
              tls_type = tilegx_elf_hash_entry(h)->tls_type;
-             if (!bfd_link_pic (info)
+             if (bfd_link_executable (info)
                  && h->dynindx == -1
                  && tls_type == GOT_TLS_IE)
                r_type = (!input_section->sec_flg0
@@ -3978,11 +3806,12 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
               && h->def_dynamic)
          && _bfd_elf_section_offset (output_bfd, info, input_section,
                                      rel->r_offset) != (bfd_vma) -1)
-       (*_bfd_error_handler)
-         (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+       _bfd_error_handler
+         /* xgettext:c-format */
+         (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
           input_bfd,
           input_section,
-          (long) rel->r_offset,
+          rel->r_offset,
           howto->name,
           h->root.root.string);
 
@@ -4044,15 +3873,14 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          switch (r)
            {
            case bfd_reloc_overflow:
-             r = info->callbacks->reloc_overflow
+             (*info->callbacks->reloc_overflow)
                (info, (h ? &h->root : NULL), name, howto->name,
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              break;
 
            case bfd_reloc_undefined:
-             r = info->callbacks->undefined_symbol
-               (info, name, input_bfd, input_section, rel->r_offset,
-                TRUE);
+             (*info->callbacks->undefined_symbol)
+               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
 
            case bfd_reloc_outofrange:
@@ -4073,11 +3901,8 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
            }
 
          if (msg)
-           r = info->callbacks->warning
-             (info, msg, name, input_bfd, input_section, rel->r_offset);
-
-         if (! r)
-           return FALSE;
+           (*info->callbacks->warning) (info, msg, name, input_bfd,
+                                        input_section, rel->r_offset);
        }
     }
 
@@ -4208,7 +4033,10 @@ tilegx_elf_finish_dynamic_symbol (bfd *output_bfd,
       /* This symbols needs a copy reloc.  Set it up.  */
       BFD_ASSERT (h->dynindx != -1);
 
-      s = htab->srelbss;
+      if (h->root.u.def.section == htab->elf.sdynrelro)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
       BFD_ASSERT (s != NULL);
 
       rela.r_offset = (h->root.u.def.value
@@ -4300,7 +4128,7 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd,
 
       ret = tilegx_finish_dyn (output_bfd, info, dynobj, sdyn, splt);
 
-      if (ret != TRUE)
+      if (!ret)
        return ret;
 
       /* Fill in the head and tail entries in the procedure linkage table.  */
@@ -4320,17 +4148,17 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd,
             entry size.  */
          pad_size = PLT_ENTRY_SIZE - PLT_HEADER_SIZE - PLT_TAIL_SIZE;
          memset (splt->contents + splt->size - pad_size, 0, pad_size);
-       }
 
-      elf_section_data (splt->output_section)->this_hdr.sh_entsize
-       = PLT_ENTRY_SIZE;
+         elf_section_data (splt->output_section)->this_hdr.sh_entsize
+           = PLT_ENTRY_SIZE;
+       }
     }
 
   if (htab->elf.sgotplt)
     {
       if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
            (_("discarded output section: `%A'"), htab->elf.sgotplt);
          return FALSE;
        }
@@ -4344,10 +4172,10 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd,
          TILEGX_ELF_PUT_WORD (htab, output_bfd, (bfd_vma) 0,
                               htab->elf.sgotplt->contents
                               + GOT_ENTRY_SIZE (htab));
-       }
 
-      elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
-       GOT_ENTRY_SIZE (htab);
+         elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
+           GOT_ENTRY_SIZE (htab);
+       }
     }
 
   if (htab->elf.sgot)
@@ -4361,10 +4189,10 @@ tilegx_elf_finish_dynamic_sections (bfd *output_bfd,
                         0);
          TILEGX_ELF_PUT_WORD (htab, output_bfd, val,
                               htab->elf.sgot->contents);
-       }
 
-      elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize =
-       GOT_ENTRY_SIZE (htab);
+         elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize =
+           GOT_ENTRY_SIZE (htab);
+       }
     }
 
   return TRUE;
@@ -4430,14 +4258,16 @@ tilegx_additional_program_headers (bfd *abfd,
 
 
 bfd_boolean
-_bfd_tilegx_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+_bfd_tilegx_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   const char *targ1 = bfd_get_target (ibfd);
   const char *targ2 = bfd_get_target (obfd);
 
   if (strcmp (targ1, targ2) != 0)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
+       /* xgettext:c-format */
        (_("%B: Cannot link together %s and %s objects."),
         ibfd, targ1, targ2);
       bfd_set_error (bfd_error_bad_value);
This page took 0.035923 seconds and 4 git commands to generate.