public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] aarch64: Emit jump slot for conditional branches to weak_undef
@ 2020-05-15  2:17 Siddhesh Poyarekar
  2020-05-15 10:25 ` Nick Clifton
  0 siblings, 1 reply; 6+ messages in thread
From: Siddhesh Poyarekar @ 2020-05-15  2:17 UTC (permalink / raw)
  To: binutils; +Cc: rearnsha, Kyrylo.Tkachov

The linker silently writes out a conditional branch to 0 if the
target symbol in R_AARCH64_CONDBR19 or R_AARCH64_TSTBR14 relocations is
undefined.  Emit a PLT instead so that behaviour is the same for these
relocations as the llvm linker.

The special behaviour for undefined weak symbols, where conditional
branches to such symbols result in a branch unto themselves, has been
retained.  This is because the weak-undefined.s test explicitly checks
for that, leading me to conclude that it's expected behaviour.

bfd/ChangeLog:

2020-05-15  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

	* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Club
	BFD_RELOC_AARCH64_BRANCH19 and BFD_RELOC_AARCH64_TSTBR14
	cases with BFD_RELOC_AARCH64_JUMP26.
	(elfNN_aarch64_check_relocs): Likewise.

ld/ChangeLog:

2020-05-15  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

	* testsuite/ld-aarch64/aarch64-elf.exp: New test
	emit-relocs-560.
	* testsuite/ld-aarch64/emit-relocs-560.d: New file.
	* testsuite/ld-aarch64/emit-relocs-560.s: New file.

---

 bfd/elfnn-aarch64.c                       | 22 +++++++++--
 ld/testsuite/ld-aarch64/aarch64-elf.exp   |  1 +
 ld/testsuite/ld-aarch64/emit-relocs-560.d | 47 +++++++++++++++++++++++
 ld/testsuite/ld-aarch64/emit-relocs-560.s |  3 ++
 4 files changed, 69 insertions(+), 4 deletions(-)
 create mode 100644 ld/testsuite/ld-aarch64/emit-relocs-560.d
 create mode 100644 ld/testsuite/ld-aarch64/emit-relocs-560.s

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 4bb5707d2f..02df893fcd 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -5494,6 +5494,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
   bfd_vma orig_value = value;
   bfd_boolean resolved_to_zero;
   bfd_boolean abs_symbol_p;
+  bfd_boolean via_plt_p;
 
   globals = elf_aarch64_hash_table (info);
 
@@ -5515,6 +5516,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 		  : bfd_is_und_section (sym_sec));
   abs_symbol_p = h != NULL && bfd_is_abs_symbol (&h->root);
 
+  via_plt_p = (globals->root.splt != NULL && h != NULL
+	       && h->plt.offset != (bfd_vma) - 1);
 
   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
      it here if it is defined in a non-shared object.  */
@@ -5850,12 +5853,23 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 	value += signed_addend;
       break;
 
+    case BFD_RELOC_AARCH64_BRANCH19:
+    case BFD_RELOC_AARCH64_TSTBR14:
+      /* A conditional branch to an undefined weak symbol is converted to a
+	 branch to itself.  */
+      if (weak_undef_p && !via_plt_p)
+	{
+	  value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
+						       place, value,
+						       signed_addend,
+						       weak_undef_p);
+	  break;
+	}
+      /* Fall through.  */
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       {
 	asection *splt = globals->root.splt;
-	bfd_boolean via_plt_p =
-	  splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
 
 	/* A call to an undefined weak symbol is converted to a jump to
 	   the next instruction unless a PLT entry will be created.
@@ -5943,7 +5957,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_32:
 #endif
     case BFD_RELOC_AARCH64_ADD_LO12:
-    case BFD_RELOC_AARCH64_BRANCH19:
     case BFD_RELOC_AARCH64_LDST128_LO12:
     case BFD_RELOC_AARCH64_LDST16_LO12:
     case BFD_RELOC_AARCH64_LDST32_LO12:
@@ -5959,7 +5972,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_MOVW_G2_NC:
     case BFD_RELOC_AARCH64_MOVW_G2_S:
     case BFD_RELOC_AARCH64_MOVW_G3:
-    case BFD_RELOC_AARCH64_TSTBR14:
       value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
 						   place, value,
 						   signed_addend, weak_undef_p);
@@ -8022,6 +8034,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  }
 
+	case BFD_RELOC_AARCH64_BRANCH19:
+	case BFD_RELOC_AARCH64_TSTBR14:
 	case BFD_RELOC_AARCH64_CALL26:
 	case BFD_RELOC_AARCH64_JUMP26:
 	  /* If this is a local symbol then we resolve it
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 297a3e96db..4c44fa1642 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -236,6 +236,7 @@ run_dump_test_lp64 "emit-relocs-557"
 run_dump_test_lp64 "emit-relocs-558"
 run_dump_test_lp64 "emit-relocs-558-overflow"
 run_dump_test_lp64 "emit-relocs-559"
+run_dump_test_lp64 "emit-relocs-560"
 
 run_dump_test "reloc-overflow-bad"
 
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-560.d b/ld/testsuite/ld-aarch64/emit-relocs-560.d
new file mode 100644
index 0000000000..208aa3bbd9
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-560.d
@@ -0,0 +1,47 @@
+#source: emit-relocs-560.s
+#ld: -shared
+#objdump: -DR -j .got.plt -j .text -j .plt
+
+.*:     file format .*
+
+
+Disassembly of section .plt:
+
+00000000000001b0 <.plt>:
+ 1b0:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+ 1b4:	90000090 	adrp	x16, 10000 <foo\+0xfe10>
+ 1b8:	f9418a11 	ldr	x17, \[x16, #784\]
+ 1bc:	910c4210 	add	x16, x16, #0x310
+ 1c0:	d61f0220 	br	x17
+ 1c4:	d503201f 	nop
+ 1c8:	d503201f 	nop
+ 1cc:	d503201f 	nop
+
+00000000000001d0 <baz@plt>:
+ 1d0:	90000090 	adrp	x16, 10000 <foo\+0xfe10>
+ 1d4:	f9418e11 	ldr	x17, \[x16, #792\]
+ 1d8:	910c6210 	add	x16, x16, #0x318
+ 1dc:	d61f0220 	br	x17
+
+00000000000001e0 <bar@plt>:
+ 1e0:	90000090 	adrp	x16, 10000 <foo\+0xfe10>
+ 1e4:	f9419211 	ldr	x17, \[x16, #800\]
+ 1e8:	910c8210 	add	x16, x16, #0x320
+ 1ec:	d61f0220 	br	x17
+
+Disassembly of section .text:
+
+00000000000001f0 <foo>:
+ 1f0:	360fff80 	tbz	w0, #1, 1e0 <bar@plt>
+ 1f4:	b5fffee1 	cbnz	x1, 1d0 <baz@plt>
+
+Disassembly of section .got.plt:
+
+0000000000010300 <.got.plt>:
+	...
+   10318:	000001b0 	.*
+			10318: R_AARCH64_JUMP_SLOT	baz
+   1031c:	00000000 	.*
+   10320:	000001b0 	.*
+			10320: R_AARCH64_JUMP_SLOT	bar
+   10324:	00000000 	.*
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-560.s b/ld/testsuite/ld-aarch64/emit-relocs-560.s
new file mode 100644
index 0000000000..9529e8fd5e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-560.s
@@ -0,0 +1,3 @@
+foo:
+	tbz	x0, 1, bar
+	cbnz	x1, baz
-- 
2.17.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] aarch64: Emit jump slot for conditional branches to weak_undef
  2020-05-15  2:17 [PATCH] aarch64: Emit jump slot for conditional branches to weak_undef Siddhesh Poyarekar
@ 2020-05-15 10:25 ` Nick Clifton
  2020-05-15 18:23   ` [PATCH v2] " Siddhesh Poyarekar
  0 siblings, 1 reply; 6+ messages in thread
From: Nick Clifton @ 2020-05-15 10:25 UTC (permalink / raw)
  To: Siddhesh Poyarekar, binutils; +Cc: rearnsha

Hi Siddhesh,

> 	* testsuite/ld-aarch64/aarch64-elf.exp: New test
> 	emit-relocs-560.
> 	* testsuite/ld-aarch64/emit-relocs-560.d: New file.
> 	* testsuite/ld-aarch64/emit-relocs-560.s: New file.

This new test fails when used with an aarch64 toolchain that is
configured for a big-endian default (eg aarch64_be-elf):

  regexp_diff match failure
  regexp "^ 1b8:	f9418a11 	ldr	x17, \[x16, #784\]$"
  line   " 1b8:	f9418211 	ldr	x17, [x16, #768]"
  ...and more...

Cheers
  Nick


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2] aarch64: Emit jump slot for conditional branches to weak_undef
  2020-05-15 10:25 ` Nick Clifton
