gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-nios2.c
index c63932fd1b02049556ab726fe3207bbb7081deb0..71200da9b57b05468df2c0c886a379c64f890a50 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for Nios II.
-   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+   Copyright (C) 2012-2020 Free Software Foundation, Inc.
    Contributed by Nigel Gray (ngray@altera.com).
    Contributed by Mentor Graphics, Inc.
 
@@ -31,6 +31,7 @@
 #include "elf/nios2.h"
 #include "opcode/nios2.h"
 #include "elf32-nios2.h"
+#include "libiberty.h"
 
 /* Use RELA relocations.  */
 #ifndef USE_RELA
@@ -1400,7 +1401,7 @@ static reloc_howto_type elf_nios2_r2_howto_table_rel[] = {
         TRUE,
         6,
         complain_overflow_signed,
-        bfd_elf_generic_reloc,         /* FIXME? */
+        bfd_elf_generic_reloc,         /* FIXME? */
         "R_NIOS2_R2_I10_1_PCREL",
         FALSE,
         0xffc0,
@@ -1578,10 +1579,8 @@ lookup_howto (unsigned int rtype, bfd *abfd)
   int i;
   /* R2 relocations are a superset of R1, so use that for the lookup
      table.  */
-  int r1_howto_tbl_size = (int) (sizeof (elf_nios2_r1_howto_table_rel)
-                                / sizeof (elf_nios2_r1_howto_table_rel[0]));
-  int r2_howto_tbl_size = (int) (sizeof (elf_nios2_r2_howto_table_rel)
-                                / sizeof (elf_nios2_r2_howto_table_rel[0]));
+  int r1_howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r1_howto_table_rel);
+  int r2_howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r2_howto_table_rel);
 
   if (!initialized)
     {
@@ -1597,18 +1596,19 @@ lookup_howto (unsigned int rtype, bfd *abfd)
        }
     }
 
-  BFD_ASSERT (rtype <= R_NIOS2_ILLEGAL);
+  if (rtype > R_NIOS2_ILLEGAL)
+    return NULL;
   i = elf_code_to_howto_index[rtype];
   if (BFD_IS_R2 (abfd))
     {
       if (i >= r2_howto_tbl_size)
-       return 0;
+       return NULL;
       return elf_nios2_r2_howto_table_rel + i;
     }
   else
     {
       if (i >= r1_howto_tbl_size)
-       return 0;
+       return NULL;
       return elf_nios2_r1_howto_table_rel + i;
     }
 }
@@ -1620,7 +1620,8 @@ struct elf_reloc_map
   enum elf_nios2_reloc_type elf_val;
 };
 
