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: REL vs. RELA: how to choose?


Very good analysis of why RELA is better.
[I didn't actually follow the math.  You're on the right track though
so I'm assuming you got it right.]

Note that the mips and m32r ports are REL
but they do get the 16 hi + 16 lo case correct.
[At least I think it's mips.  I copied some port when
I made it work for the m32r and I think it was mips.]

Nick Clifton writes:
 > One reason for preferring RELA relocations is that the REL format can
 > have some hidden restrictions.  Consider for example an ISA where a 32
 > bit constant cannot be loaded by a single instruction but has to be
 > done in two parts - a high 16 bit load followed by a low 16 bit load.
 > The assembler to load the address of element 0xffffff of an array 'foo'
 > into register 1 might look something like this:
 > 
 >   LOAD_HI r1, hi(foo + 0xffffff)
 >   ADD     r1, lo(foo + 0xffffff)
 > 
 > which would generate two separate relocs, one for the hi() expression
 > and one for the lo() expression.  If the file format uses REL
 > relocations then the 0xffffff value would have to be stored in the
 > LOAD_HI or ADD instructions, which presumably only have a 16 bit
 > relocatable field - not big enough to hold 0xffff.
 > 
 > In theory though, you could split the constant between the two relocs,
 > like this:
 > 
 >   LOAD_HI r1, 0xff
 >     RELOC_HIGH_16_BITS (foo)
 >   ADD     r1, 0xffff
 >     RELOC_LOW_16_BITS (foo)
 > 
 > But the problem here is overflow.  Suppose the address of 'foo' is
 > 0x000000001.  The computation for the RELOC_HIGH_16_BITS will be:
 > 
 >     ((0xff << 16) + 0x00000001) >> 16
 > or
 >     0x00ff
 > 
 > but the computation for the RELOC_LOW_16_BITS will be:
 > 
 >     (0xffff + 0x00000001) & 0xffff
 > or
 >     0x0000
 > 
 > So the final address loaded into register 1 will be:
 > 
 >   0x00ff0000
 >  +0x00000000
 >   ----------
 >   0x00ff0000
 > 
 > instead of the correct address of:
 > 
 >   0x00ffffff
 >  +0x00000001
 >   ----------
 >   0x01000000
 > 
 > So the RELOC_LOW_16_BITS needs to be able to tell the
 > RELOC_HIGH_16_BITS that its computation overflow, which can be tricky
 > if the two relocs are not next to each other, and very tricky when
 > clever compiler decide that multiple references to elements of 'foo'
 > can be optimised into only on LOAD_HI with multiple ADD instructions
 > afterwards...
 > 
 > Cheers
 > 	Nick
 > 
 >   


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