@ 2020-05-15 18:23   ` Siddhesh Poyarekar
  2020-05-18 11:47     ` Nick Clifton
  2020-05-19  8:46     ` [PATCH v3] aarch64: Emit jump slot for conditional branch to undefined symbols Siddhesh Poyarekar
  0 siblings, 2 replies; 6+ messages in thread
From: Siddhesh Poyarekar @ 2020-05-15 18:23 UTC (permalink / raw)
  To: binutils; +Cc: siddhesh, nickc, rearnsha

Hi Nick,

Sorry I missed testing on aarch64_be-linux.  I have now and fixed up the
test; although I didn't see the exact same failure.  If the PLTs still
don't match I'll switch the objdump test out for readelf instead to
ensure that the jump slot relocs are generated.

Thanks,
Siddhesh

The linker silently writes out a conditional branch to 0 if the
target symbol in R_AARCH64_CONDBR19 or R_AARCH64_TSTBR14 relocations is
undefined.  Emit a PLT instead so that behaviour is the same for these
relocations as the llvm linker.

The special behaviour for undefined weak symbols, where conditional
branches to such symbols result in a branch unto themselves, has been
retained.  This is because the weak-undefined.s test explicitly checks
for that, leading me to conclude that it's expected behaviour.

bfd/ChangeLog:

2020-05-15  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

	* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Club
	BFD_RELOC_AARCH64_BRANCH19 and BFD_RELOC_AARCH64_TSTBR14
	cases with BFD_RELOC_AARCH64_JUMP26.
	(elfNN_aarch64_check_relocs): Likewise.

ld/ChangeLog:

2020-05-15  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

	* testsuite/ld-aarch64/aarch64-elf.exp: New test
	emit-relocs-560.
	* testsuite/ld-aarch64/emit-relocs-560.d: New file.
	* testsuite/ld-aarch64/emit-relocs-560.s: New file.
---
 bfd/elfnn-aarch64.c                       | 22 +++++++++--
 ld/testsuite/ld-aarch64/aarch64-elf.exp   |  1 +
 ld/testsuite/ld-aarch64/emit-relocs-560.d | 45 +++++++++++++++++++++++
 ld/testsuite/ld-aarch64/emit-relocs-560.s |  3 ++
 4 files changed, 67 insertions(+), 4 deletions(-)
 create mode 100644 ld/testsuite/ld-aarch64/emit-relocs-560.d
 create mode 100644 ld/testsuite/ld-aarch64/emit-relocs-560.s

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 4bb5707d2f..02df893fcd 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -5494,6 +5494,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
   bfd_vma orig_value = value;
   bfd_boolean resolved_to_zero;
   bfd_boolean abs_symbol_p;
+  bfd_boolean via_plt_p;
 
   globals = elf_aarch64_hash_table (info);
 
@@ -5515,6 +5516,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 		  : bfd_is_und_section (sym_sec));
   abs_symbol_p = h != NULL && bfd_is_abs_symbol (&h->root);
 
+  via_plt_p = (globals->root.splt != NULL && h != NULL
+	       && h->plt.offset != (bfd_vma) - 1);
 
   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
      it here if it is defined in a non-shared object.  */
@@ -5850,12 +5853,23 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 	value += signed_addend;
       break;
 
+    case BFD_RELOC_AARCH64_BRANCH19:
+    case BFD_RELOC_AARCH64_TSTBR14:
+      /* A conditional branch to an undefined weak symbol is converted to a
+	 branch to itself.  */
+      if (weak_undef_p && !via_plt_p)
+	{
+	  value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
+						       place, value,
+						       signed_addend,
+						       weak_undef_p);
+	  break;
+	}
+      /* Fall through.  */
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       {
 	asection *splt = globals->root.splt;
-	bfd_boolean via_plt_p =
-	  splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
 
 	/* A call to an undefined weak symbol is converted to a jump to
 	   the next instruction unless a PLT entry will be created.
@@ -5943,7 +5957,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_32:
 #endif
     case BFD_RELOC_AARCH64_ADD_LO12:
-    case BFD_RELOC_AARCH64_BRANCH19:
     case BFD_RELOC_AARCH64_LDST128_LO12:
     case BFD_RELOC_AARCH64_LDST16_LO12:
     case BFD_RELOC_AARCH64_LDST32_LO12:
@@ -5959,7 +5972,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_MOVW_G2_NC:
     case BFD_RELOC_AARCH64_MOVW_G2_S:
     case BFD_RELOC_AARCH64_MOVW_G3:
-    case BFD_RELOC_AARCH64_TSTBR14:
       value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
 						   place, value,
 						   signed_addend, weak_undef_p);
@@ -8022,6 +8034,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  }
 
+	case BFD_RELOC_AARCH64_BRANCH19:
+	case BFD_RELOC_AARCH64_TSTBR14:
 	case BFD_RELOC_AARCH64_CALL26:
 	case BFD_RELOC_AARCH64_JUMP26:
 	  /* If this is a local symbol then we resolve it
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 297a3e96db..4c44fa1642 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -236,6 +236,7 @@ run_dump_test_lp64 "emit-relocs-557"
 run_dump_test_lp64 "emit-relocs-558"
 run_dump_test_lp64 "emit-relocs-558-overflow"
 run_dump_test_lp64 "emit-relocs-559"
+run_dump_test_lp64 "emit-relocs-560"
 
 run_dump_test "reloc-overflow-bad"
 
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-560.d b/ld/testsuite/ld-aarch64/emit-relocs-560.d
new file mode 100644
index 0000000000..2592ee4076
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-560.d
@@ -0,0 +1,45 @@
+#source: emit-relocs-560.s
+#ld: -shared
+#objdump: -DR -j .got.plt -j .text -j .plt
+
+.*:     file format .*
+
+
+Disassembly of section .plt:
+
+00000000000001b0 <.plt>:
+ 1b0:	a9bf7bf0 	stp	x16, x30, \[sp, #-16\]!
+ 1b4:	90000090 	adrp	x16, 10000 <foo\+0xfe10>
+ 1b8:	f9418a11 	ldr	x17, \[x16, #784\]
+ 1bc:	910c4210 	add	x16, x16, #0x310
+ 1c0:	d61f0220 	br	x17
+ 1c4:	d503201f 	nop
+ 1c8:	d503201f 	nop
+ 1cc:	d503201f 	nop
+
+00000000000001d0 <baz@plt>:
+ 1d0:	90000090 	adrp	x16, 10000 <foo\+0xfe10>
+ 1d4:	f9418e11 	ldr	x17, \[x16, #792\]
+ 1d8:	910c6210 	add	x16, x16, #0x318
+ 1dc:	d61f0220 	br	x17
+
+00000000000001e0 <bar@plt>:
+ 1e0:	90000090 	adrp	x16, 10000 <foo\+0xfe10>
+ 1e4:	f9419211 	ldr	x17, \[x16, #800\]
+ 1e8:	910c8210 	add	x16, x16, #0x320
+ 1ec:	d61f0220 	br	x17
+
+Disassembly of section .text:
+
+00000000000001f0 <foo>:
+ 1f0:	360fff80 	tbz	w0, #1, 1e0 <bar@plt>
+ 1f4:	b5fffee1 	cbnz	x1, 1d0 <baz@plt>
+
+Disassembly of section .got.plt:
+
+0000000000010300 <.got.plt>:
+#...
+			10318: R_AARCH64_JUMP_SLOT	baz
+#...
+			10320: R_AARCH64_JUMP_SLOT	bar
+#...
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-560.s b/ld/testsuite/ld-aarch64/emit-relocs-560.s
new file mode 100644
index 0000000000..9529e8fd5e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-560.s
@@ -0,0 +1,3 @@
+foo:
+	tbz	x0, 1, bar
+	cbnz	x1, baz
-- 
2.26.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] aarch64: Emit jump slot for conditional branches to weak_undef
  2020-05-15 18:23   ` [PATCH v2] " Siddhesh Poyarekar
