[AArch64] Relax long branch veneer insertion for non STT_FUNC symbol

As defined at AArch64 ELF Specification (4.6.7 Call and Jump
  relocations), symbol with type of non STT_FUNC but in different input
  section with relocation place should insert long branch veneer also.

  Meanwhile the current long branch veneer infrastructure havn't considered
  the situation where the branch destination is "sym_value + rela->addend".

  This was OK because we only insert veneer for long call destination is
  STT_FUNC symbol for which the addend is always zero. But as we relax the
  support to other situations by this patch, we need to handle addend be
  non-zero value. For example, for static function, relocation against
  "local symbol" are turned into relocation against "section symbol + offset"
  where there is a valid addend.

  bfd/
	* elfnn-aarch64.c (aarch64_type_of_stub): Allow insert long branch
	veneer for sym_sec != input_sec.
	(elfNN_aarch64_size_stub): Support STT_SECTION symbol.
	(elfNN_aarch64_final_link_relocate): Take rela addend into account when
	calculation destination.

  ld/
	* testsuite/ld-aarch64/farcall-section.d: Delete.
	* testsuite/ld-aarch64/farcall-section.s: Delete.
	* testsuite/ld-aarch64/farcall-b-section.d: New expectation file.
	* testsuite/ld-aarch64/farcall-bl-section.d: Likewise.
	* testsuite/ld-aarch64/farcall-b-section.s: New testcase.
	* testsuite/ld-aarch64/farcall-bl-section.s: Likewise.
	* testsuite/ld-aarch64/aarch64-elf.exp: Likewise.
This commit is contained in:
Jiong Wang 2016-01-20 16:57:59 +00:00
parent aeb7056972
commit 2f340668a9
12 changed files with 187 additions and 33 deletions

View file

@ -1,3 +1,11 @@
2016-01-21 Jiong Wang <jiong.wang@arm.com>
* elfnn-aarch64.c (aarch64_type_of_stub): Allow insert long branch
veneer for sym_sec != input_sec.
(elfNN_aarch64_size_stub): Support STT_SECTION symbol.
(elfNN_aarch64_final_link_relocate): Take rela addend into account when
calculation destination.
2016-01-21 Alan Modra <amodra@gmail.com>
* elf-linux-core.h (swap_linux_prpsinfo32_out): New function.

View file

@ -2655,7 +2655,7 @@ aarch64_type_of_stub (struct bfd_link_info *info,
bfd_boolean via_plt_p;
if (st_type != STT_FUNC
&& (sym_sec != bfd_abs_section_ptr))
&& (sym_sec == input_sec))
return stub_type;
globals = elf_aarch64_hash_table (info);
@ -4174,7 +4174,7 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
goto error_ret_free_internal;
}
stub_entry->target_value = sym_value;
stub_entry->target_value = sym_value + irela->r_addend;
stub_entry->target_section = sym_sec;
stub_entry->stub_type = stub_type;
stub_entry->h = hash;
@ -5280,15 +5280,28 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
/* Check if a stub has to be inserted because the destination
is too far away. */
struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
if (! aarch64_valid_branch_p (value, place))
/* If the branch destination is directed to plt stub, "value" will be
the final destination, otherwise we should plus signed_addend, it may
contain non-zero value, for example call to local function symbol
which are turned into "sec_sym + sec_off", and sec_off is kept in
signed_addend. */
if (! aarch64_valid_branch_p (via_plt_p ? value : value + signed_addend,
place))
/* The target is out of reach, so redirect the branch to
the local stub for this function. */
stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
rel, globals);
if (stub_entry != NULL)
value = (stub_entry->stub_offset
+ stub_entry->stub_sec->output_offset
+ stub_entry->stub_sec->output_section->vma);
{
value = (stub_entry->stub_offset
+ stub_entry->stub_sec->output_offset
+ stub_entry->stub_sec->output_section->vma);
/* We have redirected the destination to stub entry address,
so ignore any addend record in the original rela entry. */
signed_addend = 0;
}
}
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
signed_addend, weak_undef_p);

View file

@ -1,3 +1,13 @@
2016-01-20 Jiong Wang <jiong.wang@arm.com>
* testsuite/ld-aarch64/farcall-section.d: Delete.
* testsuite/ld-aarch64/farcall-section.s: Delete.
* testsuite/ld-aarch64/farcall-b-section.d: New expectation file.
* testsuite/ld-aarch64/farcall-bl-section.d: Likewise.
* testsuite/ld-aarch64/farcall-b-section.s: New testcase.
* testsuite/ld-aarch64/farcall-bl-section.s: Likewise.
* testsuite/ld-aarch64/aarch64-elf.exp: Likewise.
2016-01-20 Nick Clifton <nickc@redhat.com>
PR 19457

View file

@ -170,7 +170,6 @@ run_dump_test "pcrel_pic_defined_local"
run_dump_test "limit-b"
run_dump_test "limit-bl"
run_dump_test "farcall-section"
run_dump_test "farcall-back"
run_dump_test "farcall-b-defsym"
run_dump_test "farcall-bl-defsym"
@ -181,6 +180,8 @@ run_dump_test "farcall-bl"
run_dump_test "farcall-b"
run_dump_test "farcall-b-none-function"
run_dump_test "farcall-bl-none-function"
run_dump_test "farcall-b-section"
run_dump_test "farcall-bl-section"
run_dump_test "tls-relax-all"
run_dump_test "tls-relax-gd-le"

