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]

Re: MIPS embedded PIC bug.


Geoff Keating <geoffk@geoffk.org> writes:
> > Really?  My understanding of this says that if it can't be resolved
> > into something PC-relative, you need to emit more complex code, and a
> > sample like the above, but with L20 not defined in the same segment,
> > can't be resolved into something PC-relative with a single
> > instruction.
> 
> Sure it can.
> 
> The basic PC-relative reloc looks like:
> 
> 	  .word Lbar-.
> 
> This is a PC-relative reloc to Lbar, because the address we need is
> the address of Lbar less the address of the PC, which is `.' in assembler.
>
> A similar problem looks like:
> 
> Lfoo:
> 	.word 0
> 	.word Lbar-Lfoo
> 
> The expression 'Lbar-Lfoo' can be rewritten as 'Lbar-Lfoo+.-.',
> which (because Lfoo and the .word are in the same segment) can be
> rewritten in this case as 'Lbar-4-.', which is a PC-relative reloc to
> Lbar-4.

Sure... but when you start trying to put that into the 16-bit offset
field in an instruction, in many cases (esp. when . and the label are
in different sections) it's just not going to work.


> This is certainly a bug, but I wrote the patch quite some time before
> that and it worked then (it took about 6 months to be approved).

Hmm.  More on this below.


> The PC-relative version of BFD_RELOC_LO16 is BFD_RELOC_PCREL_LO16
> (which gets output as a R_MIPS_GNU_REL_LO16, just as the comment in
> the testcase says), so the error message indicates that the conversion
> of a PC-relative BFD_RELOC_LO16 is going wrong.

I really don't think so.  If you look at the difference between what
the testcase currently expects, for instance:

         la      $3,g1-l3        # R_MIPS_GNU_REL_HI16   g1   0
                                 # R_MIPS_GNU_REL_LO16   g1   C

and what would be output in the case that triggers the error messages,
I think it shows it's not that easy.

The testcase expects 'la' to be emitted as multiple instructions, one
with the REL_HI16 and one with REL_LO16.  Both mean that a full 32-bit
address can be relocated, i.e. anyplace it ends up, it's good.

In the case that triggers the error messages, because the test in the
code at issue succeeds, instead a _single_ instruction would be
output, with only a 16-bit RELOC_LO16.  The code output in this case
is _not_ attempting to be PC-relative, as far as I can tell.


Anyway, this feeds into the question of "in what circumstances is it
breaking?"  And about that, to continue about "it worked when it was
submitted":

1999-11-15  Gavin Romig-Koch  <gavin@cygnus.com>

        * mips-opc.c (la): Create a version that just uses addiu directly.
        (dla): Expand to daddiu if possible.

These use the 'o' instruction operand format.

To be honest, I'm not sure what the benefit of providing doing those
directly in the opcode table is.  It seems to me that any benefit
could be had by doing a bit of coding in the la and dla expansions.

But on the other hand, i'm not sure it _should_ be handled in C,
rather than in the table; the EMBEDDED_PIC check in the 'o' format
handling code really does seem too loose to me.  It really doesn't
seem to me that you can handle the general case in a simple 16-bit
relocation, which is what it apparently allows.



chris


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