This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

readonly_dynrelocs


In early October, HJ Lu added support for a number of targets to "Dump
dynamic relocation in read-only section with minfo".  This extends
that support to more targets, displays the symbol involved, and splits
the existing function that sets TEXTREL into a "readonly_dynrelocs"
and "maybe_set_textrel" function.  I'll need "readonly_dynrelocs" if I
ever get around to fixing "pr22374 function pointer initialization"
fails.

am33_2.0, arc, bfin, hppa64, mn10300, and nios2 fail to mark a binary
needing text relocations with DT_TEXTREL.  That's not good.  xtensa also
fails to do so but complains about "dangerous relocation: dynamic
relocation in read-only section" so I reckon that is fine and have
marked the test as an xfail.  The other targets need maintainer
attention.

Curiously, the map file dump wasn't added for x86, so the map test
currently fail on x86.  (I can add the x86 support if you like HJ?)
It also fails on alpha, am33_2.0, arc, bfin, hppa64, ia64, m68k, mips,
mn10300, nios2, score and vax.  cris complains with "tmpdir/textrel.o,
section .rodata: relocation R_CRIS_32 should not be used in a shared
object; recompile with -fPIC" so I've marked it as an xfail.

bfd/
	* elf32-hppa.c (maybe_set_textrel): Print symbol for map file output.
	* elf32-ppc.c (maybe_set_textrel): Likewise.
	* elf64-ppc.c (maybe_set_textrel): Likewise.
	* elf32-arm.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing..
	(elf32_arm_readonly_dynrelocs): ..this.
	* elf32-lm32.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf32-m32r.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf32-metag.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf32-nds32.c: Delete unnecessary forward declarations.
	(readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf32-or1k.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf32-s390.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf32-sh.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf32-tic6x.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing..
	(elf32_tic6x_readonly_dynrelocs): ..this.
	* elf32-tilepro.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elf64-s390.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elfnn-aarch64.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing..
	(aarch64_readonly_readonly_dynrelocs): ..this.
	* elfnn-riscv.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elfxx-sparc.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
	* elfxx-tilegx.c (readonly_dynrelocs): New function.
	(maybe_set_textrel): New function, replacing old version of..
	(readonly_dynrelocs): ..this.
ld/
	* testsuite/ld-elf/shared.exp: Run new textrel tests.
	* testsuite/ld-elf/textrel.map: New file.
	* testsuite/ld-elf/textrel.rd: New file.
	* testsuite/ld-elf/textrel.s: New file.
	* testsuite/ld-elf/textrel.warn: New file.

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1b2db46..ae28970 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,57 @@
 2017-12-01  Alan Modra  <amodra@gmail.com>
 
+	* elf32-hppa.c (maybe_set_textrel): Print symbol for map file output.
+	* elf32-ppc.c (maybe_set_textrel): Likewise.
+	* elf64-ppc.c (maybe_set_textrel): Likewise.
+	* elf32-arm.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing..
+	(elf32_arm_readonly_dynrelocs): ..this.
+	* elf32-lm32.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf32-m32r.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf32-metag.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf32-nds32.c: Delete unnecessary forward declarations.
+	(readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf32-or1k.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf32-s390.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf32-sh.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf32-tic6x.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing..
+	(elf32_tic6x_readonly_dynrelocs): ..this.
+	* elf32-tilepro.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elf64-s390.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elfnn-aarch64.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing..
+	(aarch64_readonly_readonly_dynrelocs): ..this.
+	* elfnn-riscv.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elfxx-sparc.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+	* elfxx-tilegx.c (readonly_dynrelocs): New function.
+	(maybe_set_textrel): New function, replacing old version of..
+	(readonly_dynrelocs): ..this.
+
+2017-12-01  Alan Modra  <amodra@gmail.com>
+
 	PR 22533
 	* elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Don't do anything
 	special with non_got_ref for weak aliases.
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index bd0fee6..6f16e2d 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -15091,6 +15091,23 @@ elf32_arm_find_inliner_info (bfd *          abfd,
   return found;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+
+  for (p = elf32_arm_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -15598,28 +15615,29 @@ allocate_dynrelocs_for_symbol (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
-elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 {
-  struct elf32_arm_link_hash_entry * eh;
-  struct elf_dyn_relocs * p;
+  asection *sec;
 
-  eh = (struct elf32_arm_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec;
+  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;
 }
@@ -16016,8 +16034,7 @@ elf32_arm_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->root, elf32_arm_readonly_dynrelocs,
-				info);
+	elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
 
       if ((info->flags & DF_TEXTREL) != 0)
 	{
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index 3f71159..57d746e 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -2098,8 +2098,8 @@ maybe_set_textrel (struct elf_link_hash_entry *eh, void *inf)
 
       info->flags |= DF_TEXTREL;
       info->callbacks->minfo
-	(_("%B: dynamic relocation in read-only section `%A'\n"),
-	 sec->owner, sec);
+	(_("%B: dynamic relocation against `%T' in read-only section `%A'\n"),
+	 sec->owner, eh->root.root.string, sec);
 
       /* Not an error, just cut short the traversal.  */
       return FALSE;
diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c
index e0286d6..35911d9 100644
--- a/bfd/elf32-lm32.c
+++ b/bfd/elf32-lm32.c
@@ -1643,6 +1643,24 @@ lm32_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
     }
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_lm32_dyn_relocs *p;
+  struct elf_lm32_link_hash_entry *eh = (struct elf_lm32_link_hash_entry *) h;
+
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -1972,28 +1990,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 elf_lm32_link_hash_entry *eh;
-  struct elf_lm32_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct elf_lm32_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;
 }
@@ -2189,8 +2208,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd,
           /* 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->root, readonly_dynrelocs,
-                                    info);
+            elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
 
           if ((info->flags & DF_TEXTREL) != 0)
             {
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index 9a7b5c3..94bd482 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -1757,6 +1757,24 @@ m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
 }
 
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_m32r_dyn_relocs *p;
+  struct elf_m32r_link_hash_entry *eh = (struct elf_m32r_link_hash_entry *) h;
+
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2090,28 +2108,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 elf_m32r_link_hash_entry *eh;
-  struct elf_m32r_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct elf_m32r_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;
 }
@@ -2311,8 +2330,7 @@ m32r_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->root, readonly_dynrelocs,
-                                    info);
+            elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
 
           if ((info->flags & DF_TEXTREL) != 0)
             {
diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c
index 3a80cb3..30c980e 100644
--- a/bfd/elf32-metag.c
+++ b/bfd/elf32-metag.c
@@ -2452,6 +2452,23 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind);
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_metag_dyn_reloc_entry *p;
+
+  for (p = metag_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->hdh_next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2779,31 +2796,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, 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 *eh, void *inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 {
-  struct elf_metag_link_hash_entry *hh;
-  struct elf_metag_dyn_reloc_entry *hdh_p;
+  asection *sec;
 
-  if (eh->root.type == bfd_link_hash_warning)
-    eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-  hh = (struct elf_metag_link_hash_entry *) eh;
-  for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
     {
-      asection *s = hdh_p->sec->output_section;
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	{
-	  struct bfd_link_info *info = inf;
-
-	  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;
 }
@@ -3032,7 +3047,7 @@ elf_metag_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->etab, readonly_dynrelocs, info);
+	    elf_link_hash_traverse (&htab->etab, maybe_set_textrel, info);
 
 	  if ((info->flags & DF_TEXTREL) != 0)
 	    {
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index 32870ee..65e430c 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -56,56 +56,8 @@ static bfd_reloc_status_type nds32_elf_sda15_reloc
 static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc
   (bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma,
    asection *, bfd_vma, bfd_vma);
-static void nds32_elf_relocate_hi20
-  (bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
-static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup
-  (enum elf_nds32_reloc_type);
-static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
-  (bfd *, bfd_reloc_code_real_type);
-
-/* Target hooks.  */
-static void nds32_info_to_howto_rel
-  (bfd *, arelent *, Elf_Internal_Rela *dst);
-static void nds32_info_to_howto
-  (bfd *, arelent *, Elf_Internal_Rela *dst);
-static bfd_boolean nds32_elf_add_symbol_hook
-  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
-   flagword *, asection **, bfd_vma *);
-static bfd_boolean nds32_elf_relocate_section
-  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
-static bfd_boolean nds32_elf_object_p (bfd *);
-static void nds32_elf_final_write_processing (bfd *, bfd_boolean);
-static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword);
-static bfd_boolean nds32_elf_merge_private_bfd_data
-  (bfd *, struct bfd_link_info *);
-static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *);
-static bfd_boolean nds32_elf_check_relocs
-  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
-static asection *nds32_elf_gc_mark_hook
-  (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-   struct elf_link_hash_entry *, Elf_Internal_Sym *);
-static bfd_boolean nds32_elf_adjust_dynamic_symbol
-  (struct bfd_link_info *, struct elf_link_hash_entry *);
-static bfd_boolean nds32_elf_size_dynamic_sections
-  (bfd *, struct bfd_link_info *);
-static bfd_boolean nds32_elf_create_dynamic_sections
-  (bfd *, struct bfd_link_info *);
-static bfd_boolean nds32_elf_finish_dynamic_sections
-  (bfd *, struct bfd_link_info *info);
-static bfd_boolean nds32_elf_finish_dynamic_symbol
-  (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
-   Elf_Internal_Sym *);
-static bfd_boolean nds32_elf_mkobject (bfd *);
 
 /* Nds32 helper functions.  */
-static bfd_reloc_status_type nds32_elf_final_sda_base
-  (bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean);
-static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *);
-static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *);
-static Elf_Internal_Rela *find_relocs_at_address
-  (Elf_Internal_Rela *, Elf_Internal_Rela *,
-   Elf_Internal_Rela *, enum elf_nds32_reloc_type);
 static bfd_vma calculate_memory_address
 (bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *);
 static int nds32_get_section_contents (bfd *, asection *,
@@ -134,13 +86,6 @@ static bfd_boolean  nds32_relax_fp_as_gp
 static bfd_boolean nds32_fag_remove_unused_fpbase
   (bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs,
    Elf_Internal_Rela *irelend);
-static bfd_byte *
-nds32_elf_get_relocated_section_contents (bfd *abfd,
-					  struct bfd_link_info *link_info,
-					  struct bfd_link_order *link_order,
-					  bfd_byte *data,
-					  bfd_boolean relocatable,
-					  asymbol **symbols);
 
 enum
 {
@@ -3561,6 +3506,22 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_nds32_dyn_relocs *p;
+
+  for (p = elf32_nds32_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
 
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
@@ -3893,31 +3854,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 elf_nds32_link_hash_entry *eh;
-  struct elf_nds32_dyn_relocs *p;
+  asection *sec;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-  eh = (struct elf_nds32_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
     {
-      asection *s = p->sec->output_section;
-
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	{
-	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+      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;
 }
@@ -4113,7 +4072,7 @@ nds32_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->root, readonly_dynrelocs,
+	    elf_link_hash_traverse (&htab->root, maybe_set_textrel,
 				    (void *) info);
 
 	  if ((info->flags & DF_TEXTREL) != 0)
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index c12dea4..03accf7 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -1921,6 +1921,24 @@ or1k_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
     }
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_or1k_dyn_relocs *p;
+  struct elf_or1k_link_hash_entry *eh = (struct elf_or1k_link_hash_entry *) h;
+
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2264,28 +2282,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 elf_or1k_link_hash_entry *eh;
-  struct elf_or1k_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct elf_or1k_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;
 }
@@ -2499,8 +2518,7 @@ or1k_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->root, readonly_dynrelocs,
-                                   info);
+           elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
 
          if ((info->flags & DF_TEXTREL) != 0)
            {
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 80454eb..bd5cc5c 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -6153,8 +6153,8 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 
       info->flags |= DF_TEXTREL;
       info->callbacks->minfo
-	(_("%B: dynamic relocation in read-only section `%A'\n"),
-	 sec->owner, sec);
+	(_("%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;
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index d073ea2..b0f8752 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -1419,6 +1419,23 @@ elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h)
   h->gotplt_refcount = -1;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+
+  for (p = elf_s390_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -1827,28 +1844,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 elf_s390_link_hash_entry *eh;
-  struct elf_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct elf_s390_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;
 }
@@ -2076,7 +2094,7 @@ elf_s390_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) != 0)
 	    {
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index e451bb6..0ff6a1b 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -2795,6 +2795,23 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   return TRUE;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_sh_dyn_relocs *p;
+
+  for (p = sh_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -3282,31 +3299,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 elf_sh_link_hash_entry *eh;
-  struct elf_sh_dyn_relocs *p;
-
-  eh = (struct elf_sh_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
+  asection *sec;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	{
-	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-	  info->flags |= DF_TEXTREL;
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
+    {
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-	  info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"),
-				  p->sec->owner, p->sec);
+      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;
 }
@@ -3630,7 +3645,7 @@ sh_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->root, readonly_dynrelocs, info);
+	    elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
 
 	  if ((info->flags & DF_TEXTREL) != 0)
 	    {
diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c
index 8575a26..fccfb42 100644
--- a/bfd/elf32-tic6x.c
+++ b/bfd/elf32-tic6x.c
@@ -1971,6 +1971,25 @@ elf32_tic6x_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
   return TRUE;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+  struct elf32_tic6x_link_hash_entry *eh
+    = (struct elf32_tic6x_link_hash_entry *) h;
+
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -3165,28 +3184,29 @@ elf32_tic6x_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
-elf32_tic6x_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 {
-  struct elf32_tic6x_link_hash_entry *eh;
-  struct elf_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct elf32_tic6x_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;
 }
@@ -3404,8 +3424,7 @@ elf32_tic6x_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  /* 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,
-				    elf32_tic6x_readonly_dynrelocs, info);
+	    elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
 
 	  if ((info->flags & DF_TEXTREL) != 0)
 	    {
diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c
index 9643e70..521ee37 100644
--- a/bfd/elf32-tilepro.c
+++ b/bfd/elf32-tilepro.c
@@ -1889,6 +1889,23 @@ tilepro_elf_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct tilepro_elf_dyn_relocs *p;
+
+  for (p = tilepro_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2229,31 +2246,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 tilepro_elf_link_hash_entry *eh;
-  struct tilepro_elf_dyn_relocs *p;
-
-  eh = (struct tilepro_elf_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
+  asection *sec;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	{
-	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-	  info->flags |= DF_TEXTREL;
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
+    {
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-	  info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"),
-				  p->sec->owner, p->sec);
+      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;
 }
@@ -2504,7 +2519,7 @@ tilepro_elf_size_dynamic_sections (bfd *output_bfd,
       /* 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)
 	{
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index b7f4029..b0fc020 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -9890,8 +9890,8 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
 
       info->flags |= DF_TEXTREL;
       info->callbacks->minfo
-	(_("%B: dynamic relocation in read-only section `%A'\n"),
-	 sec->owner, sec);
+	(_("%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;
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 0329c16..6c53ed3 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -1351,6 +1351,23 @@ elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h)
   h->gotplt_refcount = -1;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+
+  for (p = elf_s390_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -1763,28 +1780,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h,
   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 elf_s390_link_hash_entry *eh;
-  struct elf_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct elf_s390_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;
 }
@@ -2016,8 +2034,7 @@ elf_s390_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) != 0)
 	    {
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 7f50f77..a4ee136 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -6693,6 +6693,23 @@ elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
   return TRUE;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+
+  for (p = elf_aarch64_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Return true if we need copy relocation against EH.  */
 
 static bfd_boolean
@@ -8260,28 +8277,29 @@ elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
   return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
 }
 
-/* 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
-aarch64_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 {
-  struct elf_aarch64_link_hash_entry * eh;
-  struct elf_dyn_relocs * p;
+  asection *sec;
 
-  eh = (struct elf_aarch64_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec;
+  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;
 }
@@ -8576,8 +8594,7 @@ elfNN_aarch64_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->root, aarch64_readonly_dynrelocs,
-				    info);
+	    elf_link_hash_traverse (&htab->root, maybe_set_textrel, info);
 
 	  if ((info->flags & DF_TEXTREL) != 0)
 	    {
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 6a56174..47d2c47 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -757,6 +757,23 @@ riscv_elf_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct riscv_elf_dyn_relocs *p;
+
+  for (p = riscv_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -1102,24 +1119,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 riscv_elf_link_hash_entry *eh;
-  struct riscv_elf_dyn_relocs *p;
+  asection *sec;
 
-  eh = (struct riscv_elf_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
+
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
     {
-      asection *s = p->sec->output_section;
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	{
-	  ((struct bfd_link_info *) inf)->flags |= DF_TEXTREL;
-	  return FALSE;
-	}
+      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;
     }
   return TRUE;
 }
@@ -1329,7 +1351,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       /* 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)
 	{
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 13aa6c5..89b9a0e 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -1969,6 +1969,23 @@ _bfd_sparc_elf_fixup_symbol (struct bfd_link_info *info,
   return TRUE;
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct _bfd_sparc_elf_dyn_relocs *p;
+
+  for (p = _bfd_sparc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2449,31 +2466,29 @@ allocate_local_dynrelocs (void **slot, void *inf)
   return allocate_dynrelocs (h, inf);
 }
 
-/* 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 _bfd_sparc_elf_link_hash_entry *eh;
-  struct _bfd_sparc_elf_dyn_relocs *p;
-
-  eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
+  asection *sec;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	{
-	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-	  info->flags |= DF_TEXTREL;
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
+    {
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-	  info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"),
-				  p->sec->owner, p->sec);
+      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;
 }
@@ -2732,7 +2747,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
       /* 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)
 	{
diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c
index 5f6622a..19c5541 100644
--- a/bfd/elfxx-tilegx.c
+++ b/bfd/elfxx-tilegx.c
@@ -2128,6 +2128,23 @@ tilegx_elf_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct tilegx_elf_dyn_relocs *p;
+
+  for (p = tilegx_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	return p->sec;
+    }
+  return NULL;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2471,31 +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;
-
-  eh = (struct tilegx_elf_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
+  asection *sec;
 
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	{
-	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-	  info->flags |= DF_TEXTREL;
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
+    {
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-	  info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"),
-				  p->sec->owner, p->sec);
+      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;
 }
@@ -2740,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)
 	{
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 51d50d1..0729d21 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2017-12-01  Alan Modra  <amodra@gmail.com>
+
+	* testsuite/ld-elf/shared.exp: Run new textrel tests.
+	* testsuite/ld-elf/textrel.map: New file.
+	* testsuite/ld-elf/textrel.rd: New file.
+	* testsuite/ld-elf/textrel.s: New file.
+	* testsuite/ld-elf/textrel.warn: New file.
+
 2017-11-30  Alan Modra  <amodra@gmail.com>
 
 	PR 22471
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 99c34be..cc145b4 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -83,6 +83,31 @@ run_ld_link_tests [list \
     ] \
 ]
 
+run_ld_link_tests [list \
+    [list \
+	"DT_TEXTREL in shared lib" \
+	"$LFLAGS -shared --warn-shared-textrel" \
+	"" \
+	"$AFLAGS_PIC" \
+	{textrel.s} \
+	 {{ld textrel.warn} \
+	  {readelf {-d --wide} textrel.rd}} \
+	"textrel.so" \
+    ] \
+] "xtensa-*-*"
+
+run_ld_link_tests [list \
+    [list \
+	"DT_TEXTREL map file warning" \
+	"$LFLAGS -shared -M" \
+	"" \
+	"$AFLAGS_PIC" \
+	{textrel.s} \
+	 {{ld textrel.map}} \
+	"textrel.so" \
+    ] \
+] "cris*-*-*"
+
 # PR ld/20828 check for correct dynamic symbol table entries where:
 # - symbols have been defined with a linker script,
 # - the same symbols have been seen in shared library used in the link,
diff --git a/ld/testsuite/ld-elf/textrel.map b/ld/testsuite/ld-elf/textrel.map
new file mode 100644
index 0000000..fa33113
--- /dev/null
+++ b/ld/testsuite/ld-elf/textrel.map
@@ -0,0 +1,3 @@
+#...
+.*dynamic relocation .* read-only section.*
+#pass
diff --git a/ld/testsuite/ld-elf/textrel.rd b/ld/testsuite/ld-elf/textrel.rd
new file mode 100644
index 0000000..cc270df
--- /dev/null
+++ b/ld/testsuite/ld-elf/textrel.rd
@@ -0,0 +1,3 @@
+#...
+.*\(TEXTREL\).*
+#pass
diff --git a/ld/testsuite/ld-elf/textrel.s b/ld/testsuite/ld-elf/textrel.s
new file mode 100644
index 0000000..b4bfb58
--- /dev/null
+++ b/ld/testsuite/ld-elf/textrel.s
@@ -0,0 +1,5 @@
+ .section .rodata,"a",%progbits
+ .global pfoo, foo
+pfoo:
+ .dc.a foo
+foo:
diff --git a/ld/testsuite/ld-elf/textrel.warn b/ld/testsuite/ld-elf/textrel.warn
new file mode 100644
index 0000000..51d9ca8
--- /dev/null
+++ b/ld/testsuite/ld-elf/textrel.warn
@@ -0,0 +1,3 @@
+#...
+.*warning:.*DT_TEXTREL.*
+#pass

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]