@ 2020-05-18 11:47     ` Nick Clifton
  2020-05-19  8:46     ` [PATCH v3] aarch64: Emit jump slot for conditional branch to undefined symbols Siddhesh Poyarekar
  1 sibling, 0 replies; 6+ messages in thread
From: Nick Clifton @ 2020-05-18 11:47 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: binutils, rearnsha

Hi Siddhesh,

> Sorry I missed testing on aarch64_be-linux.  I have now and fixed up the
> test; although I didn't see the exact same failure.  If the PLTs still
> don't match I'll switch the objdump test out for readelf instead to
> ensure that the jump slot relocs are generated.

Hmm, that might be a good idea.  I am still getting these failures, except
that now it is for both the big-endian and little-endian versions of the
toolchain:
   regexp_diff match failure
  regexp "^ 1b8: 	f9418a11 	ldr	x17, \[x16, #784\]$"
  line    " 1b8: 	f9418211 	ldr	x17, [x16, #768]"
  regexp_diff match failure
  regexp "^ 1bc:	910c4210 	add	x16, x16, #0x310$"
  line    " 1bc:	910c0210 	add	x16, x16, #0x300"
  regexp_diff match failure
  ...and  more...

(And the exact same failures for the other toolchain too).

I am not sure what is different between my test environment and yours,
but maybe using a different dumping tool will solve the problem.