-static const struct elf_reloc_map nios2_reloc_map[] = {
+static const struct elf_reloc_map nios2_reloc_map[] =
+{
   {BFD_RELOC_NONE, R_NIOS2_NONE},
   {BFD_RELOC_NIOS2_S16, R_NIOS2_S16},
   {BFD_RELOC_NIOS2_U16, R_NIOS2_U16},
@@ -1726,26 +1727,6 @@ struct elf32_nios2_stub_hash_entry
    bfd_hash_lookup ((table), (string), (create), (copy)))
 
 
-/* The Nios II linker needs to keep track of the number of relocs that it
-   decides to copy as dynamic relocs in check_relocs for each symbol.
-   This is so that it can later discard them if they are found to be
-   unnecessary.  We store the information in a field extending the
-   regular ELF linker hash table.  */
-
-struct elf32_nios2_dyn_relocs
-{
-  struct elf32_nios2_dyn_relocs *next;
-
-  /* The input section of the reloc.  */
-  asection *sec;
-
-  /* Total number of relocs copied for the input section.  */
-  bfd_size_type count;
-
-  /* Number of pc-relative relocs copied for the input section.  */
-  bfd_size_type pc_count;
-};
-
 /* Nios II ELF linker hash entry.  */
 
 struct elf32_nios2_link_hash_entry
@@ -1756,9 +1737,6 @@ struct elf32_nios2_link_hash_entry
      symbol.  */
   struct elf32_nios2_stub_hash_entry *hsh_cache;
 
-  /* Track dynamic relocs copied for this symbol.  */
-  struct elf32_nios2_dyn_relocs *dyn_relocs;
-
 #define GOT_UNKNOWN    0
 #define GOT_NORMAL     1
 #define GOT_TLS_GD     2
@@ -1820,8 +1798,6 @@ struct elf32_nios2_link_hash_table
     Elf_Internal_Sym **all_local_syms;
 
     /* Short-cuts to get to dynamic linker sections.  */
-    asection *sdynbss;
-    asection *srelbss;
     asection *sbss;
 
     /* GOT pointer symbol _gp_got.  */
@@ -2060,7 +2036,6 @@ link_hash_newfunc (struct bfd_hash_entry *entry,
 
       eh = (struct elf32_nios2_link_hash_entry *) entry;
       eh->hsh_cache = NULL;
-      eh->dyn_relocs = NULL;
       eh->tls_type = GOT_UNKNOWN;
       eh->got_types_used = 0;
     }
@@ -2226,7 +2201,7 @@ nios2_add_stub (const char *stub_name,
   if (hsh == NULL)
     {
       /* xgettext:c-format */
-      _bfd_error_handler (_("%B: cannot create stub entry %s"),
+      _bfd_error_handler (_("%pB: cannot create stub entry %s"),
                          section->owner,
                          stub_name);
       return NULL;
@@ -2249,7 +2224,7 @@ nios2_elf32_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
   unsigned int top_id, top_index;
   asection *section;
   asection **input_list, **list;
-  bfd_size_type amt;
+  size_t amt;
   struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
 
   /* Count the number of input BFDs and find the top input section id.  */
@@ -2511,6 +2486,17 @@ nios2_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U
     = (struct elf32_nios2_stub_hash_entry *) gen_entry;
   asection *stub_sec = hsh->stub_sec;
   bfd_vma sym_value;
+  struct bfd_link_info *info;
+
+  info = (struct bfd_link_info *) in_arg;
+
+  /* Fail if the target section could not be assigned to an output
+     section.  The user should fix his linker script.  */
+  if (hsh->target_section->output_section == NULL
+      && info->non_contiguous_regions)
+    info->callbacks->einfo (_("%F%P: Could not assign '%pA' to an output section. "
+                             "Retry without --enable-non-contiguous-regions.\n"),
+                           hsh->target_section);
 
   /* Make a note of the offset within the stubs for this entry.  */
   hsh->stub_offset = stub_sec->size;
@@ -2581,7 +2567,7 @@ get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd,
   /* We want to read in symbol extension records only once.  To do this
      we need to read in the local symbols in parallel and save them for
      later use; so hold pointers to the local symbols in an array.  */
-  bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+  size_t amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
   all_local_syms = bfd_zmalloc (amt);
   htab->all_local_syms = all_local_syms;
   if (all_local_syms == NULL)
@@ -2948,7 +2934,7 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
          if (bfd_big_endian (ibfd))
            {
              _bfd_error_handler
-               (_("error: %B: Big-endian R2 is not supported."), ibfd);
+               (_("error: %pB: big-endian R2 is not supported"), ibfd);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -2964,7 +2950,7 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
         architectures.  */
       _bfd_error_handler
        /* xgettext:c-format */
-       (_("error: %B: Conflicting CPU architectures %d/%d"),
+       (_("error: %pB: conflicting CPU architectures %d/%d"),
         ibfd, new_flags, old_flags);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
@@ -2976,18 +2962,16 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   return TRUE;
 }
 
-
 /* Implement bfd_elf32_bfd_reloc_type_lookup:
    Given a BFD reloc type, return a howto structure.  */
+
 static reloc_howto_type *
 nios2_elf32_bfd_reloc_type_lookup (bfd *abfd,
                                   bfd_reloc_code_real_type code)
 {
   int i;
 
-  for (i = 0;
-       i < (int) (sizeof (nios2_reloc_map) / sizeof (struct elf_reloc_map));
-       ++i)
+  for (i = 0; i < (int) ARRAY_SIZE (nios2_reloc_map); ++i)
     if (nios2_reloc_map[i].bfd_val == code)
       return lookup_howto (nios2_reloc_map[i].elf_val, abfd);
   return NULL;
@@ -2995,6 +2979,7 @@ nios2_elf32_bfd_reloc_type_lookup (bfd *abfd,
 
 /* Implement bfd_elf32_bfd_reloc_name_lookup:
    Given a reloc name, return a howto structure.  */
+
 static reloc_howto_type *
 nios2_elf32_bfd_reloc_name_lookup (bfd *abfd,
                                   const char *r_name)
@@ -3006,32 +2991,40 @@ nios2_elf32_bfd_reloc_name_lookup (bfd *abfd,
   if (BFD_IS_R2 (abfd))
     {
       howto_tbl = elf_nios2_r2_howto_table_rel;
-      howto_tbl_size = (int) (sizeof (elf_nios2_r2_howto_table_rel)
-                             / sizeof (elf_nios2_r2_howto_table_rel[0]));
+      howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r2_howto_table_rel);
     }
   else
     {
       howto_tbl = elf_nios2_r1_howto_table_rel;
-      howto_tbl_size = (int) (sizeof (elf_nios2_r1_howto_table_rel)
-                             / sizeof (elf_nios2_r1_howto_table_rel[0]));
+      howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r1_howto_table_rel);
     }
 
   for (i = 0; i < howto_tbl_size; i++)
     if (howto_tbl[i].name && strcasecmp (howto_tbl[i].name, r_name) == 0)
       return howto_tbl + i;
+
   return NULL;
 }
 
 /* Implement elf_info_to_howto:
    Given a ELF32 relocation, fill in a arelent structure.  */
-static void
+
+static bfd_boolean
 nios2_elf32_info_to_howto (bfd *abfd, arelent *cache_ptr,
                           Elf_Internal_Rela *dst)
 {
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
-  cache_ptr->howto = lookup_howto (r_type, abfd);
+  if ((cache_ptr->howto = lookup_howto (r_type, abfd)) == NULL)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+  return TRUE;
 }
 
 /* Return the base VMA address which should be subtracted from real addresses
@@ -3076,7 +3069,7 @@ nios2_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp, struct bfd_link_info *info)
 
   h = bfd_hash_lookup (&info->hash->table, "_gp", FALSE, FALSE);
   lh = (struct bfd_link_hash_entry *) h;
-lookup:
+ lookup:
   if (lh)
     {
       switch (lh->type)
@@ -3715,10 +3708,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
   splt = htab->root.splt;
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
-  if (elf32_nios2_hash_table (info)->h_gp_got == NULL)
+  if (htab->h_gp_got == NULL)
     got_base = 0;
   else
-    got_base = elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value;
+    got_base = htab->h_gp_got->root.u.def.value;
 
   for (rel = relocs; rel < relend; rel++)
     {
@@ -3734,8 +3727,8 @@ nios2_elf32_relocate_section (bfd *output_bfd,
       const char *name = NULL;
       int r_type;
       const char *format;
-      char msgbuf[256];
-      const char* msg = (const char*) NULL;
+      char *msgbuf = NULL;
+      char *msg = NULL;
       bfd_boolean unresolved_reloc;
       bfd_vma off;
       int use_plt;
@@ -3774,6 +3767,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 
       if (howto)
        {
+         bfd_boolean resolved_to_zero;
+
+         resolved_to_zero = (h != NULL
+                             && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
          switch (howto->type)
            {
            case R_NIOS2_HI16:
@@ -3830,8 +3827,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                    reloc_address = 0;
 
                  format = _("global pointer relative relocation at address "
-                            "0x%08x when _gp not defined\n");
-                 sprintf (msgbuf, format, reloc_address);
+                            "%#" PRIx64 " when _gp not defined\n");
+                 if (asprintf (&msgbuf, format,
+                               (uint64_t) reloc_address) == -1)
+                   msgbuf = NULL;
                  msg = msgbuf;
                  r = bfd_reloc_dangerous;
                }
@@ -3848,13 +3847,23 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                    {
                      if (h)
                        name = h->root.root.string;
+                     else
+                       {
+                         name = (bfd_elf_string_from_elf_section
+                                 (input_bfd, symtab_hdr->sh_link,
+                                  sym->st_name));
+                         if (name == NULL || *name == '\0')
+                           name = bfd_section_name (sec);
+                       }
                      /* xgettext:c-format */
-                     format = _("Unable to reach %s (at 0x%08x) from the "
-                                "global pointer (at 0x%08x) because the "
-                                "offset (%d) is out of the allowed range, "
-                                "-32678 to 32767.\n" );
-                     sprintf (msgbuf, format, name, symbol_address, gp,
-                              (signed)relocation);
+                     format = _("unable to reach %s (at %#" PRIx64 ") from "
+                                "the global pointer (at %#" PRIx64 ") "
+                                "because the offset (%" PRId64 ") is out of "
+                                "the allowed range, -32678 to 32767\n" );
+                     if (asprintf (&msgbuf, format, name,
+                                   (uint64_t) symbol_address, (uint64_t) gp,
+                                   (int64_t) relocation) == -1)
+                       msgbuf = NULL;
                      msg = msgbuf;
                      r = bfd_reloc_outofrange;
                    }
@@ -4000,13 +4009,14 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 
                  off = h->got.offset;
                  BFD_ASSERT (off != (bfd_vma) -1);
-                 dyn = elf_hash_table (info)->dynamic_sections_created;
+                 dyn = htab->root.dynamic_sections_created;
                  if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
                                                         bfd_link_pic (info),
                                                         h)
                      || (bfd_link_pic (info)
                          && SYMBOL_REFERENCES_LOCAL (info, h))
-                     || (ELF_ST_VISIBILITY (h->other)
+                     || ((ELF_ST_VISIBILITY (h->other)
+                          || resolved_to_zero)
                          && h->root.type == bfd_link_hash_undefweak))
                    {
                      /* This is actually a static link, or it is a -Bsymbolic
@@ -4260,7 +4270,8 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 
                    if ((bfd_link_pic (info) || indx != 0)
                        && (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))
                      {
                        need_relocs = TRUE;
@@ -4371,10 +4382,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                {
                  _bfd_error_handler
                    /* xgettext:c-format */
-                   (_("%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not "
+                   (_("%pB(%pA+%#" PRIx64 "): %s relocation not "
                       "permitted in shared object"),
                     input_bfd, input_section,
-                    (long) rel->r_offset, howto->name);
+                    (uint64_t) rel->r_offset, howto->name);
                  return FALSE;
                }
              else
@@ -4389,7 +4400,8 @@ nios2_elf32_relocate_section (bfd *output_bfd,
              if (bfd_link_pic (info)
                  && (input_section->flags & SEC_ALLOC) != 0
                  && (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))
                {
                  Elf_Internal_Rela outrel;
@@ -4479,7 +4491,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                                                      symtab_hdr->sh_link,
                                                      sym->st_name);
              if (name == NULL || *name == '\0')
-               name = bfd_section_name (input_bfd, sec);
+               name = bfd_section_name (sec);
            }
 
          switch (r)
@@ -4522,6 +4534,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
            {
              (*info->callbacks->warning) (info, msg, name, input_bfd,
                                           input_section, rel->r_offset);
+             free (msgbuf);
              return FALSE;
            }
        }
@@ -4532,10 +4545,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 /* Implement elf-backend_section_flags:
    Convert NIOS2 specific section flags to bfd internal section flags.  */
 static bfd_boolean
-nios2_elf32_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
+nios2_elf32_section_flags (const Elf_Internal_Shdr *hdr)
 {
   if (hdr->sh_flags & SHF_NIOS2_GPREL)
-    *flags |= SEC_SMALL_DATA;
+    hdr->bfd_section->flags |= SEC_SMALL_DATA;
 
   return TRUE;
 }
@@ -4547,7 +4560,7 @@ static bfd_boolean
 nios2_elf32_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
                           Elf_Internal_Shdr *hdr, asection *sec)
 {
-  register const char *name = bfd_get_section_name (abfd, sec);
+  const char *name = bfd_section_name (sec);
 
   if ((sec->flags & SEC_SMALL_DATA)
       || strcmp (name, ".sdata") == 0
@@ -4573,7 +4586,7 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
 
   /* In order for the two loads in .PLTresolve to share the same %hiadj,
      _GLOBAL_OFFSET_TABLE_ must be aligned to a 16-byte boundary.  */
-  if (!bfd_set_section_alignment (dynobj, htab->root.sgotplt, 4))
+  if (!bfd_set_section_alignment (htab->root.sgotplt, 4))
     return FALSE;
 
   /* The Nios II ABI specifies that GOT-relative relocations are relative
@@ -4582,7 +4595,7 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
      points to the base of the GOT while _gp_got may include a bias.  */
   h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,
                                   "_gp_got");
-  elf32_nios2_hash_table (info)->h_gp_got = h;
+  htab->h_gp_got = h;
   if (h == NULL)
     return FALSE;
 
@@ -4602,26 +4615,14 @@ nios2_elf32_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   if (!htab->root.sgot && !create_got_section (dynobj, info))
     return FALSE;
 
-  _bfd_elf_create_dynamic_sections (dynobj, info);
+  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+    return FALSE;
 
   /* In order for the two loads in a shared object .PLTresolve to share the
      same %hiadj, the start of the PLT (as well as the GOT) must be aligned
      to a 16-byte boundary.  This is because the addresses for these loads
      include the -(.plt+4) PIC correction.  */
-  if (!bfd_set_section_alignment (dynobj, htab->root.splt, 4))
-    return FALSE;
-
-  htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!htab->sdynbss)
-    return FALSE;
-  if (!bfd_link_pic (info))
-    {
-      htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-      if (!htab->srelbss)
-       return FALSE;
-    }
-
-  return TRUE;
+  return bfd_set_section_alignment (htab->root.splt, 4);
 }
 
 /* Implement elf_backend_copy_indirect_symbol:
@@ -4636,37 +4637,6 @@ nios2_elf32_copy_indirect_symbol (struct bfd_link_info *info,
   edir = (struct elf32_nios2_link_hash_entry *) dir;
   eind = (struct elf32_nios2_link_hash_entry *) ind;
 
-  if (eind->dyn_relocs != NULL)
-    {
-      if (edir->dyn_relocs != NULL)
-       {
-         struct elf32_nios2_dyn_relocs **pp;
-         struct elf32_nios2_dyn_relocs *p;
-
-         /* Add reloc counts against the indirect sym to the direct sym
-            list.  Merge any entries against the same section.  */
-         for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
-           {
-             struct elf32_nios2_dyn_relocs *q;
-
-             for (q = edir->dyn_relocs; q != NULL; q = q->next)
-               if (q->sec == p->sec)
-                 {
-                   q->pc_count += p->pc_count;
-                   q->count += p->count;
-                   *pp = p->next;
-                   break;
-                 }
-             if (q == NULL)
-               pp = &p->next;
-           }
-         *pp = edir->dyn_relocs;
-       }
-
-      edir->dyn_relocs = eind->dyn_relocs;
-      eind->dyn_relocs = NULL;
-    }
-
   if (ind->root.type == bfd_link_hash_indirect
       && dir->got.refcount <= 0)
     {
@@ -4708,21 +4678,26 @@ static bfd_boolean
 nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                          asection *sec, const Elf_Internal_Rela *relocs)
 {
-  bfd *dynobj;
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   struct elf32_nios2_link_hash_table *htab;
-  asection *sgot;
-  asection *srelgot;
   asection *sreloc = NULL;
   bfd_signed_vma *local_got_refcounts;
 
   if (bfd_link_relocatable (info))
     return TRUE;
 
-  dynobj = elf_hash_table (info)->dynobj;
+  /* Don't do anything special with non-loaded, non-alloced sections.
+     In particular, any relocs in such sections should not affect GOT
+     and PLT reference counting (ie. we don't allow them to create GOT
+     or PLT entries), there's no possibility or desire to optimize TLS
+     relocs, and there's not much point in propagating relocs to shared
+     libs that the dynamic linker won't relocate.  */
+  if ((sec->flags & SEC_ALLOC) == 0)
+    return TRUE;
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   sym_hashes_end = (sym_hashes
@@ -4732,8 +4707,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
   htab = elf32_nios2_hash_table (info);
-  sgot = htab->root.sgot;
-  srelgot = htab->root.srelgot;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -4751,10 +4724,6 @@ nios2_elf32_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 = ELF32_R_TYPE (rel->r_info);
@@ -4792,26 +4761,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                break;
              }
 
-           if (dynobj == NULL)
-             {
-               /* Create the .got section.  */
-               elf_hash_table (info)->dynobj = dynobj = abfd;
-               nios2_elf32_create_dynamic_sections (dynobj, info);
-             }
-
-           if (sgot == NULL)
-             {
-               sgot = htab->root.sgot;
-               BFD_ASSERT (sgot != NULL);
-             }
-
-           if (srelgot == NULL
-               && (h != NULL || bfd_link_pic (info)))
-             {
-               srelgot = htab->root.srelgot;
-               BFD_ASSERT (srelgot != NULL);
-             }
-
            if (h != NULL)
              {
                struct elf32_nios2_link_hash_entry *eh
@@ -4870,11 +4819,7 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;
              }
          }
