diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 16447f15b05af3165b8bb2354437aa337ea3e304..dd1c28ad7e4352d9407b1b7a1d863a0cb293a9a4 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -7611,36 +7611,53 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, if (outrel.r_offset & 0xf) return bfd_reloc_overflow; - bfd_reloc_status_type ret; - - ret = c64_fixup_frag (input_bfd, info, bfd_r_type, sym, h, sym_sec, - input_section, hit_data + 8, value, - signed_addend, rel->r_offset); - - if (ret != bfd_reloc_continue) - return ret; - outrel.r_addend = signed_addend; - value |= (h != NULL ? h->target_internal : sym->st_target_internal); - /* Emit a dynamic relocation if we are building PIC. */ + /* Emit a dynamic relocation if we are handling a symbol which the + dynamic linker will be told about. */ if (h != NULL && h->dynindx != -1 - && bfd_link_pic (info) + && globals->root.dynamic_sections_created && !SYMBOL_REFERENCES_LOCAL (info, h)) - outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); + { + outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); + /* Dynamic symbols will be handled by the dynamic loader. Hence + there is no need to fill a fragment with a value even if there + is a value that we would use assuming no interception. */ + value = 0; + } else - outrel.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE)); - - /* Symbols without size information get bounds to the - whole section: adjust the base of the capability to the - start of the section and set the addend to obtain the - correct address for the symbol. */ - bfd_vma new_value; - if (c64_symbol_adjust (h, value, sym_sec, info, &new_value)) { - outrel.r_addend += (value - new_value); - value = new_value; + /* This relocation will point into the object we are building + (either because this is a statically linked executable and + hence there is only one object it could point at, or because + we know it will resolve locally even though this is + dynamically linked). + + Hence we want to emit a RELATIVE relocation rather than a + CAPINIT one. */ + bfd_reloc_status_type ret; + + value |= (h != NULL ? h->target_internal : sym->st_target_internal); + ret = c64_fixup_frag (input_bfd, info, bfd_r_type, sym, h, sym_sec, + input_section, hit_data + 8, value, + signed_addend, rel->r_offset); + + if (ret != bfd_reloc_continue) + return ret; + + outrel.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE)); + + /* Symbols without size information get bounds to the + whole section: adjust the base of the capability to the + start of the section and set the addend to obtain the + correct address for the symbol. */ + bfd_vma new_value; + if (c64_symbol_adjust (h, value, sym_sec, info, &new_value)) + { + outrel.r_addend += (value - new_value); + value = new_value; + } } asection *s = globals->srelcaps; diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 19070408e990abbe50050b1cba183a6e4bf24934..235df2872084b5115239b671c5107b56a36b446f 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -91,6 +91,15 @@ proc aarch64_required_func_addend { base result } { return [format %x [expr "0x$result + 1 - 0x$base"]]; } +# Return the hexadecimal addition of the two given values. Values should be +# provided in hexadecimal without the leading 0x prefix. +# +# Used in a testsuite to check that the combination of some ADRP/ADD constants +# do indeed point at a variable later on in the dump. +proc aarch64_page_plus_offset { page offset } { + return [format %x [expr "0x$page + 0x$offset"] ]; +} + set eh-frame-merge-lp64 [list [list "EH Frame merge" \ [concat "-m " [aarch64_choose_lp64_emul] \ " -Ttext 0x8000"] \ @@ -282,6 +291,14 @@ if { [ld_assemble_flags $as -march=morello+c64 $srcdir/$subdir/morello-dynamic-r run_dump_test_lp64 "morello-dynamic-link-rela-dyn" run_dump_test_lp64 "morello-dynamic-link-rela-dyn2" run_dump_test_lp64 "morello-dynamic-local-got" + run_dump_test_lp64 "morello-funcptr-in-code" + run_dump_test_lp64 "morello-funcptr-through-data" + run_dump_test_lp64 "morello-funcptr-through-data-pie" + run_dump_test_lp64 "morello-funcptr-code-and-data" + run_dump_test_lp64 "morello-dataptr-in-code" + run_dump_test_lp64 "morello-dataptr-through-data" + run_dump_test_lp64 "morello-dataptr-through-data-pie" + run_dump_test_lp64 "morello-dataptr-code-and-data" } run_dump_test_lp64 "morello-static-got" diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-3-a64c.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-3-a64c.d index d596a53df90e6a73ee950e91187ecf72c86d7e13..f57aa48ca3feb1ab75d6162bb4c882ef0c86309f 100644 --- a/ld/testsuite/ld-aarch64/emit-relocs-morello-3-a64c.d +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-3-a64c.d @@ -36,12 +36,9 @@ Disassembly of section .data: .*: 00000000 .* .* : -.*: [0-9a-f]+ .* + \.\.\. .*: R_MORELLO_CAPINIT str -.*: 00000000 .* -.*: 0000001b .* -.*: 02000000 .* .* : - ... + \.\.\. .*: R_MORELLO_CAPINIT str2 diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-3.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-3.d index fe248be367e98bc0720042b0c2ed9bab76427c86..7266ca94469966d71ef5fc3e6104f02125a74a08 100644 --- a/ld/testsuite/ld-aarch64/emit-relocs-morello-3.d +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-3.d @@ -36,12 +36,9 @@ Disassembly of section .data: .*: 00000000 .* .* : -.*: [0-9a-f]+ .* + \.\.\. .*: R_MORELLO_CAPINIT str -.*: 00000000 .* -.*: 0000001b .* -.*: 02000000 .* .* : - ... + \.\.\. .*: R_MORELLO_CAPINIT str2 diff --git a/ld/testsuite/ld-aarch64/morello-dataptr-code-and-data.d b/ld/testsuite/ld-aarch64/morello-dataptr-code-and-data.d new file mode 100644 index 0000000000000000000000000000000000000000..6d19f2310ebc2d7ea53821247f0989e3b38b60f8 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dataptr-code-and-data.d @@ -0,0 +1,35 @@ +# Want to double-check that when creating a PDE which loads a data pointer +# in an external library using an adrp/ldr code sequence and also via a CAPINIT +# relocation, we generate both a COPY relocation and a CAPINIT relocation. +# +# We want to make sure the COPY relocation is used by the text. We can not +# check that the dynamic loader would initialize the CAPINIT relocation with +# the address of that COPY relocation, so that's left. +#as: -march=morello+c64 +#ld: tmpdir/morello-dynamic-relocs.so +#objdump: -dR -j .data -j .bss -j .text + +.*: file format .* + + +Disassembly of section \.text: + +.* <_start>: +#record: PAGE +.*: .* adrp c0, ([0-9a-f]*).* +#record: OFFSET +.*: .* add c0, c0, #0x([0-9a-f]*) +.*: .* ldr w0, \[c0\] +.*: .* ret c30 + +Disassembly of section \.data: +#... + .*: R_MORELLO_CAPINIT var + +Disassembly of section \.bss: + +#check: VAR_LOCATION aarch64_page_plus_offset $PAGE $OFFSET +0*VAR_LOCATION : + \.\.\. + VAR_LOCATION: R_AARCH64_COPY var + diff --git a/ld/testsuite/ld-aarch64/morello-dataptr-code-and-data.s b/ld/testsuite/ld-aarch64/morello-dataptr-code-and-data.s new file mode 100644 index 0000000000000000000000000000000000000000..85ae06b69093839674540cd69e9779b0a62fec18 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dataptr-code-and-data.s @@ -0,0 +1,16 @@ + .arch morello+crc+c64 + .text + .p2align 4,,11 + .global _start + .type _start, %function +_start: + .cfi_startproc purecap + adrp c0, var + add c0, c0, #:lo12:var + ldr w0, [c0] + ret + .cfi_endproc + .size _start, .-_start + .data +varptr: + .chericap var diff --git a/ld/testsuite/ld-aarch64/morello-dataptr-in-code.d b/ld/testsuite/ld-aarch64/morello-dataptr-in-code.d new file mode 100644 index 0000000000000000000000000000000000000000..4f54626d9b0699f8df0fb3670ff2de782690a620 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dataptr-in-code.d @@ -0,0 +1,31 @@ +# Want to double-check that when creating a PDE which references a data pointer +# in an external library in code with an adrp/add, we generate a COPY +# relocation and access that the data said relocation will initialize. +# +# We check this by ensuring that there is a new `var` symbol in the .bss of the +# PDE, that the adrp/add addresses point to that symbol, and that there is a +# COPY relocation at that symbol for its initialisation. +#as: -march=morello+c64 +#ld: tmpdir/morello-dynamic-relocs.so +#objdump: -dR -j .plt -j .bss -j .text + +.*: file format .* + + +Disassembly of section \.text: + +.* <_start>: +#record: PAGE +.*: .* adrp c0, ([0-9a-f]*).* +#record: OFFSET +.*: .* add c0, c0, #0x([0-9a-f]*) +.*: .* ldr w0, \[c0\] +.*: .* ret c30 + +Disassembly of section \.bss: + +#check: VAR_LOCATION aarch64_page_plus_offset $PAGE $OFFSET +0*VAR_LOCATION : + \.\.\. + VAR_LOCATION: R_AARCH64_COPY var + diff --git a/ld/testsuite/ld-aarch64/morello-dataptr-in-code.s b/ld/testsuite/ld-aarch64/morello-dataptr-in-code.s new file mode 100644 index 0000000000000000000000000000000000000000..9babed420907e8a71b2a5e052dacfc2e443f78f7 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dataptr-in-code.s @@ -0,0 +1,13 @@ + .arch morello+crc+c64 + .text + .p2align 4,,11 + .global _start + .type _start, %function +_start: + .cfi_startproc purecap + adrp c0, var + add c0, c0, #:lo12:var + ldr w0, [c0] + ret + .cfi_endproc + .size _start, .-_start diff --git a/ld/testsuite/ld-aarch64/morello-dataptr-through-data-pie.d b/ld/testsuite/ld-aarch64/morello-dataptr-through-data-pie.d new file mode 100644 index 0000000000000000000000000000000000000000..2270c33557617ac02d4291a7cb07299316446ce8 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dataptr-through-data-pie.d @@ -0,0 +1,12 @@ +# Want to double-check that when creating a PIE which loads a data pointer +# in an external library using a CAPINIT relocation we end up with a +# straight-forward CAPINIT relocation in the final binary requesting the +# dynamic loader to provide a capability pointing to that bit of data. +#source: morello-dataptr-through-data.s +#as: -march=morello+c64 +#ld: -pie tmpdir/morello-dynamic-relocs.so +#readelf: --relocs + +Relocation section '\.rela\.dyn' at offset .* contains 1 entry: + Offset Info Type Sym\. Value Sym\. Name \+ Addend +.* .* R_MORELLO_CAPINIT .* var \+ 0 diff --git a/ld/testsuite/ld-aarch64/morello-dataptr-through-data.d b/ld/testsuite/ld-aarch64/morello-dataptr-through-data.d new file mode 100644 index 0000000000000000000000000000000000000000..0c42017ae48fea415d02e74c1b7a94c609d81183 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dataptr-through-data.d @@ -0,0 +1,11 @@ +# Want to double-check that when creating a PDE which loads a data pointer +# in an external library using a CAPINIT relocation we end up with a +# straight-forward CAPINIT relocation in the final binary requesting the +# dynamic loader to provide a capability pointing to that bit of data. +#as: -march=morello+c64 +#ld: tmpdir/morello-dynamic-relocs.so +#readelf: --relocs + +Relocation section '\.rela\.dyn' at offset .* contains 1 entry: + Offset Info Type Sym\. Value Sym\. Name \+ Addend +.* .* R_MORELLO_CAPINIT .* var \+ 0 diff --git a/ld/testsuite/ld-aarch64/morello-dataptr-through-data.s b/ld/testsuite/ld-aarch64/morello-dataptr-through-data.s new file mode 100644 index 0000000000000000000000000000000000000000..9b56a256f4bdc9c4e9810260c71444d82b8fd1f6 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-dataptr-through-data.s @@ -0,0 +1,13 @@ + .arch morello+crc+c64 + .text + .p2align 4,,11 + .global _start + .type _start, %function +_start: + .cfi_startproc purecap + ret + .cfi_endproc + .size _start, .-_start + .data +varptr: + .chericap var diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s b/ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s index 80e84e5bc847a99b21c1da515749a3362842a641..2b4e058cc0383e0dbb98ca8fdf7e97fab92bb3da 100644 --- a/ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s +++ b/ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s @@ -1,5 +1,11 @@ .arch morello+crc+c64 .text + .p2align 4,,11 + .global memcpy + .type memcpy,%function +memcpy: + ret + .size memcpy, .-memcpy .global var .bss .align 2 diff --git a/ld/testsuite/ld-aarch64/morello-funcptr-code-and-data.d b/ld/testsuite/ld-aarch64/morello-funcptr-code-and-data.d new file mode 100644 index 0000000000000000000000000000000000000000..c8cfff8268e940d2bfc4a7f669c8c9e3e595cf26 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-funcptr-code-and-data.d @@ -0,0 +1,26 @@ +# Want to double-check that when creating a PDE which references a function +# pointer in an external library with a CAPINIT and also references the +# function pointer in code with an adrp/add, we generate a CAPINIT +# entry in that PDE and also generate a PLT entry. +# We check this by ensuring that there is a memcpy@plt entry in the PLT, that +# there is the associated MORELLO jump slot relocation in the .got.plt, and +# there is a CAPINIT relocation. +#as: -march=morello+c64 +#ld: tmpdir/morello-dynamic-relocs.so +#objdump: -dR -j .plt -j .data -j .got.plt + +.*: file format .* + +Disassembly of section \.plt: +#... +.* : +#... +Disassembly of section \.got\.plt: +#... +.*: R_MORELLO_JUMP_SLOT memcpy +#... +Disassembly of section \.data: + +.*

