[PATCH v2] aarch64: Emit jump slot for conditional branches to weak_undef

Siddhesh Poyarekar siddhesh@gotplt.org
Fri May 15 18:23:53 GMT 2020


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



More information about the Binutils mailing list