This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH, ARM]: Fix SB group relocations
- From: John Tytgat <john at bass-software dot com>
- To: rearnsha at arm dot com
- Cc: binutils at sourceware dot org, nickc at redhat dot com
- Date: Fri, 26 Jul 2013 03:10:57 +0100
- Subject: Re: [PATCH, ARM]: Fix SB group relocations
- References: <51cd3a6b53 dot Jo at hobbes dot bass-software dot com> <51E92EB7 dot 2010307 at arm dot com>
In message <51E92EB7.2010307@arm.com>
Richard Earnshaw <rearnsha@arm.com> wrote:
> 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.
Thanks for this confirmation.
> > 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.
I think that's ok. Just to be 100% sure :
.text
ldr r1, [r9, #:sb_g0:(foo1)]
ldr r2, [r9, #:sb_g0:(foo2)]
.section .data.1
.word 0
foo1: .word 1
.section .data.2
.word 2
.word 3
.word 4
foo2: .word 5
Assembled and linked with:
PHDRS
{
text PT_LOAD ;
data PT_LOAD ;
}
SECTIONS
{
. = 0x20000;
.text : { *(.text) } :text
.data : { *(.data.1) *(.data.2) } :data
}
results in:
00020000 <.text>:
20000: e5991004 ldr r1, [r9, #4]
20004: e5992014 ldr r2, [r9, #20]
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00020000 008000 000008 00 AX 0 0 4
[ 2] .data PROGBITS 00020008 008008 000018 00 WA 0 0 1
[ 3] .ARM.attributes ARM_ATTRIBUTES 00000000 008020 000016 00 0 0 1
[ 4] .shstrtab STRTAB 00000000 008036 000037 00 0 0 1
[ 5] .symtab SYMTAB 00000000 008188 0000b0 10 6 11 4
[ 6] .strtab STRTAB 00000000 008238 000018 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x008000 0x00020000 0x00020000 0x00008 0x00008 R E 0x8000
LOAD 0x008008 0x00020008 0x00020008 0x00018 0x00018 RW 0x8000
Section to Segment mapping:
Segment Sections...
00 .text
01 .data
> > --- 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.
We originally had 4 linker groups tests : group-relocs-alu-bad,
group-relocs-ldc-bad, group-relocs-ldr-bad and group-relocs-ldrs-bad.
The first two were pc-based, the last two were sb-based. I've changed the
last two in pc-based as well and added 4 new sb-based tests.
John.
--
John Tytgat BASS
John@bass-software.com