-         /* Fall through */
-       case R_NIOS2_TLS_LDM16:
-         if (r_type == R_NIOS2_TLS_LDM16)
-           htab->tls_ldm_got.refcount++;
-
+       make_got:
          if (htab->root.sgot == NULL)
            {
              if (htab->root.dynobj == NULL)
@@ -4884,6 +4829,10 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
            }
          break;
 
+       case R_NIOS2_TLS_LDM16:
+         htab->tls_ldm_got.refcount++;
+         goto make_got;
+
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
        case R_NIOS2_GNU_VTINHERIT:
@@ -4931,16 +4880,19 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  || (h != NULL && ! h->needs_plt
                      && (! SYMBOLIC_BIND (info, h) || ! h->def_regular))))
            {
-             struct elf32_nios2_dyn_relocs *p;
-             struct elf32_nios2_dyn_relocs **head;
+             struct elf_dyn_relocs *p;
+             struct elf_dyn_relocs **head;
 
              /* When creating a shared object, we must copy these
                 reloc types into the output file.  We create a reloc
                 section in dynobj and make room for this reloc.  */
              if (sreloc == NULL)
                {
+                 if (htab->root.dynobj == NULL)
+                   htab->root.dynobj = abfd;
+
                  sreloc = _bfd_elf_make_dynamic_reloc_section
-                   (sec, dynobj, 2, abfd, TRUE);
+                   (sec, htab->root.dynobj, 2, abfd, TRUE);
                  if (sreloc == NULL)
                    return FALSE;
                }
@@ -4948,7 +4900,7 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
              /* If this is a global symbol, we count the number of
                 relocations we need for this symbol.  */
              if (h != NULL)
-               head = &((struct elf32_nios2_link_hash_entry *) h)->dyn_relocs;
+               head = &h->dyn_relocs;
              else
                {
                  /* Track dynamic relocs needed for local syms too.
@@ -4969,14 +4921,14 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    s = sec;
 
                  vpp = &elf_section_data (s)->local_dynrel;
-                 head = (struct elf32_nios2_dyn_relocs **) vpp;
+                 head = (struct elf_dyn_relocs **) vpp;
                }
 
              p = *head;
              if (p == NULL || p->sec != sec)
                {
-                 bfd_size_type amt = sizeof *p;
-                 p = ((struct elf32_nios2_dyn_relocs *)
+                 size_t amt = sizeof *p;
+                 p = ((struct elf_dyn_relocs *)
                       bfd_alloc (htab->root.dynobj, amt));
                  if (p == NULL)
                    return FALSE;
@@ -5018,110 +4970,6 @@ nios2_elf32_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
-/* Implement elf_backend_gc_sweep_hook:
-   Update the got entry reference counts for the section being removed.  */
-static bfd_boolean
-nios2_elf32_gc_sweep_hook (bfd *abfd,
-                          struct bfd_link_info *info,
-                          asection *sec,
-                          const Elf_Internal_Rela *relocs)
-{
-  Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes;
-  bfd_signed_vma *local_got_refcounts;
-  const Elf_Internal_Rela *rel, *relend;
-  bfd *dynobj;
-
-  if (bfd_link_relocatable (info))
-    return TRUE;
-
-  elf_section_data (sec)->local_dynrel = NULL;
-
-  dynobj = elf_hash_table (info)->dynobj;
-  if (dynobj == NULL)
-    return TRUE;
-
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  sym_hashes = elf_sym_hashes (abfd);
-  local_got_refcounts = elf_local_got_refcounts (abfd);
-
-  relend = relocs + sec->reloc_count;
-  for (rel = relocs; rel < relend; rel++)
-    {
-      unsigned long r_symndx;
-      struct elf_link_hash_entry *h = NULL;
-      int r_type;
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-      if (r_symndx >= symtab_hdr->sh_info)
-       {
-         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;
-       }
-
-      r_type = ELF32_R_TYPE (rel->r_info);
-      switch (r_type)
-       {
-       case R_NIOS2_GOT16:
-       case R_NIOS2_GOT_LO:
-       case R_NIOS2_GOT_HA:
-       case R_NIOS2_CALL16:
-       case R_NIOS2_CALL_LO:
-       case R_NIOS2_CALL_HA:
-         if (h != NULL)
-           {
-             if (h->got.refcount > 0)
-               --h->got.refcount;
-           }
-         else if (local_got_refcounts != NULL)
-           {
-             if (local_got_refcounts[r_symndx] > 0)
-               --local_got_refcounts[r_symndx];
-           }
-         break;
-
-       case R_NIOS2_PCREL_LO:
-       case R_NIOS2_PCREL_HA:
-       case R_NIOS2_BFD_RELOC_32:
-       case R_NIOS2_CALL26:
-       case R_NIOS2_CALL26_NOAT:
-         if (h != NULL)
-           {
-             struct elf32_nios2_link_hash_entry *eh;
-             struct elf32_nios2_dyn_relocs **pp;
-             struct elf32_nios2_dyn_relocs *p;
-
-             eh = (struct elf32_nios2_link_hash_entry *) h;
-
-             if (h->plt.refcount > 0)
-               --h->plt.refcount;
-
-             if (r_type == R_NIOS2_PCREL_LO || r_type == R_NIOS2_PCREL_HA
-                 || r_type == R_NIOS2_BFD_RELOC_32)
-               {
-                 for (pp = &eh->dyn_relocs; (p = *pp) != NULL;
-                      pp = &p->next)
-                   if (p->sec == sec)
-                     {
-                       p->count -= 1;
-                       if (p->count == 0)
-                         *pp = p->next;
-                       break;
-                     }
-               }
-           }
-         break;
-
-       default:
-         break;
-       }
-    }
-
-  return TRUE;
-}
-
 /* Implement elf_backend_finish_dynamic_symbols:
    Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
@@ -5289,22 +5137,24 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak));
 
-      s = htab->srelbss;
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_COPY);
       rela.r_addend = 0;
+      if (h->root.u.def.section == htab->root.sdynrelro)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
+      BFD_ASSERT (s != NULL);
       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
 
   /* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute.  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || h == elf_hash_table (info)->hgot
-      || h == elf32_nios2_hash_table (info)->h_gp_got)
+      || h == htab->root.hgot
+      || h == htab->h_gp_got)
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -5315,24 +5165,22 @@ static bfd_boolean
 nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
                                     struct bfd_link_info *info)
 {
-  bfd *dynobj;
   asection *sgotplt;
   asection *sdyn;
   struct elf32_nios2_link_hash_table *htab;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
   sgotplt = htab->root.sgotplt;
-  BFD_ASSERT (sgotplt != NULL);
-  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+  sdyn = NULL;
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       asection *splt;
       Elf32_External_Dyn *dyncon, *dynconend;
 
       splt = htab->root.splt;
-      BFD_ASSERT (splt != NULL && sdyn != NULL);
+      sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic");
+      BFD_ASSERT (splt != NULL && sdyn != NULL && sgotplt != NULL);
 
       dyncon = (Elf32_External_Dyn *) sdyn->contents;
       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
@@ -5341,7 +5189,7 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
          Elf_Internal_Dyn dyn;
          asection *s;
 
-         bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+         bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
 
          switch (dyn.d_tag)
            {
@@ -5425,8 +5273,9 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
            }
        }
     }
+
   /* Fill in the first three entries in the global offset table.  */
-  if (sgotplt->size > 0)
+  if (sgotplt != NULL && sgotplt->size > 0)
     {
       if (sdyn == NULL)
        bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
@@ -5436,9 +5285,10 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
                    sgotplt->contents);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
-    }
 
-  elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+      if (sgotplt->output_section != bfd_abs_section_ptr)
+       elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+    }
 
   return TRUE;
 }
