This is the mail archive of the 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]
Other format: [Raw text]

Re: [PATCH, ARM]: Fix SB group relocations

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.

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

-	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.

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