This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: Reloc changes to bfd/elf32-mips.c
> Mailing-List: contact binutils-help@sourceware.cygnus.com; run by ezmlm
> List-Unsubscribe: <mailto:binutils-unsubscribe-geoffk=cygnus.com@sourceware.cygnus.com>
> List-Subscribe: <mailto:binutils-subscribe@sourceware.cygnus.com>
> List-Archive: <http://sourceware.cygnus.com/ml/binutils/>
> List-Post: <mailto:binutils@sourceware.cygnus.com>
> List-Help: <mailto:binutils-help@sourceware.cygnus.com>, <http://sourceware.cygnus.com/ml/#faqs>
> Date: 28 Sep 1999 23:55:39 -0400
> From: Ian Lance Taylor <ian@zembu.com>
> CC: mark@codesourcery.com, gavin@cygnus.com, binutils@sourceware.cygnus.com,
> brendan@cygnus.com
>
> Date: Wed, 29 Sep 1999 13:30:48 +1000
> From: Geoff Keating <geoffk@ozemail.com.au>
>
> > From: Mark Mitchell <mark@codesourcery.com>
> > Date: Tue, 28 Sep 1999 00:59:56 -0700
> >
> > I'm confused on a couple of points.
> >
> > @@ -6557,6 +6556,7 @@ _bfd_mips_elf_relocate_section (output_b
> > int r_type = ELF32_R_TYPE (rel->r_info);
> >
> > /* Find the relocation howto for this relocation. */
> > +#ifndef BFD64
> > if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd))
> > /* Some 32-bit code uses R_MIPS_64. In particular, people use
> > 64-bit code, but make sure all their addresses are in the
> > @@ -6566,6 +6566,7 @@ _bfd_mips_elf_relocate_section (output_b
> > stored value is sign-extended to 64 bits. */
> > howto = elf_mips_howto_table + R_MIPS_32;
> > else
> > +#endif
> > howto = mips_rtype_to_howto (r_type);
> >
> > That's fine by me, in that I never understood exactly what was going
> > on there. But, I don't think it's right. The idea here is that
> > 32-bit object code can still use R_MIPS_64, according to Ian. So, I
> > don't think BFD64 (which says something about how many bits you have
> > when you're compiling BFD) is the right thing.
>
> What I think this code was trying to do was make a R_MIPS_64 reloc
> work when you have a 32-bit BFD.
>
> To be precise, this code was trying to make a R_MIPS_64 reloc work
> when using 32 bit MIPS ELF.
>
> I invented it because we had 64 bit MIPS chips, but we only supported
> the 32 bit MIPS ELF format. Since the compiler was generating 64 bit
> address loads, we needed to have some way to get the right value in a
> relocation. Of course, since we were using a 32 bit object file
> format, the correct value was always 32 bits. The relocation made
> sure that it was sign extended correctly.
Yes.
> If you have a 64-bit BFD, none of
> this is necessary, and you can just do the right thing. The object
> format size is irrelevant, you'd have to do a similar thing to make a
> R_MIPS_64 reloc work in an elf64 file with a 32-bit BFD (but you'd have
> to do many many other things too).
>
> I don't see why it matters whether you have a 64 bit BFD. What
> matters is how you compute the relocation.
If you have a 32-bit BFD, you can't ask it to load a 64-bit value out
of memory into a bfd_vma; it will abort.
> Since this is a 32 bit object file format, all the values going into
> this computation are 32 bit values. The correct way to compute the
> value is to compute the 32 bit relocation, and to sign extend the 32
> bit result to 64 bits when storing it in memory.
The addend is stored as a 64-bit value. I don't know if it should be
considered to have all 64 bits significant (at present it isn't), but
it's still 8 bytes long.
> This is a target calculation. It's not immediately obvious why it
> should depend upon the host facilities in any way.
Certainly, you should get the same result. You may need to get the
result in a different way in a 32-bit BFD.
> The original code used the R_MIPS_32 howto for a R_MIPS_64 reloc, but
> if you do that the addend gets computed wrong in big-endian files
> because BFD thinks the addend is 32 bits long and only sees the high
> 32 bits which are not usually helpful.
>
> Before Mark's rewrite, the code handled this correctly in
> mips_elf_relocate_section:
>
> if (r_type == R_MIPS_64 && bfd_big_endian (input_bfd))
> r = _bfd_relocate_contents (howto, input_bfd,
> addend,
> contents + rel->r_offset + 4);
>
> Perhaps this got dropped somewhere along the way.
It seems so.
--
Geoffrey Keating <geoffk@cygnus.com>