@@ -5455,16 +5305,16 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   struct elf32_nios2_link_hash_table *htab;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
   unsigned align2;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
 
   /* 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)));
@@ -5498,12 +5348,12 @@ nios2_elf32_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;
     }
 
@@ -5537,19 +5387,22 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
      determine the address it must put in the global offset table, so
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
-  s = htab->sdynbss;
-  BFD_ASSERT (s != NULL);
-
   /* We must generate a R_NIOS2_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
+      srel = htab->root.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {
-      asection *srel;
-
-      srel = htab->srelbss;
-      BFD_ASSERT (srel != NULL);
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
@@ -5560,8 +5413,8 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   /* Align dynbss.  */
   s->size = BFD_ALIGN (s->size, (bfd_size_type)1 << align2);
-  if (align2 > bfd_get_section_alignment (dynobj, s)
-      && !bfd_set_section_alignment (dynobj, s, align2))
+  if (align2 > bfd_section_alignment (s)
+      && !bfd_set_section_alignment (s, align2))
     return FALSE;
 
   /* Define the symbol as being at this point in the section.  */
@@ -5610,7 +5463,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
   struct bfd_link_info *info;
   struct elf32_nios2_link_hash_table *htab;
   struct elf32_nios2_link_hash_entry *eh;
-  struct elf32_nios2_dyn_relocs *p;
+  struct elf_dyn_relocs *p;
   int use_plt;
 
   if (h->root.type == bfd_link_hash_indirect)
