This is the mail archive of the binutils@sources.redhat.com 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]

Don't set DT_TEXTREL flag for Xtensa


Use of the DT_TEXTREL dynamic entry for Xtensa shared objects is not compatible with the way the Xtensa runtime loader handles literal pools. The literal pools are located within the text section, and the loader reads a special "literal table" to locate the literal pools and make them writable. If the DT_TEXTREL flag is set, the entire text section reverts to being read-only after the initial relocations have been performed, thereby undoing the protection changes for pages containing literal pools. This problem went undetected for quite a while because it was masked by a bug in the Xtensa port of the 2.4 Linux kernel.

This patch changes the assembler to always emit literal table entries, even when using the --text-section-literals assembler option. The previous plan was to handle --text-section-literals by setting DT_TEXTREL. With this patch, code assembled with --text-section-literals will at least work, even if the literal tables are larger than one would like. I'm not very concerned about this because it doesn't really make much sense to use --text-section-literals on a system with shared objects, anyway. I'm thinking of some ways to clean this up in the longer term.

The patch also changes the linker to make it stop setting DT_TEXTREL when it encounters a relocation on a read-only section and outside a literal pool. Instead, it now checks the literal tables when emitting dynamic relocations, and if there is a dynamic relocation outside a literal pool, it is treated as an error.

I tested this by running the testsuite with an xtensa-elf target (no shared libraries), and by building glibc and booting a board with it. Committed on the mainline and 2.15 branch.


bfd/ChangeLog:


	* elf32-xtensa.c (elf_xtensa_check_relocs): Remove code to read
	literal tables and check for relocs outside of literal pools.
	(elf_xtensa_make_sym_local): Don't clear ELF_LINK_NON_GOT_REF flag.
	(elf_xtensa_fix_refcounts): Don't check ELF_LINK_NON_GOT_REF or
	set DF_TEXTREL.
	(elf_xtensa_size_dynamic_sections): Don't add DT_TEXTREL entry.
	(elf_xtensa_relocate_section): Read literal tables and check for
	dynamic relocations in read-only sections and not in literal pools.

gas/ChangeLog:

	* config/tc-xtensa.c (xtensa_post_relax_hook): Create literal
	tables even when use_literal_section flag is not set.


Index: elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.21
diff -u -p -r1.21 elf32-xtensa.c
--- elf32-xtensa.c	22 Mar 2004 02:28:17 -0000	1.21
+++ elf32-xtensa.c	23 Mar 2004 01:12:12 -0000
@@ -619,8 +619,6 @@ elf_xtensa_check_relocs (abfd, info, sec
   struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
-  property_table_entry *lit_table;
-  int ltblsize;
 
   if (info->relocatable)
     return TRUE;
@@ -628,11 +626,6 @@ elf_xtensa_check_relocs (abfd, info, sec
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
 
-  ltblsize = xtensa_read_table_entries (abfd, sec, &lit_table,
-					XTENSA_LIT_SEC_NAME);
-  if (ltblsize < 0)
-    return FALSE;
-
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
@@ -669,11 +662,6 @@ elf_xtensa_check_relocs (abfd, info, sec
 
 	  if ((sec->flags & SEC_ALLOC) != 0)
 	    {
-	      if ((sec->flags & SEC_READONLY) != 0
-		  && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
-						  sec->vma + rel->r_offset))
-		h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
 	      if (h->got.refcount <= 0)
 		h->got.refcount = 1;
 	      else
@@ -689,11 +677,6 @@ elf_xtensa_check_relocs (abfd, info, sec
 
 	  if ((sec->flags & SEC_ALLOC) != 0)
 	    {
-	      if ((sec->flags & SEC_READONLY) != 0
-		  && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
-						  sec->vma + rel->r_offset))
-		h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
 	      if (h->plt.refcount <= 0)
 		{
 		  h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
@@ -736,14 +719,6 @@ elf_xtensa_check_relocs (abfd, info, sec
 		  elf_local_got_refcounts (abfd) = local_got_refcounts;
 		}
 	      local_got_refcounts[r_symndx] += 1;
-
-	      /* If the relocation is not inside the GOT, the DF_TEXTREL
-		 flag needs to be set.  */
-	      if (info->shared
-		  && (sec->flags & SEC_READONLY) != 0
-		  && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
-						  sec->vma + rel->r_offset))
-		info->flags |= DF_TEXTREL;
 	    }
 	  break;
 
@@ -774,7 +749,6 @@ elf_xtensa_check_relocs (abfd, info, sec
 	}
     }
 
-  free (lit_table);
   return TRUE;
 }
 
@@ -1044,7 +1018,6 @@ elf_xtensa_make_sym_local (info, h)
   else
     {
       /* Don't need any dynamic relocations at all.  */
-      h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
       h->plt.refcount = 0;
       h->got.refcount = 0;
     }
@@ -1064,11 +1037,6 @@ elf_xtensa_fix_refcounts (h, arg)
   if (! xtensa_elf_dynamic_symbol_p (h, info))
     elf_xtensa_make_sym_local (info, h);
 
-  /* If the symbol has a relocation outside the GOT, set the
-     DF_TEXTREL flag.  */
-  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) != 0)
-    info->flags |= DF_TEXTREL;
-
   return TRUE;
 }
 