Cheers
  Nick


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3] aarch64: Emit jump slot for conditional branch to undefined symbols
  2020-05-15 18:23   ` [PATCH v2] " Siddhesh Poyarekar
  2020-05-18 11:47     ` Nick Clifton
@ 2020-05-19  8:46     ` Siddhesh Poyarekar
  2020-05-19 10:10       ` Nick Clifton
  1 sibling, 1 reply; 6+ messages in thread
From: Siddhesh Poyarekar @ 2020-05-19  8:46 UTC (permalink / raw)
  To: binutils; +Cc: siddhesh, nickc, rearnsha

The linker silently writes out a conditional branch to 0 if the
target symbol in R_AARCH64_CONDBR19 or R_AARCH64_TSTBR14 relocations is
undefined.  Emit a PLT instead so that behaviour is the same for these
relocations as the llvm linker.

The special behaviour for undefined weak symbols, where conditional
branches to such symbols result in a branch unto themselves, has been
retained.  This is because the weak-undefined.s test explicitly checks
for that, leading me to conclude that it's expected behaviour.

bfd/ChangeLog:

2020-05-19  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

	* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Club
	BFD_RELOC_AARCH64_BRANCH19 and BFD_RELOC_AARCH64_TSTBR14
	cases with BFD_RELOC_AARCH64_JUMP26.
	(elfNN_aarch64_check_relocs): Likewise.

