[PATCH, ARM]: Fix SB group relocations

Richard Earnshaw rearnsha@arm.com
Fri Jul 19 12:19:00 GMT 2013


On 14/07/13 18:50, John Tytgat wrote:
> ARM's IHI0044E document specifies the B(S) for the
> R_ARM_{ALU|LDR|LDC|LDRS}_SB_G{0|1|2} relocations as:
>
> B(S) is the addressing origin of the output segment defining the symbol S.
> The origin is not required to be the base address of the segment. This
> value must always be word-aligned.
>
> However currently in bfd/elf32-arm.c the sb value gets calculated as:
>
> 	/* sb should be the origin of the *segment* containing the symbol.
> 	   It is not clear how to obtain this OS-dependent value, so we
> 	   make an arbitrary choice of zero.  */
> 	bfd_vma sb = 0;
>
> IMHO this is wrong and this is not about the origin of the output segment
> at run time but about the one which gets determined at linking time.

Agreed, but the existing code is not totally invalid.  The idea behind 
all this is that you can do segment-relative addressing.  That is, you 
have a register (somewhere) that contains B(s) and then you can form 
addresses off that register simply by adding the offsets.  The offsets 
are constant if the target address is in the same segment as the base 
address.

We would normally expect B(s) to be the address of the first byte of the 
segment, but this is not a requirement: the only constraints are that 
the base address used can be loaded (somehow) into the base address 
register and that the base is close enough to handle the number of 
relocations supported by the code.  Using '0' as the notional base 
address will work provided that, if the segment is loaded at an address 
other than the 'static link' address, the base address is adjusted 
appropriately (by the difference in the two values).

However, using 0 is, in general, a poor choice, since it will mean that 
more instructions will be needed to form the full address offset than 
might be required with a more sensible starting point.

> As
> sb group relocations are static ones they are most probably the same so we
> better use sym_sec->output_section->vma instead of a fixed value 0.
>

I presume that output_section in this context is really the output 
segment and not a section within that segment.  Otherwise you'll need a 
further adjustment.



> --- ld/testsuite/ld-arm/group-relocs-ldrs-bad.s	15 Jun 2006 11:03:02 -0000	1.1
> +++ ld/testsuite/ld-arm/group-relocs-ldrs-bad.s	14 Jul 2013 16:45:03 -0000
> @@ -6,8 +6,8 @@
>   	.globl _start
>
>   _start:
> -	add	r0, r0, #:sb_g0_nc:(bar)
> -	ldrd	r2, [r0, #:sb_g1:(bar)]
> +	add	r0, r0, #:pc_g0_nc:(bar)
> +	ldrd	r2, [r0, #:pc_g1:(bar + 4)]
>
>   @ We will place the section foo at 0x8000100.
>

Why have you changed this test from SB relative to PC relative?  That 
means it no-longer tests the same thing.










More information about the Binutils mailing list