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: elf64-ppc.c *r_offset patch


On Mon, Jun 16, 2003 at 10:04:48AM +0200, Jakub Jelinek wrote:
> On Mon, Jun 16, 2003 at 01:38:39PM +0930, Alan Modra wrote:
> > Jakub found an error in handling of DTPMOD dynamic relocs, and we've
> > been throwing patches at each other over the weekend with the aim of
> > making prelink work on powerpc64.  It's perhaps a little early to apply
> > this one, as we haven't quite finished arguing. :)  Maybe I'm missing
> > some prelink requirement, but I guess the rest of the discussion can
> > occur on the mailing list.  The prelink aspect of the patch arranges for
> > section contents at r_offset to be written equal to r_addend for
> > R_PPC64_RELATIVE relocs, and to zero for other reloc types.  We need
> > RELATIVE relocs to be applied like this in the .opd section to suit the
> > way our ld.so works, the choice for other relocs is somewhat arbitrary.
> 
> For the sake of prelinking existing ppc64 binaries and libraries, I'd
> appreciate if R_PPC64_ADDR64 could be *r_offset == r_addend as well,
> the rest can be set to 0 if you prefer.
> A little background why prelink needs this:
> prelink supports --undo and --verify switches. The former is supposed to
> be bitwise exact copy of the binary or library before prelinking, the latter
> effectively does an --undo operation followed by normal prelink operation
> and checks whether the result is identical with the library/binary before
> --undo and gives the unprelinked file image to the verificating utility.
> As prelink does not want to bloat the binary/library unnecessarily and has
> to overwrite *r_offset with the final resolved addresses in prelinked
> program, it needs a way to compute the content of *r_offset during --undo
> from the things which are the same in prelinked and non-prelinked image,
> like relocation type, section r_offset is in, r_addend, etc.

Good, I did understand the situation correctly.

> Now, when I checked around a thousand of ppc64 binaries/libraries, I found
> with the exception of glibc only R_PPC64_JMP_SLOT, R_PPC64_ADDR64, R_PPC64_COPY
> and R_PPC64_RELATIVE relocations in use. R_PPC64_JMP_SLOT is uninteresting here,
> as in unprelinked binaries/libraries .plt section is SHT_NOBITS, which
> means *r_offset is 0. R_PPC64_RELATIVE and R_PPC64_ADDR64 relocs followed
> in all binaries/libraries I checked *r_offset == r_addend (again, with
> exception of glibc, where some R_PPC64_RELATIVE relocs against .got section
> had *r_offset == 0 && r_addend != 0).
> So, if R_PPC64_ADDR64 would be now *r_offset == 0, newly linked
> binaries/libraries can be prelinked and prelink --undo'ed just fine, while
> all current binaries/libraries can be prelinked but --undo will give
> different bits (e.g. package management programs might complain, etc.).
> 
> > @@ -8315,9 +8329,14 @@ ppc64_elf_relocate_section (output_bfd, 
> >  
> >  	      /* If this reloc is against an external symbol, it will
> >  		 be computed at runtime, so there's no need to do
> > -		 anything now.  */
> > +		 anything now.  However, for the sake of prelink ensure
> > +		 that the section contents are a known value.  */
> >  	      if (! relocate)
> > -		continue;
> > +		{
> > +		  relocation = 0;
> > +		  addend = 0;
> > +		  unresolved_reloc = FALSE;
> > +		}
> 
> Will this handle pc relative relocs correctly?
> Stuff like:
> echo '.data; .8byte foo + 128 - .' > test.s
> gcc -shared -o test.so test.s -nostdlib

Sure.  Since we are RELA, the section contents can be ignored by ld.so.
We do this except for the special case of .opd, where we might access
the section contents before they have been relocated (and we know all
.opd relocs are R_PPC64_RELATIVE).  See elf_machine_fixup_plt.

If we want R_PPC64_ADDR64 to have *r_offset == r_addend, it's just a
matter of adding

		  if (r_type == R_PPC64_ADDR64)
		    addend = outrel.r_addend;

in the hunk you quote above.  I suppose that's not too big a price to
pay for improved backward compatibility.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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