ld/ChangeLog:

2020-05-19  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

	* testsuite/ld-aarch64/aarch64-elf.exp: New test
	emit-relocs-560.
	* testsuite/ld-aarch64/emit-relocs-560.d: New file.
	* testsuite/ld-aarch64/emit-relocs-560.s: New file.
---
 bfd/elfnn-aarch64.c                       | 22 ++++++++++++++++++----
 ld/testsuite/ld-aarch64/aarch64-elf.exp   |  1 +
 ld/testsuite/ld-aarch64/emit-relocs-560.d |  8 ++++++++
 ld/testsuite/ld-aarch64/emit-relocs-560.s |  3 +++
 4 files changed, 30 insertions(+), 4 deletions(-)
 create mode 100644 ld/testsuite/ld-aarch64/emit-relocs-560.d
 create mode 100644 ld/testsuite/ld-aarch64/emit-relocs-560.s

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 4bb5707d2f..02df893fcd 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -5494,6 +5494,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
   bfd_vma orig_value = value;
   bfd_boolean resolved_to_zero;
   bfd_boolean abs_symbol_p;
+  bfd_boolean via_plt_p;
 
   globals = elf_aarch64_hash_table (info);
 
@@ -5515,6 +5516,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 		  : bfd_is_und_section (sym_sec));
   abs_symbol_p = h != NULL && bfd_is_abs_symbol (&h->root);
 
+  via_plt_p = (globals->root.splt != NULL && h != NULL
+	       && h->plt.offset != (bfd_vma) - 1);
 
   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
      it here if it is defined in a non-shared object.  */
@@ -5850,12 +5853,23 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 	value += signed_addend;
       break;
 