View file

@ -2,4 +2,23 @@
#source: farcall-b-none-function.s
#as:
#ld: -Ttext 0x1000 --section-start .foo=0x8001000
#error: .*\(.text\+0x0\): relocation truncated to fit: R_AARCH64_JUMP26 against symbol `bar'.*
#objdump: -dr
#...
Disassembly of section .text:
.* <_start>:
1000: 14000003 b 100c <__bar_veneer>
1004: d65f03c0 ret
1008: 14000007 b 1024 <__bar_veneer\+0x18>
.* <__bar_veneer>:
100c: 90040010 adrp x16, 8001000 <bar>
1010: 91000210 add x16, x16, #0x0
1014: d61f0200 br x16
...
Disassembly of section .foo:
.* <bar>:
8001000: d65f03c0 ret

View file

@ -0,0 +1,34 @@
#name: aarch64-farcall-b-section
#source: farcall-b-section.s
#as:
#ld: -Ttext 0x1000 --section-start .foo=0x8001000
#objdump: -dr
#...
Disassembly of section .text:
.* <_start>:
1000: 14000008 b 1020 <___veneer>
1004: 14000003 b 1010 <___veneer>
1008: d65f03c0 ret
100c: 1400000d b 1040 <___veneer\+0x20>
.* <___veneer>:
1010: 90040010 adrp x16, 8001000 <bar>
1014: 91001210 add x16, x16, #0x4
1018: d61f0200 br x16
101c: 00000000 .inst 0x00000000 ; undefined
.* <___veneer>:
1020: 90040010 adrp x16, 8001000 <bar>
1024: 91000210 add x16, x16, #0x0
1028: d61f0200 br x16
...
Disassembly of section .foo:
.* <bar>:
8001000: d65f03c0 ret
.* <bar2>:
8001004: d65f03c0 ret

View file

@ -0,0 +1,20 @@
.global _start
# We will place the section .text at 0x1000.
.text
_start:
b bar
b bar2
ret
# We will place the section .foo at 0x8001000.
.section .foo, "xa"
.type bar, @function
bar:
ret
.type bar2, @function
bar2:
ret

View file

@ -2,4 +2,23 @@
#source: farcall-bl-none-function.s
#as:
#ld: -Ttext 0x1000 --section-start .foo=0x8001000
#error: .*\(.text\+0x0\): relocation truncated to fit: R_AARCH64_CALL26 against symbol `bar'.*
#objdump: -dr
#...
Disassembly of section .text:
.* <_start>:
1000: 94000003 bl 100c <__bar_veneer>
1004: d65f03c0 ret
1008: 14000007 b 1024 <__bar_veneer\+0x18>
.* <__bar_veneer>:
100c: 90040010 adrp x16, 8001000 <bar>
1010: 91000210 add x16, x16, #0x0
1014: d61f0200 br x16
...
Disassembly of section .foo:
.* <bar>:
8001000: d65f03c0 ret

View file

@ -0,0 +1,34 @@
#name: aarch64-farcall-bl-section
#source: farcall-bl-section.s
#as:
#ld: -Ttext 0x1000 --section-start .foo=0x8001000
#objdump: -dr
#...
Disassembly of section .text:
.* <_start>:
1000: 94000008 bl 1020 <___veneer>
1004: 94000003 bl 1010 <___veneer>
1008: d65f03c0 ret
100c: 1400000d b 1040 <___veneer\+0x20>
.* <___veneer>:
1010: 90040010 adrp x16, 8001000 <bar>
1014: 91001210 add x16, x16, #0x4
1018: d61f0200 br x16
101c: 00000000 .inst 0x00000000 ; undefined
.* <___veneer>:
1020: 90040010 adrp x16, 8001000 <bar>
1024: 91000210 add x16, x16, #0x0
1028: d61f0200 br x16
...
Disassembly of section .foo:
.* <bar>:
8001000: d65f03c0 ret
.* <bar2>:
8001004: d65f03c0 ret

View file

@ -0,0 +1,20 @@
.global _start
# We will place the section .text at 0x1000.
.text
_start:
bl bar
bl bar2
ret
# We will place the section .foo at 0x8001000.
.section .foo, "xa"
.type bar, @function
bar:
ret
.type bar2, @function
bar2:
ret

View file

@ -1,5 +0,0 @@
#name: Aarch64 farcall to symbol of type STT_SECTION
#source: farcall-section.s
#as:
#ld: -Ttext 0x1000 --section-start .foo=0x8001014
#error: .*\(.text\+0x0\): relocation truncated to fit: R_AARCH64_CALL26 against `.foo'

View file

@ -1,19 +0,0 @@
# Test to ensure that an Aarch64 call exceeding 128MB generates an error
# if the destination is of type STT_SECTION (eg non-global symbol)
.global _start
# We will place the section .text at 0x1000.
.text
_start:
bl bar
# We will place the section .foo at 0x8001020.
.section .foo, "xa"
bar:
ret