]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Backport][AArch64] Relax long branch veneer insertion for non STT_FUNC symbol
authorJiong Wang <jiong.wang@arm.com>
Thu, 25 Feb 2016 10:26:34 +0000 (10:26 +0000)
committerJiong Wang <jiong.wang@arm.com>
Thu, 25 Feb 2016 10:26:34 +0000 (10:26 +0000)
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.

12 files changed:
bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/farcall-b-none-function.d
ld/testsuite/ld-aarch64/farcall-b-section.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/farcall-b-section.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/farcall-bl-none-function.d
ld/testsuite/ld-aarch64/farcall-bl-section.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/farcall-bl-section.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/farcall-section.d [deleted file]
ld/testsuite/ld-aarch64/farcall-section.s [deleted file]

index 9bd29253c1a7901a334ab5d4d98e037ce1c4b755..fce5964ac9bc2a67afa23cbe628b788eecab8ab9 100644 (file)
@@ -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
index 59c51cc42e08f78d28221aeecf0f72e86fdd7d16..d83dc1b670c850a79e8f8e794c45230e64577620 100644 (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);
index 4d500e17154a788f07b15eba56a5a4d9d31a6208..37c6d6b03367fd32952e2fb74f04ace8b0c2e90f 100644 (file)
@@ -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
index 0e5b31ea70b890de47a01b62274fccf1c8e31d6a..576cc65bbfeaa767e58046395a463245dce18c61 100644 (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"
index 34a6568dfb1cde0667c74aea65219be22f5cfffa..ba2981fb10ec7497c7946adfd0544cb42694ea76 100644 (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
diff --git a/ld/testsuite/ld-aarch64/farcall-b-section.d b/ld/testsuite/ld-aarch64/farcall-b-section.d
new file mode 100644 (file)
index 0000000..4745c0f
--- /dev/null
@@ -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 (file)
index 0000000..1a135ef
--- /dev/null
@@ -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
index 6ce9ca45b2994c9e3f436c0e4e7726bdc3776c82..b6a4ddae44a40803e91c4e931704cc5505ba2870 100644 (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
diff --git a/ld/testsuite/ld-aarch64/farcall-bl-section.d b/ld/testsuite/ld-aarch64/farcall-bl-section.d
new file mode 100644 (file)
index 0000000..2bd4f85
--- /dev/null
@@ -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 (file)
index 0000000..4469d4d
--- /dev/null
@@ -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 (file)
index 85775e1..0000000
+++ /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 (file)
index 86a070c..0000000
+++ /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
-