+    case BFD_RELOC_AARCH64_BRANCH19:
+    case BFD_RELOC_AARCH64_TSTBR14:
+      /* A conditional branch to an undefined weak symbol is converted to a
+	 branch to itself.  */
+      if (weak_undef_p && !via_plt_p)
+	{
+	  value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
+						       place, value,
+						       signed_addend,
+						       weak_undef_p);
+	  break;
+	}
+      /* Fall through.  */
     case BFD_RELOC_AARCH64_CALL26:
     case BFD_RELOC_AARCH64_JUMP26:
       {
 	asection *splt = globals->root.splt;
-	bfd_boolean via_plt_p =
-	  splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
 
 	/* A call to an undefined weak symbol is converted to a jump to
 	   the next instruction unless a PLT entry will be created.
@@ -5943,7 +5957,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_32:
 #endif
     case BFD_RELOC_AARCH64_ADD_LO12:
-    case BFD_RELOC_AARCH64_BRANCH19:
     case BFD_RELOC_AARCH64_LDST128_LO12:
     case BFD_RELOC_AARCH64_LDST16_LO12:
     case BFD_RELOC_AARCH64_LDST32_LO12:
@@ -5959,7 +5972,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_MOVW_G2_NC:
     case BFD_RELOC_AARCH64_MOVW_G2_S:
     case BFD_RELOC_AARCH64_MOVW_G3:
-    case BFD_RELOC_AARCH64_TSTBR14:
       value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type,
 						   place, value,
 						   signed_addend, weak_undef_p);
@@ -8022,6 +8034,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  }
 
+	case BFD_RELOC_AARCH64_BRANCH19:
+	case BFD_RELOC_AARCH64_TSTBR14:
 	case BFD_RELOC_AARCH64_CALL26:
 	case BFD_RELOC_AARCH64_JUMP26:
 	  /* If this is a local symbol then we resolve it
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 297a3e96db..4c44fa1642 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -236,6 +236,7 @@ run_dump_test_lp64 "emit-relocs-557"
 run_dump_test_lp64 "emit-relocs-558"
 run_dump_test_lp64 "emit-relocs-558-overflow"
 run_dump_test_lp64 "emit-relocs-559"
+run_dump_test_lp64 "emit-relocs-560"
 
 run_dump_test "reloc-overflow-bad"
 
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-560.d b/ld/testsuite/ld-aarch64/emit-relocs-560.d
new file mode 100644
index 0000000000..153532457b
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-560.d
@@ -0,0 +1,8 @@
+#source: emit-relocs-560.s
+#ld: -shared
+#readelf: -r
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 2 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name \+ Addend
+[0-9a-f]+  000100000402 R_AARCH64_JUMP_SL 0000000000000000 baz \+ 0
+[0-9a-f]+  000200000402 R_AARCH64_JUMP_SL 0000000000000000 bar \+ 0
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-560.s b/ld/testsuite/ld-aarch64/emit-relocs-560.s
new file mode 100644
index 0000000000..9529e8fd5e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-560.s
@@ -0,0 +1,3 @@
+foo:
+	tbz	x0, 1, bar
+	cbnz	x1, baz
-- 
2.26.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] aarch64: Emit jump slot for conditional branch to undefined symbols
  2020-05-19  8:46     ` [PATCH v3] aarch64: Emit jump slot for conditional branch to undefined symbols Siddhesh Poyarekar
@ 2020-05-19 10:10       ` Nick Clifton
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Clifton @ 2020-05-19 10:10 UTC (permalink / raw)
  To: Siddhesh Poyarekar, binutils; +Cc: rearnsha

Hi Siddhesh,

  Thanks - that did it.

> bfd/ChangeLog:
> 2020-05-19  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
> 
> 	* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Club
> 	BFD_RELOC_AARCH64_BRANCH19 and BFD_RELOC_AARCH64_TSTBR14
> 	cases with BFD_RELOC_AARCH64_JUMP26.
> 	(elfNN_aarch64_check_relocs): Likewise.
> 
> ld/ChangeLog:
> 2020-05-19  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
> 
> 	* testsuite/ld-aarch64/aarch64-elf.exp: New test
> 	emit-relocs-560.
> 	* testsuite/ld-aarch64/emit-relocs-560.d: New file.
> 	* testsuite/ld-aarch64/emit-relocs-560.s: New file.
 
Approved and applied.

Cheers
  Nick


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-05-19 10:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-15  2:17 [PATCH] aarch64: Emit jump slot for conditional branches to weak_undef Siddhesh Poyarekar
2020-05-15 10:25 ` Nick Clifton
2020-05-15 18:23   ` [PATCH v2] " Siddhesh Poyarekar
2020-05-18 11:47     ` Nick Clifton
2020-05-19  8:46     ` [PATCH v3] aarch64: Emit jump slot for conditional branch to undefined symbols Siddhesh Poyarekar
2020-05-19 10:10       ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).