@@ -1391,12 +1359,6 @@ elf_xtensa_size_dynamic_sections (output
 	    return FALSE;
 	}
 
-      if ((info->flags & DF_TEXTREL) != 0)
-	{
-	  if (!add_dynamic_entry (DT_TEXTREL, 0))
-	    return FALSE;
-	}
-
       if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
 	  || !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
 	return FALSE;
@@ -1851,6 +1813,8 @@ elf_xtensa_relocate_section (output_bfd,
   struct elf_link_hash_entry **sym_hashes;
   asection *srelgot, *srelplt;
   bfd *dynobj;
+  property_table_entry *lit_table = 0;
+  int ltblsize = 0;
   char *error_message = NULL;
 
   if (xtensa_default_isa == NULL)
@@ -1868,6 +1832,14 @@ elf_xtensa_relocate_section (output_bfd,
       srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
     }
 
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      ltblsize = xtensa_read_table_entries (input_bfd, input_section,
+					    &lit_table, XTENSA_LIT_SEC_NAME);
+      if (ltblsize < 0)
+	return FALSE;
+    }
+
   rel = relocs;
   relend = relocs + input_section->reloc_count;
   for (; rel < relend; rel++)
@@ -2068,6 +2040,21 @@ elf_xtensa_relocate_section (output_bfd,
 		  outrel.r_offset += (input_section->output_section->vma
 				      + input_section->output_offset);
 
+		  /* Complain if the relocation is in a read-only section
+		     and not in a literal pool.  */
+		  if ((input_section->flags & SEC_READONLY) != 0
+		      && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+						      input_section->vma
+						      + rel->r_offset))
+		    {
+		      error_message =
+			_("dynamic relocation in read-only section");
+		      if (!((*info->callbacks->reloc_dangerous)
+			    (info, error_message, input_bfd, input_section,
+			     rel->r_offset)))
+			return FALSE;
+		    }
+
 		  if (dynamic_symbol)
 		    {
 		      outrel.r_addend = rel->r_addend;
@@ -2154,6 +2141,9 @@ elf_xtensa_relocate_section (output_bfd,
 	    return FALSE;
 	}
     }
+
+  if (lit_table)
+    free (lit_table);
 
   return TRUE;
 }
Index: config/tc-xtensa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.c,v
retrieving revision 1.8
diff -u -p -r1.8 tc-xtensa.c
--- config/tc-xtensa.c	19 Mar 2004 22:35:32 -0000	1.8
+++ config/tc-xtensa.c	22 Mar 2004 20:01:46 -0000
@@ -7888,10 +7888,9 @@ xtensa_post_relax_hook ()
   xtensa_create_property_segments (get_frag_is_insn,
 				   XTENSA_INSN_SEC_NAME,
 				   xt_insn_sec);
-  if (use_literal_section)
-    xtensa_create_property_segments (get_frag_is_literal,
-				     XTENSA_LIT_SEC_NAME,
-				     xt_literal_sec);
+  xtensa_create_property_segments (get_frag_is_literal,
+				   XTENSA_LIT_SEC_NAME,
+				   xt_literal_sec);
 }
 
 

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