From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Lance Taylor To: geoffk@ozemail.com.au Cc: mark@codesourcery.com, gavin@cygnus.com, binutils@sourceware.cygnus.com, brendan@cygnus.com Subject: Re: Reloc changes to bfd/elf32-mips.c Date: Tue, 28 Sep 1999 20:57:00 -0000 Message-id: <19990929035539.20417.qmail@daffy.airs.com> References: <199909271118.VAA01663@gluttony.geoffk.wattle.id.au> <19990928005956V.mitchell@codesourcery.com> <199909290330.NAA00657@gluttony.geoffk.wattle.id.au> X-SW-Source: 1999-09/msg00195.html Date: Wed, 29 Sep 1999 13:30:48 +1000 From: Geoff Keating > From: Mark Mitchell > 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. 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. 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. This is a target calculation. It's not immediately obvious why it should depend upon the host facilities in any way. 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. Ian