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]

sparc64 solaris different-brokenness patch



The original reason for this line (in the sparc32, ppc, and probably
dozens of other backends) is that it's a workaround for a bug in the
sparc solaris ld.so.  The correct way to process a R_*_RELATIVE RELA
reloc is to compute:

(base address of shared object) + addend

and stuff that into the location being relocated.  The sparc32 Solaris
ld.so does:

(base address of shared object) + (contents of location being relocated)

so we have to put a copy of the addend at the location being
relocated.

The sparc64 Solaris ld.so does

(base address of shared object) + addend + (contents of location being relocated)

which is still wrong, but differently wrong, and the old work-around
won't work (we get the addend twice).  So we use a new work-around.

OK to commit?

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/sparc64-relative.patch=============
2000-08-30  Geoffrey Keating  <geoffk@cygnus.com>

	* elf64-sparc.c (sparc64_elf_relocate_section): Clear the location
	of a GOT reloc.

Index: elf64-sparc.c
===================================================================
RCS file: /cvs/cvsfiles/devo/bfd/elf64-sparc.c,v
retrieving revision 1.48.2.2
diff -c -r1.48.2.2 elf64-sparc.c
*** elf64-sparc.c	2000/08/14 20:06:33	1.48.2.2
--- elf64-sparc.c	2000/08/31 03:23:54
***************
*** 2356,2362 ****
  		off &= ~1;
  	      else
  		{
- 		  bfd_put_64 (output_bfd, relocation, sgot->contents + off);
  		  local_got_offsets[r_symndx] |= 1;
  
  		  if (info->shared)
--- 2356,2361 ----
***************
*** 2364,2369 ****
--- 2363,2375 ----
  		      asection *srelgot;
  		      Elf_Internal_Rela outrel;
  
+ 		      /* The Solaris 2.7 64-bit linker adds the contents
+ 			 of the location to the value of the reloc.
+ 			 Note this is different behaviour to the
+ 			 32-bit linker, which both adds the contents
+ 			 and ignores the addend.  So clear the location.  */
+ 		      bfd_put_64 (output_bfd, 0, sgot->contents + off);
+ 		      
  		      /* We need to generate a R_SPARC_RELATIVE reloc
  			 for the dynamic linker.  */
  		      srelgot = bfd_get_section_by_name(dynobj, ".rela.got");
***************
*** 2380,2385 ****
--- 2386,2393 ----
  						  + srelgot->reloc_count));
  		      ++srelgot->reloc_count;
  		    }
+ 		  else
+ 		    bfd_put_64 (output_bfd, relocation, sgot->contents + off);
  		}
  	      relocation = sgot->output_offset + off - got_base;
  	    }
============================================================

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