This is the mail archive of the binutils@sourceware.org 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


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


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