: + \.\.\. + .*: R_MORELLO_CAPINIT memcpy diff --git a/ld/testsuite/ld-aarch64/morello-funcptr-code-and-data.s b/ld/testsuite/ld-aarch64/morello-funcptr-code-and-data.s new file mode 100644 index 0000000000000000000000000000000000000000..489fa7c114f190433f98c411549a8574e91777f2 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-funcptr-code-and-data.s @@ -0,0 +1,21 @@ + .arch morello+crc+c64 + .text + .p2align 4,,11 + .global _start + .type _start, %function +_start: + .cfi_startproc purecap + adrp c0, memcpy + ldr c0, [c0, #:lo12:memcpy] + ldr w0, [c0] + ret + .cfi_endproc + .size _start, .-_start + .global p + .section .data.rel,"aw" + .align 4 + .type p, %object + .size p, 16 +p: + .chericap memcpy + diff --git a/ld/testsuite/ld-aarch64/morello-funcptr-in-code.d b/ld/testsuite/ld-aarch64/morello-funcptr-in-code.d new file mode 100644 index 0000000000000000000000000000000000000000..9bcb7d3397ad3a3527bf8e542884706f8e0bb954 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-funcptr-in-code.d @@ -0,0 +1,21 @@ +# Want to double-check that when creating a PDE which loads a function pointer +# in an external library using an adrp/ldr code sequence, we generate a PLT +# entry in that PDE and use that PLT entry as the address that is loaded in the +# code. +# We check this by ensuring that there is a memcpy@plt entry in the PLT, and +# that the .got.plt has a MORELLO jump slot relocation in it. +#as: -march=morello+c64 +#ld: tmpdir/morello-dynamic-relocs.so +#objdump: -dR -j .plt -j .got.plt + +.*: file format .* + + +Disassembly of section \.plt: +#... +.* : +#... +Disassembly of section \.got\.plt: +#... +.*: R_MORELLO_JUMP_SLOT memcpy +#pass diff --git a/ld/testsuite/ld-aarch64/morello-funcptr-in-code.s b/ld/testsuite/ld-aarch64/morello-funcptr-in-code.s new file mode 100644 index 0000000000000000000000000000000000000000..6bc38a12c7a6e6f90a39ce76a31b6da5d80fe023 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-funcptr-in-code.s @@ -0,0 +1,13 @@ + .text + .p2align 4,,11 + .global _start + .type _start, %function +_start: + .cfi_startproc purecap + adrp c0, memcpy + add c0, c0, #:lo12:memcpy + ldr w0, [c0] + ret + .cfi_endproc + .size _start, .-_start + diff --git a/ld/testsuite/ld-aarch64/morello-funcptr-through-data-pie.d b/ld/testsuite/ld-aarch64/morello-funcptr-through-data-pie.d new file mode 100644 index 0000000000000000000000000000000000000000..5f5b20198e911cd24a45c340568c86b2883a0d62 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-funcptr-through-data-pie.d @@ -0,0 +1,19 @@ +# Want to double-check that when creating a PIE which references a function +# pointer in an external library with a CAPINIT and does not reference the +# function pointer in code with an adrp/add, we generate a CAPINIT +# entry in that PIE and do not generate a PLT entry. +# We check this by ensuring that there is no memcpy@plt entry in the PLT, and +# by checking there is a CAPINIT relocation. +#source: morello-funcptr-through-data.s +#as: -march=morello+c64 +#ld: -pie tmpdir/morello-dynamic-relocs.so +#objdump: -dR -j .plt -j .data + +.*: file format .* + +Disassembly of section \.data: + +.*

: + \.\.\. + .*: R_MORELLO_CAPINIT memcpy + diff --git a/ld/testsuite/ld-aarch64/morello-funcptr-through-data.d b/ld/testsuite/ld-aarch64/morello-funcptr-through-data.d new file mode 100644 index 0000000000000000000000000000000000000000..1b0d13f3da79991865e6f02c1a9bcfd7d1a190b8 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-funcptr-through-data.d @@ -0,0 +1,17 @@ +# Want to double-check that when creating a PDE which references a function +# pointer in an external library with a CAPINIT and does not reference the +# function pointer in code with an adrp/add, we generate a CAPINIT +# entry in that PDE and do not generate a PLT entry. +# We check this by ensuring that there is no memcpy@plt entry in the PLT, and +# by checking there is a CAPINIT relocation. +#as: -march=morello+c64 +#ld: tmpdir/morello-dynamic-relocs.so +#objdump: -dR -j .plt -j .data + +.*: file format .* + +Disassembly of section \.data: + +.*

: + \.\.\. + .*: R_MORELLO_CAPINIT memcpy diff --git a/ld/testsuite/ld-aarch64/morello-funcptr-through-data.s b/ld/testsuite/ld-aarch64/morello-funcptr-through-data.s new file mode 100644 index 0000000000000000000000000000000000000000..1782a7fa94a22e44b1c86955a549d25afb2f4418 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-funcptr-through-data.s @@ -0,0 +1,18 @@ + .arch morello+crc+c64 + .text + .p2align 4,,11 + .global _start + .type _start, %function +_start: + .cfi_startproc purecap + ret + .cfi_endproc + .size _start, .-_start + .global p + .section .data.rel,"aw" + .align 4 + .type p, %object + .size p, 16 +p: + .chericap memcpy +