Bug 14603 - no reloc emitted for ld generated veneers for ARM
: no reloc emitted for ld generated veneers for ARM
Status: REOPENED
Product: binutils
Classification: Unclassified
Component: ld
: unspecified
: P2 normal
: ---
Assigned To: Not yet assigned to anyone
:
:
:
:
  Show dependency treegraph
 
Reported: 2012-09-21 08:43 UTC by Marcin Bukat
Modified: 2012-09-21 11:09 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
testcase (598 bytes, application/x-bzip)
2012-09-21 08:43 UTC, Marcin Bukat
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Marcin Bukat 2012-09-21 08:43:49 UTC
Created attachment 6642 [details]
testcase

The simple test case provided shows that 0x80000000 constant used as jump
address in veneer generated by ld has no reloc associated. I believe this is a
bug (or inconsistency at least). I noticed this working on bFLT loader for the
target with memory split - fast internal ram and regular dram. With current ld
behavior runtime relocation is broken by this.

The workaround is to use -mlong-calls when compiling C sources but this imposes
performance penalty as well as does not solve the problem of asm files.

Tested with 2.20.1 as well as with current snapshot.
Comment 1 Matthew Gretton-Dann 2012-09-21 09:13:48 UTC
The testcase doesn't mark the branch destination as a function.  The linker
will only veneer function calls.

The test should work fine with the following source:

.text
.arm
.global _start
_start:
    bl far_foo

.section .far_text,"ax"
.arm
.global far_foo
.type far_foo, %function
@ For thumb you would instead do: .thumb_func
far_foo:
    nop
    bx lr 

For further examples see ld/testsuite/ld-arm/farcall-*.s source files.
Comment 2 Marcin Bukat 2012-09-21 09:19:32 UTC
Running provided testcase I get this:

test.elf:     file format elf32-littlearm


Disassembly of section .text:

00000000 <_start>:
   0:    eb000000     bl    8 <__far_foo_veneer>
            0: R_ARM_CALL    far_foo
   4:    00000000     andeq    r0, r0, r0

00000008 <__far_foo_veneer>:
   8:    e51ff004     ldr    pc, [pc, #-4]    ; c <__far_foo_veneer+0x4>
   c:    80000000     .word    0x80000000

Disassembly of section .far_text:

80000000 <far_foo>:
80000000:    e1a00000     nop            ; (mov r0, r0)
80000004:    e12fff1e     bx    lr
            80000004: R_ARM_V4BX    *ABS*


There is clearly veneer inserted as well as with your proposed change. But this
is not the case. The bug is about lack of relocation in veneer jump address
which still holds.
Comment 3 Matthew Gretton-Dann 2012-09-21 09:43:34 UTC
Surely as you have linked the image together and it is now fully relocated, the
linker doesn't need to create relocations for veneers?

The test case you provide only contains static relocations.  These are applied
once at static link time, and cannot - in general - be reapplied after linking
(as if the relocations have been specified with .rel sections the necessary
addend has been destroyed).

If you want to do runtime linking and relocation you need to use dynamic
relocations which do not get fixed by the static linker.
Comment 4 Marcin Bukat 2012-09-21 11:09:02 UTC
elf2flt allows you to take fully resolved elf binary produced with
--emit-relocs and produce flat file which is relocated at load time. I want to
archive the same but with address space split. I do understand why usually it
is not needed but veneer inserted by ld can be seen like any other code coming
from object files. It does introduce new symbols, but does not create
relocation for this symbols. I see this as inconsistency at least.