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]

Re: R_SPARC_RELATIVE vs R_SPARC_UA32 & unaligned unwind tables - again


On Tue, Dec 18, 2001 at 11:58:17PM -0500, DJ Delorie wrote:
> 
> > OK, so you're using Sun's libc and ld.so.  Smells like a bug in their
> > ld.so, as the testcase objects look good to me.
> 
> Present in 2.5.1, 2.6, and fixed in 2.7, and 2.8 if so.  The 2.5.1
> test binary/so work fine in 2.7 and 2.8.
> 
> Sigh.  That means I can't fix it...

Yes you can.

> >  For amusement, see what happens if you poke some non-zero values in
> > libdj-s.so's image .data for "y".
> 
> It twiddles the result accordingly.

And this is why it can be fixed.  All that needs to be done is for the
relocation to be applied to the section contents.  The following might
need some tweaking (eg. you've already said my "wild guess" patch didn't
work, although I'm still of the opinion it's logically correct) to suit
any further bugs you might find in Sun's dynamic linkers, but the general
idea ought to work.  The beauty is that changing the section contents
won't break dynamic linkers that behave correctly.

Index: elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.34
diff -u -p -r1.34 elf32-sparc.c
--- elf32-sparc.c	2001/12/17 00:52:35	1.34
+++ elf32-sparc.c	2001/12/19 06:58:44
@@ -1415,6 +1415,7 @@ elf32_sparc_relocate_section (output_bfd
 	    {
 	      Elf_Internal_Rela outrel;
 	      boolean skip;
+	      boolean relocate;
 
 	      /* When generating a shared object, these relocations
                  are copied into the output file to be resolved at run
@@ -1449,6 +1450,7 @@ elf32_sparc_relocate_section (output_bfd
 		skip = true;
 	      outrel.r_offset += (input_section->output_section->vma
 				  + input_section->output_offset);
+	      outrel.r_addend = rel->r_addend;
 
 	      /* Optimize unaligned reloc usage now that we know where
 		 it finally resides.  */
@@ -1472,6 +1474,7 @@ elf32_sparc_relocate_section (output_bfd
 		  break;
 		}
 
+	      relocate = false;
 	      if (skip)
 		memset (&outrel, 0, sizeof outrel);
 	      /* h->dynindx may be -1 if the symbol was marked to
@@ -1483,14 +1486,15 @@ elf32_sparc_relocate_section (output_bfd
 		{
 		  BFD_ASSERT (h->dynindx != -1);
 		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
-		  outrel.r_addend = rel->r_addend;
 		}
 	      else
 		{
+		  relocate = true;
+		  outrel.r_addend += relocation;
+
 		  if (r_type == R_SPARC_32)
 		    {
 		      outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
-		      outrel.r_addend = relocation + rel->r_addend;
 		    }
 		  else
 		    {
@@ -1505,6 +1509,7 @@ elf32_sparc_relocate_section (output_bfd
 					  == bfd_link_hash_defweak));
 			  sec = h->root.u.def.section;
 			}
+
 		      if (sec != NULL && bfd_is_abs_section (sec))
 			indx = 0;
 		      else if (sec == NULL || sec->owner == NULL)
@@ -1530,10 +1535,16 @@ elf32_sparc_relocate_section (output_bfd
 			      bfd_set_error (bfd_error_bad_value);
 			      return false;
 			    }
+
+			  /* We are turning this relocation into one
+			     against a section symbol, so subtract out
+			     the output section's address but not the
+			     offset of the input section in the output
+			     section.  */
+			  outrel.r_addend -= osec->vma;
 			}
 
 		      outrel.r_info = ELF32_R_INFO (indx, r_type);
-		      outrel.r_addend = relocation + rel->r_addend;
 		    }
 		}
 
@@ -1544,8 +1555,11 @@ elf32_sparc_relocate_section (output_bfd
 	      ++sreloc->reloc_count;
 
 	      /* This reloc will be computed at runtime, so there's no
-                 need to do anything now.  */
-	      continue;
+                 need to do anything now.  Sigh, except that the Solaris
+		 2.5.1 and 2.6 dynamic linker use the section contents when
+		 relocating dynamic relocs against local symbols.  */
+	      if (!relocate)
+		continue;
 	    }
 	  break;
 


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