From mboxrd@z Thu Jan 1 00:00:00 1970 From: Geoff Keating To: mark@codesourcery.com Cc: 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:32:00 -0000 Message-id: <199909290330.NAA00657@gluttony.geoffk.wattle.id.au> References: <199909271118.VAA01663@gluttony.geoffk.wattle.id.au> <19990928005956V.mitchell@codesourcery.com> X-SW-Source: 1999-09/msg00193.html > Cc: gavin@cygnus.com, binutils@sourceware.cygnus.com, brendan@cygnus.com > X-URL: http://www.codesourcery.com > Organization: CodeSourcery, LLC > From: Mark Mitchell > Date: Tue, 28 Sep 1999 00:59:56 -0700 > X-Dispatcher: imput version 990425(IM115) > > > 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. 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). 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. It's also possible to usefully have a R_MIPS_64 reloc with a full 64-bit addend, eg if you write 0: .dword 0f+0xa000000000000000 I don't know why anyone bothered to do this in the first place, there aren't that many compilers left that don't support 64-bit values; but it must have been useful for someone so I left the code in. > @@ -6628,26 +6629,11 @@ _bfd_mips_elf_relocate_section (output_b > l &= lo16_howto->src_mask; > l = mips_elf_sign_extend (l, 16); > > - /* Save the high-order bit for later. When we > - encounter the R_MIPS_LO16 relocation we will need > - them again. */ > addend <<= 16; > - last_hi16_addend = addend; > - last_hi16_addend_valid_p = true; > > /* Compute the combined addend. */ > addend += l; > } > - else if (r_type == R_MIPS_LO16) > - { > - /* Used the saved HI16 addend. */ > - if (!last_hi16_addend_valid_p) > - { > - bfd_set_error (bfd_error_bad_value); > - return false; > - } > - addend |= last_hi16_addend; > - } > else if (r_type == R_MIPS16_GPREL) > { > /* The addend is scrambled in the object file. See > > Why is all this code going away? This looks like it will make > R_MIPS_LO16 not work in .rel sections. The addend for the LO16 > relocation is the combination of bits in the HI16 and LO16 relocs, I > think. The addend for the LO16 reloc can be considered as just the bits in the LO16 reloc; we only care about the least-significant 16 bits. HI16 relocs are different because there can be a carry from the lower 16 bits. The problem it fixes is that the assembler does not sort LO16 relocs so that they all come after some HI16 reloc that matches them; it sorts HI16 relocs so that they all come before some LO16 reloc that matches. For instance, the following .s file: l1: b l2 l3: lw $5,%lo(l1+0x10004)($2) b l4 l2: lui $2,%hi(l1+0x10004) add $3,$2,$3 lw $4,%lo(l1+0x10004)($3) b l3 l4: produces the following relocs from gas: RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 000000000000000c R_MIPS_LO16 .text 0000000000000010 R_MIPS_HI16 .text 000000000000001c R_MIPS_LO16 .text Contents of section .text: 0000 10000003 00000000 10000005 8c450004 .............E.. 0010 3c020001 00431820 1000fffb 8c640004 <....C. .....d.. which used to cause ld to fail with an error. gcc can generate control flows like this (although some of the branches have to be conditional). -- Geoffrey Keating