@@ -5752,7 +5605,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
   else
     h->got.offset = (bfd_vma) -1;
 
-  if (eh->dyn_relocs == NULL)
+  if (h->dyn_relocs == NULL)
     return TRUE;
 
   /* In the shared -Bsymbolic case, discard space allocated for
@@ -5766,9 +5619,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
       if (h->def_regular
          && (h->forced_local || SYMBOLIC_BIND (info, h)))
        {
-         struct elf32_nios2_dyn_relocs **pp;
+         struct elf_dyn_relocs **pp;
 
-         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+         for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
            {
              p->count -= p->pc_count;
              p->pc_count = 0;
@@ -5781,11 +5634,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
 
       /* Also discard relocs on undefined weak syms with non-default
         visibility.  */
-      if (eh->dyn_relocs != NULL
+      if (h->dyn_relocs != NULL
          && h->root.type == bfd_link_hash_undefweak)
        {
-         if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
-           eh->dyn_relocs = NULL;
+         if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+             || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+           h->dyn_relocs = NULL;
 
          /* Make sure undefined weak symbols are output as a dynamic
             symbol in PIEs.  */
@@ -5820,13 +5674,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
            goto keep;
        }
 
-      eh->dyn_relocs = NULL;
+      h->dyn_relocs = NULL;
 
     keep: ;
     }
 
   /* Finally, allocate space.  */
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+  for (p = h->dyn_relocs; p != NULL; p = p->next)
     {
       asection *sreloc = elf_section_data (p->sec)->sreloc;
       sreloc->size += p->count * sizeof (Elf32_External_Rela);
@@ -5843,18 +5697,16 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 {
   bfd *dynobj;
   asection *s;
-  bfd_boolean plt;
-  bfd_boolean got;
   bfd_boolean relocs;
   bfd *ibfd;
   struct elf32_nios2_link_hash_table *htab;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
   BFD_ASSERT (dynobj != NULL);
 
   htab->res_n_size = 0;
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
       if (bfd_link_executable (info) && !info->nointerp)
@@ -5893,7 +5745,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       for (s = ibfd->sections; s != NULL; s = s->next)
        {
-         struct elf32_nios2_dyn_relocs *p;
+         struct elf_dyn_relocs *p;
 
          for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
            {
@@ -5909,8 +5761,6 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                {
                  srel = elf_section_data (p->sec)->sreloc;
                  srel->size += p->count * sizeof (Elf32_External_Rela);
-                 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
-                   info->flags |= DF_TEXTREL;
                }
            }
        }
@@ -5962,21 +5812,19 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
      sym dynamic relocs.  */
   elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* If the .got section is more than 0x8000 bytes, we add
         0x8000 to the value of _gp_got, so that 16-bit relocations
         have a greater chance of working. */
       if (htab->root.sgot->size >= 0x8000
-         && elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value == 0)
-       elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value = 0x8000;
+         && htab->h_gp_got->root.u.def.value == 0)
+       htab->h_gp_got->root.u.def.value = 0x8000;
     }
 
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
      memory for them.  */
