[PATCH] aarch64: Emit jump slot for conditional branches to weak_undef
Siddhesh Poyarekar
siddhesh@gotplt.org
Fri May 15 02:17:55 GMT 2020
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
More information about the Binutils
mailing list