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]

fix Xtensa regression in bfd


One of my recent changes (http://sources.redhat.com/ml/binutils/2004-03/msg00511.html) causes problems with the linker. The symptoms didn't show up until I tried building a different version of glibc. The issue is that the xtensa_read_table_entries function was formerly called during the ELF check_relocs hook, but I changed it to be called during the relocate_section hook. I failed to account for the fact that when called from relocate_section, the table section may have been relaxed and/or relocated (depending on the order in which sections are relocated). This patch fixes the problems I found building glibc. It uses the section reloc_done flag to mark whether a table section has been relocated yet. (This flag doesn't seem to be set in most of the places where I would expect it to be set; I hope I'm not misusing it.)

I tested this by running the testsuite for an xtensa-elf target and by building glibc 2.3.2 with an xtensa-linux-gnu target. Committed on the mainline and 2.15 branch.


2004-04-27 Bob Wilson <bob.wilson@acm.org>


	* elf32-xtensa.c (xtensa_read_table_entries): Use section _cooked_size
	if set.  Check reloc_done flag before applying relocations.  Use
	output addresses, both when applying relocations and when comparing
	against the specified section.
	(elf_xtensa_relocate_section): Use output address to check if dynamic
	reloc is in a literal pool.  Set section's reloc_done flag.

Index: elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.25
diff -u -p -r1.25 elf32-xtensa.c
--- elf32-xtensa.c	21 Apr 2004 18:12:47 -0000	1.25
+++ elf32-xtensa.c	27 Apr 2004 17:25:25 -0000
@@ -497,13 +497,15 @@ xtensa_read_table_entries (abfd, section
   int block_count;
   bfd_size_type num_records;
   Elf_Internal_Rela *internal_relocs;
+  bfd_vma section_addr;
 
   table_section_name = 
     xtensa_get_property_section_name (section, sec_name);
   table_section = bfd_get_section_by_name (abfd, table_section_name);
   free (table_section_name);
   if (table_section != NULL)
-    table_size = bfd_get_section_size_before_reloc (table_section);
+    table_size = (table_section->_cooked_size
+		  ? table_section->_cooked_size : table_section->_raw_size);
   
   if (table_size == 0) 
     {
@@ -517,10 +519,12 @@ xtensa_read_table_entries (abfd, section
     bfd_malloc (num_records * sizeof (property_table_entry));
   block_count = 0;
   
+  section_addr = section->output_section->vma + section->output_offset;
+
   /* If the file has not yet been relocated, process the relocations
      and sort out the table entries that apply to the specified section.  */
   internal_relocs = retrieve_internal_relocs (abfd, table_section, TRUE);
-  if (internal_relocs)
+  if (internal_relocs && !table_section->reloc_done)
     {
       unsigned i;
 
@@ -539,7 +543,7 @@ xtensa_read_table_entries (abfd, section
 	    {
 	      bfd_vma sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
 	      blocks[block_count].address =
-		(section->vma + sym_off + rel->r_addend
+		(section_addr + sym_off + rel->r_addend
 		 + bfd_get_32 (abfd, table_data + rel->r_offset));
 	      blocks[block_count].size =
 		bfd_get_32 (abfd, table_data + rel->r_offset + 4);
@@ -549,16 +553,16 @@ xtensa_read_table_entries (abfd, section
     }
   else
     {
-      /* No relocations.  Presumably the file has been relocated
-	 and the addresses are already in the table.  */
+      /* The file has already been relocated and the addresses are
+	 already in the table.  */
       bfd_vma off;
 
       for (off = 0; off < table_size; off += 8) 
 	{
 	  bfd_vma address = bfd_get_32 (abfd, table_data + off);
 
-	  if (address >= section->vma
-	      && address < ( section->vma + section->_raw_size))
+	  if (address >= section_addr
+	      && address < ( section_addr + section->_raw_size))
 	    {
 	      blocks[block_count].address = address;
 	      blocks[block_count].size =
@@ -2044,8 +2048,7 @@ elf_xtensa_relocate_section (output_bfd,
 		     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))
+						      outrel.r_offset))
 		    {
 		      error_message =
 			_("dynamic relocation in read-only section");
@@ -2144,6 +2147,8 @@ elf_xtensa_relocate_section (output_bfd,
 
   if (lit_table)
     free (lit_table);
+
+  input_section->reloc_done = TRUE;
 
   return TRUE;
 }

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