-  plt = FALSE;
-  got = FALSE;
   relocs = FALSE;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
@@ -5987,48 +5835,39 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       /* It's OK to base decisions on the section name, because none
         of the dynobj section names depend upon the input files.  */
-      name = bfd_get_section_name (dynobj, s);
-
-      if (strcmp (name, ".plt") == 0)
-       {
-         /* Remember whether there is a PLT.  */
-         plt = s->size != 0;
+      name = bfd_section_name (s);
 
-         /* Correct for the number of res_N branches.  */
-         if (plt && !bfd_link_pic (info))
-           {
-             htab->res_n_size = (s->size-28) / 3;
-             s->size += htab->res_n_size;
-           }
-       }
-      else if (CONST_STRNEQ (name, ".rela"))
+      if (CONST_STRNEQ (name, ".rela"))
        {
          if (s->size != 0)
            {
-             relocs = TRUE;
+             if (s != htab->root.srelplt)
+               relocs = TRUE;
 
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
              s->reloc_count = 0;
            }
        }
-      else if (CONST_STRNEQ (name, ".got"))
-       got = s->size != 0;
-      else if (strcmp (name, ".dynbss") != 0)
+      else if (s == htab->root.splt)
+       {
+         /* Correct for the number of res_N branches.  */
+         if (s->size != 0 && !bfd_link_pic (info))
+           {
+             htab->res_n_size = (s->size - 28) / 3;
+             s->size += htab->res_n_size;
+           }
+       }
+      else if (s != htab->sbss
+              && s != htab->root.sgot
+              && s != htab->root.sgotplt
+              && s != htab->root.sdynbss
+              && s != htab->root.sdynrelro)
        /* It's not one of our sections, so don't allocate space.  */
        continue;
 
       if (s->size == 0)
        {
-         /* If we don't need this section, strip it from the
-            output file.  This is mostly to handle .rela.bss and
-            .rela.plt.  We must create both sections in
-            create_dynamic_sections, because they must be created
-            before the linker maps input sections to output
-            sections.  The linker does that before
-            adjust_dynamic_symbol is called, and it is that
-            function which decides whether anything needs to go
-            into these sections.  */
          s->flags |= SEC_EXCLUDE;
          continue;
        }
