mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
[AArch64] PR18668, repair long branch veneer for plt stub
2015-08-11 Jiong Wang <jiong.wang@arm.com> bfd/ PR ld/18668 * elfnn-aarch64.c (aarch64_type_of_stub): Update destination for calls go through plt stub. (elfNN_aarch64_final_link_relocate): Adjust code logic for CALL26, JUMP26 relocation to support inserting veneer for call to plt stub. ld/testsuite/ * ld-aarch64/farcall-b-gsym.s: New test. * ld-aarch64/farcall-b-plt.s: Likewise. * ld-aarch64/farcall-bl-plt.s: Likewise. * ld-aarch64/farcall-b-gsym.d: New expect file. * ld-aarch64/farcall-b-plt.d: Likewise. * ld-aarch64/farcall-bl-plt.d: Likewise.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2015-08-11 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
|
PR ld/18668
|
||||||
|
* elfnn-aarch64.c (aarch64_type_of_stub): Update destination for
|
||||||
|
calls go through plt stub.
|
||||||
|
(elfNN_aarch64_final_link_relocate): Adjust code logic for CALL26,
|
||||||
|
JUMP26 relocation to support inserting veneer for call to plt stub.
|
||||||
|
|
||||||
2015-08-11 Jiong Wang <jiong.wang@arm.com>
|
2015-08-11 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
* elfnn-aarch64.c (IS_AARCH64_TLS_RELOC): Recognize
|
* elfnn-aarch64.c (IS_AARCH64_TLS_RELOC): Recognize
|
||||||
|
@ -2333,9 +2333,11 @@ aarch64_type_of_stub (struct bfd_link_info *info,
|
|||||||
globals = elf_aarch64_hash_table (info);
|
globals = elf_aarch64_hash_table (info);
|
||||||
via_plt_p = (globals->root.splt != NULL && hash != NULL
|
via_plt_p = (globals->root.splt != NULL && hash != NULL
|
||||||
&& hash->root.plt.offset != (bfd_vma) - 1);
|
&& hash->root.plt.offset != (bfd_vma) - 1);
|
||||||
|
/* Make sure call to plt stub can fit into the branch range. */
|
||||||
if (via_plt_p)
|
if (via_plt_p)
|
||||||
return stub_type;
|
destination = (globals->root.splt->output_section->vma
|
||||||
|
+ globals->root.splt->output_offset
|
||||||
|
+ hash->root.plt.offset);
|
||||||
|
|
||||||
/* Determine where the call point is. */
|
/* Determine where the call point is. */
|
||||||
location = (input_sec->output_offset
|
location = (input_sec->output_offset
|
||||||
@ -4890,38 +4892,25 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|
|||||||
/* If the call goes through a PLT entry, make sure to
|
/* If the call goes through a PLT entry, make sure to
|
||||||
check distance to the right destination address. */
|
check distance to the right destination address. */
|
||||||
if (via_plt_p)
|
if (via_plt_p)
|
||||||
{
|
|
||||||
value = (splt->output_section->vma
|
value = (splt->output_section->vma
|
||||||
+ splt->output_offset + h->plt.offset);
|
+ splt->output_offset + h->plt.offset);
|
||||||
*unresolved_reloc_p = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the target symbol is global and marked as a function the
|
|
||||||
relocation applies a function call or a tail call. In this
|
|
||||||
situation we can veneer out of range branches. The veneers
|
|
||||||
use IP0 and IP1 hence cannot be used arbitrary out of range
|
|
||||||
branches that occur within the body of a function. */
|
|
||||||
if (h && h->type == STT_FUNC)
|
|
||||||
{
|
|
||||||
/* Check if a stub has to be inserted because the destination
|
/* Check if a stub has to be inserted because the destination
|
||||||
is too far away. */
|
is too far away. */
|
||||||
|
struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
|
||||||
if (! aarch64_valid_branch_p (value, place))
|
if (! aarch64_valid_branch_p (value, place))
|
||||||
{
|
|
||||||
/* The target is out of reach, so redirect the branch to
|
/* The target is out of reach, so redirect the branch to
|
||||||
the local stub for this function. */
|
the local stub for this function. */
|
||||||
struct elf_aarch64_stub_hash_entry *stub_entry;
|
stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
|
||||||
stub_entry = elfNN_aarch64_get_stub_entry (input_section,
|
|
||||||
sym_sec, h,
|
|
||||||
rel, globals);
|
rel, globals);
|
||||||
if (stub_entry != NULL)
|
if (stub_entry != NULL)
|
||||||
value = (stub_entry->stub_offset
|
value = (stub_entry->stub_offset
|
||||||
+ stub_entry->stub_sec->output_offset
|
+ stub_entry->stub_sec->output_offset
|
||||||
+ stub_entry->stub_sec->output_section->vma);
|
+ stub_entry->stub_sec->output_section->vma);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
|
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
|
||||||
signed_addend, weak_undef_p);
|
signed_addend, weak_undef_p);
|
||||||
|
*unresolved_reloc_p = FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_AARCH64_16_PCREL:
|
case BFD_RELOC_AARCH64_16_PCREL:
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2015-08-11 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
|
* ld-aarch64/farcall-b-gsym.s: New test.
|
||||||
|
* ld-aarch64/farcall-b-plt.s: Likewise.
|
||||||
|
* ld-aarch64/farcall-bl-plt.s: Likewise.
|
||||||
|
* ld-aarch64/farcall-b-gsym.d: New expect file.
|
||||||
|
* ld-aarch64/farcall-b-plt.d: Likewise.
|
||||||
|
* ld-aarch64/farcall-bl-plt.d: Likewise.
|
||||||
|
|
||||||
2015-08-11 Jiong Wang <jiong.wang@arm.com>
|
2015-08-11 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
* ld-aarch64/emit-relocs-529.s: New testcase.
|
* ld-aarch64/emit-relocs-529.s: New testcase.
|
||||||
|
@ -127,6 +127,9 @@ run_dump_test "limit-b"
|
|||||||
run_dump_test "limit-bl"
|
run_dump_test "limit-bl"
|
||||||
run_dump_test "farcall-section"
|
run_dump_test "farcall-section"
|
||||||
run_dump_test "farcall-back"
|
run_dump_test "farcall-back"
|
||||||
|
run_dump_test "farcall-b-gsym"
|
||||||
|
run_dump_test "farcall-b-plt"
|
||||||
|
run_dump_test "farcall-bl-plt"
|
||||||
run_dump_test "farcall-bl"
|
run_dump_test "farcall-bl"
|
||||||
run_dump_test "farcall-b"
|
run_dump_test "farcall-b"
|
||||||
run_dump_test "farcall-b-none-function"
|
run_dump_test "farcall-b-none-function"
|
||||||
|
5
ld/testsuite/ld-aarch64/farcall-b-gsym.d
Normal file
5
ld/testsuite/ld-aarch64/farcall-b-gsym.d
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#name: aarch64-farcall-b-gsym
|
||||||
|
#source: farcall-b-gsym.s
|
||||||
|
#as:
|
||||||
|
#ld: -Ttext 0x1000
|
||||||
|
#error: .*\(.text\+0x0\): relocation truncated to fit: R_AARCH64_JUMP26 against symbol `bar_gsym'.*
|
17
ld/testsuite/ld-aarch64/farcall-b-gsym.s
Normal file
17
ld/testsuite/ld-aarch64/farcall-b-gsym.s
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
.global _start
|
||||||
|
.global bar_gsym
|
||||||
|
|
||||||
|
# We will place the section .text at 0x1000.
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
# for long jump (JUMP26) to global symbol, we shouldn't insert veneer
|
||||||
|
# as the veneer will clobber IP0/IP1 which is caller saved, gcc only
|
||||||
|
# reserve them for function call relocation (CALL26).
|
||||||
|
b bar_gsym
|
||||||
|
# ((1 << 25) - 1) << 2
|
||||||
|
.skip 134217724, 0
|
||||||
|
bar_gsym:
|
||||||
|
nop
|
||||||
|
ret
|
38
ld/testsuite/ld-aarch64/farcall-b-plt.d
Normal file
38
ld/testsuite/ld-aarch64/farcall-b-plt.d
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#name: aarch64-farcall-b-plt
|
||||||
|
#source: farcall-b-plt.s
|
||||||
|
#as:
|
||||||
|
#ld: -shared
|
||||||
|
#objdump: -dr
|
||||||
|
#...
|
||||||
|
|
||||||
|
Disassembly of section .plt:
|
||||||
|
|
||||||
|
.* <foo@plt-0x20>:
|
||||||
|
.*: a9bf7bf0 stp x16, x30, \[sp,#-16\]!
|
||||||
|
.*: 90040090 adrp x16, 8010000 <__foo_veneer\+.*>
|
||||||
|
.*: f941f611 ldr x17, \[x16,#1000\]
|
||||||
|
.*: 910fa210 add x16, x16, #0x3e8
|
||||||
|
.*: d61f0220 br x17
|
||||||
|
.*: d503201f nop
|
||||||
|
.*: d503201f nop
|
||||||
|
.*: d503201f nop
|
||||||
|
|
||||||
|
.* <foo@plt>:
|
||||||
|
.*: 90040090 adrp x16, 8010000 <__foo_veneer\+.*>
|
||||||
|
.*: f941fa11 ldr x17, \[x16,#1008\]
|
||||||
|
.*: 910fc210 add x16, x16, #0x3f0
|
||||||
|
.*: d61f0220 br x17
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
.* <_start>:
|
||||||
|
...
|
||||||
|
.*: 14000003 b 80002c8 <__foo_veneer>
|
||||||
|
.*: d65f03c0 ret
|
||||||
|
.*: 14000007 b 80002e0 <__foo_veneer\+.*>
|
||||||
|
|
||||||
|
.* <__foo_veneer>:
|
||||||
|
.*: 90fc0010 adrp x16, 0 <foo@plt-0x2b0>
|
||||||
|
.*: 910ac210 add x16, x16, #0x2b0
|
||||||
|
.*: d61f0200 br x16
|
||||||
|
...
|
11
ld/testsuite/ld-aarch64/farcall-b-plt.s
Normal file
11
ld/testsuite/ld-aarch64/farcall-b-plt.s
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.global _start
|
||||||
|
.global foo
|
||||||
|
.type foo, @function
|
||||||
|
.text
|
||||||
|
_start:
|
||||||
|
# ((1 << 25) - 1) << 2
|
||||||
|
# jump26 relocation out of range to plt stub,
|
||||||
|
# we need long branch veneer.
|
||||||
|
.skip 134217724, 0
|
||||||
|
b foo
|
||||||
|
ret
|
38
ld/testsuite/ld-aarch64/farcall-bl-plt.d
Normal file
38
ld/testsuite/ld-aarch64/farcall-bl-plt.d
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#name: aarch64-farcall-bl-plt
|
||||||
|
#source: farcall-bl-plt.s
|
||||||
|
#as:
|
||||||
|
#ld: -shared
|
||||||
|
#objdump: -dr
|
||||||
|
#...
|
||||||
|
|
||||||
|
Disassembly of section .plt:
|
||||||
|
|
||||||
|
.* <foo@plt-0x20>:
|
||||||
|
.*: a9bf7bf0 stp x16, x30, \[sp,#-16\]!
|
||||||
|
.*: 90040090 adrp x16, 8010000 <__foo_veneer\+.*>
|
||||||
|
.*: f941f611 ldr x17, \[x16,#1000\]
|
||||||
|
.*: 910fa210 add x16, x16, #0x3e8
|
||||||
|
.*: d61f0220 br x17
|
||||||
|
.*: d503201f nop
|
||||||
|
.*: d503201f nop
|
||||||
|
.*: d503201f nop
|
||||||
|
|
||||||
|
.* <foo@plt>:
|
||||||
|
.*: 90040090 adrp x16, 8010000 <__foo_veneer\+.*>
|
||||||
|
.*: f941fa11 ldr x17, \[x16,#1008\]
|
||||||
|
.*: 910fc210 add x16, x16, #0x3f0
|
||||||
|
.*: d61f0220 br x17
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
.* <_start>:
|
||||||
|
...
|
||||||
|
.*: 94000003 bl 80002c8 <__foo_veneer>
|
||||||
|
.*: d65f03c0 ret
|
||||||
|
.*: 14000007 b 80002e0 <__foo_veneer\+.*>
|
||||||
|
|
||||||
|
.* <__foo_veneer>:
|
||||||
|
.*: 90fc0010 adrp x16, 0 <foo@plt-0x2b0>
|
||||||
|
.*: 910ac210 add x16, x16, #0x2b0
|
||||||
|
.*: d61f0200 br x16
|
||||||
|
...
|
12
ld/testsuite/ld-aarch64/farcall-bl-plt.s
Normal file
12
ld/testsuite/ld-aarch64/farcall-bl-plt.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.global _start
|
||||||
|
.global foo
|
||||||
|
.type foo, @function
|
||||||
|
.text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
# ((1 << 25) - 1) << 2
|
||||||
|
# call26 relocation out of range to plt stub,
|
||||||
|
# we need long branch veneer.
|
||||||
|
.skip 134217724, 0
|
||||||
|
bl foo
|
||||||
|
ret
|
Reference in New Issue
Block a user