This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] [AArch64] PR18668, repair long branch veneer for plt stub


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=07f9ddfeba5b572451471f905473f7ddbba1d472

commit 07f9ddfeba5b572451471f905473f7ddbba1d472
Author: Jiong Wang <jiong.wang@arm.com>
Date:   Tue Aug 11 21:44:31 2015 +0100

    [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.

Diff:
---
 bfd/ChangeLog                            |  8 +++++
 bfd/elfnn-aarch64.c                      | 51 +++++++++++++-------------------
 ld/testsuite/ChangeLog                   |  9 ++++++
 ld/testsuite/ld-aarch64/aarch64-elf.exp  |  3 ++
 ld/testsuite/ld-aarch64/farcall-b-gsym.d |  5 ++++
 ld/testsuite/ld-aarch64/farcall-b-gsym.s | 17 +++++++++++
 ld/testsuite/ld-aarch64/farcall-b-plt.d  | 38 ++++++++++++++++++++++++
 ld/testsuite/ld-aarch64/farcall-b-plt.s  | 11 +++++++
 ld/testsuite/ld-aarch64/farcall-bl-plt.d | 38 ++++++++++++++++++++++++
 ld/testsuite/ld-aarch64/farcall-bl-plt.s | 12 ++++++++
 10 files changed, 161 insertions(+), 31 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 97fffdd..e2378fe 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,13 @@
 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>
+
 	* elfnn-aarch64.c (IS_AARCH64_TLS_RELOC): Recognize
 	BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12.
 	(aarch64_reloc_got_type): Likewise.
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index c8ad421..097a275 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2333,9 +2333,11 @@ aarch64_type_of_stub (struct bfd_link_info *info,
   globals = elf_aarch64_hash_table (info);
   via_plt_p = (globals->root.splt != NULL && hash != NULL
 	       && hash->root.plt.offset != (bfd_vma) - 1);
-
+  /* Make sure call to plt stub can fit into the branch range.  */
   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.  */
   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
 	   check distance to the right destination address.  */
 	if (via_plt_p)
-	  {
-	    value = (splt->output_section->vma
-		     + 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
-	       is too far away.  */
-	    if (! aarch64_valid_branch_p (value, place))
-	      {
-		/* The target is out of reach, so redirect the branch to
-		   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,
-							   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 = (splt->output_section->vma
+		   + splt->output_offset + h->plt.offset);
+
+	/* 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))
+	  /* 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 = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
 						   signed_addend, weak_undef_p);
+      *unresolved_reloc_p = FALSE;
       break;
 
     case BFD_RELOC_AARCH64_16_PCREL:
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index dae1cbb..9b16f25 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,14 @@
 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>
+
 	* ld-aarch64/emit-relocs-529.s: New testcase.
 	* ld-aarch64/emit-relocs-529-overflow.s: Likewise.
 	* ld-aarch64/emit-relocs-86.s: Likewise.
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index c8a8aae..b87b198 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -127,6 +127,9 @@ 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-gsym"
+run_dump_test "farcall-b-plt"
+run_dump_test "farcall-bl-plt"
 run_dump_test "farcall-bl"
 run_dump_test "farcall-b"
 run_dump_test "farcall-b-none-function"
diff --git a/ld/testsuite/ld-aarch64/farcall-b-gsym.d b/ld/testsuite/ld-aarch64/farcall-b-gsym.d
new file mode 100644
index 0000000..eced18e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-b-gsym.d
@@ -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'.*
diff --git a/ld/testsuite/ld-aarch64/farcall-b-gsym.s b/ld/testsuite/ld-aarch64/farcall-b-gsym.s
new file mode 100644
index 0000000..b7bfe23
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-b-gsym.s
@@ -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
diff --git a/ld/testsuite/ld-aarch64/farcall-b-plt.d b/ld/testsuite/ld-aarch64/farcall-b-plt.d
new file mode 100644
index 0000000..9e2c891
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-b-plt.d
@@ -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
+	...
diff --git a/ld/testsuite/ld-aarch64/farcall-b-plt.s b/ld/testsuite/ld-aarch64/farcall-b-plt.s
new file mode 100644
index 0000000..227f5f1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-b-plt.s
@@ -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
diff --git a/ld/testsuite/ld-aarch64/farcall-bl-plt.d b/ld/testsuite/ld-aarch64/farcall-bl-plt.d
new file mode 100644
index 0000000..205a810
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-bl-plt.d
@@ -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
+	...
diff --git a/ld/testsuite/ld-aarch64/farcall-bl-plt.s b/ld/testsuite/ld-aarch64/farcall-bl-plt.s
new file mode 100644
index 0000000..2cb0dd0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-bl-plt.s
@@ -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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]