diff options
author | Jiong Wang <jiong.wang@arm.com> | 2016-02-25 10:26:34 +0000 |
---|---|---|
committer | Jiong Wang <jiong.wang@arm.com> | 2016-02-25 10:26:34 +0000 |
commit | 7e487fb563d5f1b9ede26fda7a6dd39a0f6d04c2 (patch) | |
tree | 606d7cea7658078774671e17b0f888687d09d97c | |
parent | 30b2144474414bfdaeb58ddb7a94aa265c4e3b37 (diff) | |
download | fsf-binutils-gdb-7e487fb563d5f1b9ede26fda7a6dd39a0f6d04c2.zip fsf-binutils-gdb-7e487fb563d5f1b9ede26fda7a6dd39a0f6d04c2.tar.gz fsf-binutils-gdb-7e487fb563d5f1b9ede26fda7a6dd39a0f6d04c2.tar.bz2 |
[Backport][AArch64] Relax long branch veneer insertion for non STT_FUNC symbol
2016-02-25 Jiong Wang <jiong.wang@arm.com>
Backport from master
bfd/
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.
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.
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elfnn-aarch64.c | 25 | ||||
-rw-r--r-- | ld/ChangeLog | 13 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/aarch64-elf.exp | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-b-none-function.d | 21 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-b-section.d | 34 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-b-section.s | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-bl-none-function.d | 21 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-bl-section.d | 34 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-bl-section.s | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-section.d | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/farcall-section.s | 19 |
12 files changed, 193 insertions, 33 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9bd2925..fce5964 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2016-02-25 Jiong Wang <jiong.wang@arm.com> + + Backport from master + 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-02-10 H.J. Lu <hongjiu.lu@intel.com> Backport from master diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 59c51cc..d83dc1b 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -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); diff --git a/ld/ChangeLog b/ld/ChangeLog index 4d500e1..37c6d6b 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +2016-02-25 Jiong Wang <jiong.wang@arm.com> + + Backport from master + 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-02-11 H.J. Lu <hongjiu.lu@intel.com> Backport from master diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 0e5b31e..576cc65 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -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" diff --git a/ld/testsuite/ld-aarch64/farcall-b-none-function.d b/ld/testsuite/ld-aarch64/farcall-b-none-function.d index 34a6568..ba2981f 100644 --- a/ld/testsuite/ld-aarch64/farcall-b-none-function.d +++ b/ld/testsuite/ld-aarch64/farcall-b-none-function.d @@ -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 diff --git a/ld/testsuite/ld-aarch64/farcall-b-section.d b/ld/testsuite/ld-aarch64/farcall-b-section.d new file mode 100644 index 0000000..4745c0f --- /dev/null +++ b/ld/testsuite/ld-aarch64/farcall-b-section.d @@ -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 diff --git a/ld/testsuite/ld-aarch64/farcall-b-section.s b/ld/testsuite/ld-aarch64/farcall-b-section.s new file mode 100644 index 0000000..1a135ef --- /dev/null +++ b/ld/testsuite/ld-aarch64/farcall-b-section.s @@ -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 diff --git a/ld/testsuite/ld-aarch64/farcall-bl-none-function.d b/ld/testsuite/ld-aarch64/farcall-bl-none-function.d index 6ce9ca4..b6a4dda 100644 --- a/ld/testsuite/ld-aarch64/farcall-bl-none-function.d +++ b/ld/testsuite/ld-aarch64/farcall-bl-none-function.d @@ -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 diff --git a/ld/testsuite/ld-aarch64/farcall-bl-section.d b/ld/testsuite/ld-aarch64/farcall-bl-section.d new file mode 100644 index 0000000..2bd4f85 --- /dev/null +++ b/ld/testsuite/ld-aarch64/farcall-bl-section.d @@ -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 diff --git a/ld/testsuite/ld-aarch64/farcall-bl-section.s b/ld/testsuite/ld-aarch64/farcall-bl-section.s new file mode 100644 index 0000000..4469d4d --- /dev/null +++ b/ld/testsuite/ld-aarch64/farcall-bl-section.s @@ -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 diff --git a/ld/testsuite/ld-aarch64/farcall-section.d b/ld/testsuite/ld-aarch64/farcall-section.d deleted file mode 100644 index 85775e1..0000000 --- a/ld/testsuite/ld-aarch64/farcall-section.d +++ /dev/null @@ -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' diff --git a/ld/testsuite/ld-aarch64/farcall-section.s b/ld/testsuite/ld-aarch64/farcall-section.s deleted file mode 100644 index 86a070c..0000000 --- a/ld/testsuite/ld-aarch64/farcall-section.s +++ /dev/null @@ -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 - |