@@ -6037,11 +5876,6 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        continue;
 
       /* Allocate memory for the section contents.  */
-      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
-        Unused entries should be reclaimed before the section's contents
-        are written out, but at the moment this does not happen.  Thus in
-        order to prevent writing out garbage, we initialize the section's
-        contents to zero.  */
       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
       if (s->contents == NULL)
        return FALSE;
@@ -6052,7 +5886,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab->res_n_size)
     elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* Add some entries to the .dynamic section.  We fill in the
         values later, in elf_nios2_finish_dynamic_sections, but we
@@ -6065,26 +5899,34 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0))
        return FALSE;
 
-      if (got && !add_dynamic_entry (DT_PLTGOT, 0))
+      if (htab->root.sgotplt->size != 0
+         && !add_dynamic_entry (DT_PLTGOT, 0))
        return FALSE;
 
-      if (plt
+      if (htab->root.splt->size != 0
          && (!add_dynamic_entry (DT_PLTRELSZ, 0)
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
              || !add_dynamic_entry (DT_JMPREL, 0)))
        return FALSE;
 
-      if (relocs
-         && (!add_dynamic_entry (DT_RELA, 0)
+      if (relocs)
+       {
+         if (!add_dynamic_entry (DT_RELA, 0)
              || !add_dynamic_entry (DT_RELASZ, 0)
-             || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))))
-       return FALSE;
+             || !add_dynamic_entry (DT_RELAENT,
+                                    sizeof (Elf32_External_Rela)))
+           return FALSE;
 
-      if (!bfd_link_pic (info) && !add_dynamic_entry (DT_NIOS2_GP, 0))
-       return FALSE;
+         if ((info->flags & DF_TEXTREL) == 0)
+           elf_link_hash_traverse (&htab->root,
+                                   _bfd_elf_maybe_set_textrel, info);
 
-      if ((info->flags & DF_TEXTREL) != 0
-         && !add_dynamic_entry (DT_TEXTREL, 0))
+         if ((info->flags & DF_TEXTREL) != 0
+             && !add_dynamic_entry (DT_TEXTREL, 0))
+           return FALSE;
+       }
+
+      if (!bfd_link_pic (info) && !add_dynamic_entry (DT_NIOS2_GP, 0))
        return FALSE;
     }
 #undef add_dynamic_entry
@@ -6108,7 +5950,7 @@ static struct bfd_link_hash_table *
 nios2_elf32_link_hash_table_create (bfd *abfd)
 {
   struct elf32_nios2_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf32_nios2_link_hash_table);
+  size_t amt = sizeof (struct elf32_nios2_link_hash_table);
 
   ret = bfd_zmalloc (amt);
   if (ret == NULL)
@@ -6175,8 +6017,6 @@ nios2_elf_add_symbol_hook (bfd *abfd,
                           asection **secp,
                           bfd_vma *valp)
 {
-  bfd *dynobj;
-
   if (sym->st_shndx == SHN_COMMON
       && !bfd_link_relocatable (info)
       && sym->st_size <= elf_gp_size (abfd)
@@ -6191,12 +6031,11 @@ nios2_elf_add_symbol_hook (bfd *abfd,
        {
          flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
 
-         dynobj = elf_hash_table (info)->dynobj;
-         if (!dynobj)
-           dynobj = abfd;
+         if (htab->root.dynobj == NULL)
+           htab->root.dynobj = abfd;
 
-         htab->sbss = bfd_make_section_anyway_with_flags (dynobj, ".sbss",
-                                                          flags);
+         htab->sbss = bfd_make_section_anyway_with_flags (htab->root.dynobj,
+                                                          ".sbss", flags);
          if (htab->sbss == NULL)
            return FALSE;
        }
@@ -6263,6 +6102,7 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] =
 #define elf_backend_can_refcount       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_got_plt       1
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
 #define elf_backend_dtrel_excludes_plt 1
 
@@ -6272,7 +6112,6 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] =
 #define elf_backend_check_relocs         nios2_elf32_check_relocs
 
 #define elf_backend_gc_mark_hook         nios2_elf32_gc_mark_hook
-#define elf_backend_gc_sweep_hook        nios2_elf32_gc_sweep_hook
 #define elf_backend_create_dynamic_sections \
                                          nios2_elf32_create_dynamic_sections
 #define elf_backend_finish_dynamic_symbol nios2_elf32_finish_dynamic_symbol
This page took 0.039647 seconds and 4 git commands to generate.