summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/elfnn-aarch64.c47
-rw-r--r--ld/testsuite/ld-aarch64/aarch64-elf.exp13
-rw-r--r--ld/testsuite/ld-aarch64/morello-dynamic-got.d12
-rw-r--r--ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.d20
-rw-r--r--ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.s41
-rw-r--r--ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn2.d14
-rw-r--r--ld/testsuite/ld-aarch64/morello-dynamic-local-got.d16
-rw-r--r--ld/testsuite/ld-aarch64/morello-dynamic-local-got.s23
-rw-r--r--ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s9
-rw-r--r--ld/testsuite/ld-aarch64/morello-static-got.d13
-rw-r--r--ld/testsuite/ld-aarch64/morello-static-got.s12
-rw-r--r--ld/testsuite/ld-aarch64/no-morello-syms-static.d13
12 files changed, 218 insertions, 15 deletions
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 80abb38c6bf..88573828da7 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -7211,6 +7211,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
off = symbol_got_offset (input_bfd, h, r_symndx);
base_got = globals->root.sgot;
+ bfd_boolean is_dynamic = elf_hash_table (info)->dynamic_sections_created;
bfd_boolean c64_reloc =
(bfd_r_type == BFD_RELOC_MORELLO_LD128_GOT_LO12_NC
|| bfd_r_type == BFD_RELOC_MORELLO_ADR_GOT_PAGE);
@@ -7235,8 +7236,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
{
bfd_vma addend = 0;
bfd_vma frag_value;
- bfd_boolean is_dynamic
- = elf_hash_table (info)->dynamic_sections_created;
/* If a symbol is not dynamic and is not undefined weak, bind it
locally and generate a RELATIVE relocation under PIC mode.
@@ -7404,7 +7403,12 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
{
rtype = MORELLO_R (RELATIVE);
- if (bfd_link_executable (info) && !bfd_link_pic (info))
+ /* Ensure that Morello RELATIVE relocations for static non-PIE
+ binaries are all stored in the same input section. This is
+ done so that we can mark that section with
+ __rela_dyn_{start,end} symbols for the runtime to find and
+ initialise relocations with. */
+ if (bfd_link_executable (info) && !is_dynamic)
s = globals->srelcaps;
outrel.r_addend = signed_addend;
@@ -9073,7 +9077,7 @@ aarch64_elf_init_got_section (bfd *abfd, struct bfd_link_info *info)
}
/* Track capability initialisation for static non-PIE binaries. */
- if (bfd_link_executable (info) && !bfd_link_pic (info)
+ if (bfd_link_executable (info) && !globals->root.dynamic_sections_created
&& globals->srelcaps == NULL)
globals->srelcaps = globals->root.srelgot;
@@ -10211,18 +10215,26 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
h->got.offset = htab->root.sgot->size;
htab->root.sgot->size += GOT_ENTRY_SIZE (htab);
- if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- || h->root.type != bfd_link_hash_undefweak)
- && (bfd_link_pic (info)
- || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
- /* Undefined weak symbol in static PIE resolves to 0 without
- any dynamic relocations. */
- && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+ if (((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (bfd_link_pic (info)
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+ /* Undefined weak symbol in static PIE resolves to 0 without
+ any dynamic relocations. */
+ && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+ /* Any capability relocations required in a dynamic binary
+ should go in the srelgot. */
+ || ((got_type == GOT_CAP) && dyn))
{
htab->root.srelgot->size += RELOC_SIZE (htab);
}
- else if (bfd_link_executable (info) && !bfd_link_pic (info))
- htab->srelcaps->size += RELOC_SIZE (htab);
+ else if (bfd_link_executable (info) && (got_type == GOT_CAP))
+ {
+ /* If we have a capability relocation that is not handled by the
+ case above then this must be a statically linked executable. */
+ BFD_ASSERT (!bfd_link_pic (info) && !dyn);
+ htab->srelcaps->size += RELOC_SIZE (htab);
+ }
}
else
{
@@ -10568,8 +10580,13 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd,
htab->root.srelgot->size += RELOC_SIZE (htab);
}
/* Static binary; put relocs into srelcaps. */
- else if (bfd_link_executable (info) && (got_type & GOT_CAP))
+ else if (bfd_link_executable (info)
+ && !htab->root.dynamic_sections_created
+ && (got_type & GOT_CAP))
htab->srelcaps->size += RELOC_SIZE (htab);
+ /* Else capability relocation needs to go into srelgot. */
+ else if (got_type & GOT_CAP)
+ htab->root.srelgot->size += RELOC_SIZE (htab);
}
else
{
@@ -10595,7 +10612,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd,
info);
if (bfd_link_executable (info)
- && !bfd_link_pic (info)
+ && !htab->root.dynamic_sections_created
&& htab->srelcaps
&& htab->srelcaps->size > 0)
{
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index a65fff67522..ba0b65a8aba 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -274,6 +274,17 @@ run_dump_test_lp64 "morello-sizeless-got-syms"
run_dump_test_lp64 "morello-disallow-merged-binaries"
run_dump_test_lp64 "c64-ehdr-sized-reloc"
+# Test for morello dynamic relocs can not be written in the usual manner since
+# we need to specify different `ld` command lines for different objects.
+if { [ld_assemble_flags $as -march=morello+c64 $srcdir/$subdir/morello-dynamic-relocs-lib.s tmpdir/morello-dynamic-relocs-lib.o]
+ && [ld_link $ld tmpdir/morello-dynamic-relocs.so "--shared tmpdir/morello-dynamic-relocs-lib.o"] } {
+ 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-static-got"
+run_dump_test_lp64 "morello-dynamic-got"
run_dump_test_lp64 "morello-dt-init-fini"
run_dump_test_lp64 "morello-capinit"
run_dump_test_lp64 "morello-stubs"
@@ -292,6 +303,8 @@ run_dump_test_lp64 "morello-tlsdesc"
run_dump_test_lp64 "morello-tlsdesc-static"
run_dump_test_lp64 "morello-tlsdesc-staticpie"
+run_dump_test "no-morello-syms-static"
+
run_dump_test "reloc-overflow-bad"
# test addend correctness when --emit-relocs specified for non-relocatable obj.
diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-got.d b/ld/testsuite/ld-aarch64/morello-dynamic-got.d
new file mode 100644
index 00000000000..810eb1033ef
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-dynamic-got.d
@@ -0,0 +1,12 @@
+# This testcase is just to exercise some code rather than to test for an
+# observable. We may as well check that the __rela_dyn_start symbol does not
+# exists.
+#source: morello-static-got.s
+#as: -march=morello+c64
+#ld: -shared
+#readelf: --symbols
+
+#failif
+#...
+.* __rela_dyn_start
+#...
diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.d b/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.d
new file mode 100644
index 00000000000..ee25827e8aa
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.d
@@ -0,0 +1,20 @@
+# Test here is to ensure that __rela_dyn_* symbols are not emitted for
+# dynamically linked objects. The code that was acting when we noticed this
+# problem was correctly avoiding the behaviour for shared objects, but not for
+# dynamically linked PDE's. Hence that's what this testcase is added for.
+#
+# N.b. aarch64-elf.exp compiles a shared libary for this test under
+# tmpdir/morello-dynamic-relocs.so. We use that shared library for the test in
+# the `ld` command below.
+#
+# This testcase is written partly to ensure a particular code path is
+# exercised. That is the purpose of the local `val` symbol that we have a GOT
+# relocation to.
+#as: -march=morello+c64
+#ld: tmpdir/morello-dynamic-relocs.so
+#readelf: --symbols
+
+#failif
+#...
+.* __rela_dyn_start
+#...
diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.s b/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.s
new file mode 100644
index 00000000000..3cffb35a8b8
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn.s
@@ -0,0 +1,41 @@
+ .arch morello+crc+c64
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+.LFB0:
+ .cfi_startproc purecap
+ adrp c0, :got:weakval
+ ldr c0, [c0, #:got_lo12:weakval]
+ adrp c0, :got:globval
+ ldr c0, [c0, #:got_lo12:globval]
+ adrp c0, :got:val
+ ldr c0, [c0, #:got_lo12:val]
+ adrp c0, :got:var
+ ldr c0, [c0, #:got_lo12:var]
+ str wzr, [c0]
+ ret
+ .cfi_endproc
+.LFE0:
+ .size _start, .-_start
+.data
+ .type val, %object
+val:
+ .byte 0x42
+ .byte 0x42
+ .byte 0x42
+ .size val, .-val
+ .chericap val
+ .global globval
+globval:
+ .byte 0x1
+ .byte 0x1
+ .byte 0x1
+ .size globval, .-globval
+ .weak weakval
+weakval:
+ .byte 0x1
+ .byte 0x1
+ .byte 0x1
+ .size weakval, .-weakval
diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn2.d b/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn2.d
new file mode 100644
index 00000000000..9de0c5f4f36
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-dynamic-link-rela-dyn2.d
@@ -0,0 +1,14 @@
+# This testcase ensures that we have the expected number and type of
+# relocations in our resultant binary.
+#source: morello-dynamic-link-rela-dyn.s
+#as: -march=morello+c64
+#ld: tmpdir/morello-dynamic-relocs.so
+#readelf: --relocs
+
+Relocation section '\.rela\.dyn' at offset .* contains 5 entries:
+ Offset Info Type Sym\. Value Sym\. Name \+ Addend
+.* 00000000e803 R_MORELLO_RELATIV 0
+.* 00000000e803 R_MORELLO_RELATIV 0
+.* 00000000e803 R_MORELLO_RELATIV 0
+.* 00000000e803 R_MORELLO_RELATIV 0
+.* 00010000e801 R_MORELLO_GLOB_DA 0000000000000000 var \+ 0
diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-local-got.d b/ld/testsuite/ld-aarch64/morello-dynamic-local-got.d
new file mode 100644
index 00000000000..3b607c9c325
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-dynamic-local-got.d
@@ -0,0 +1,16 @@
+# This testcase is written mostly to ensure a particular code path is
+# exercised. That is the purpose of the local `x` symbol that we have a GOT
+# relocation to.
+#
+# There is no particular observable for this code path -- a relocation is put
+# in one input section rather than another (though both input sections have the
+# same output section). May as well check that the __rela_dyn_* symbols are
+# not emitted, since this is a dynamic symbol.
+#as: -march=morello+crc+c64
+#ld: tmpdir/morello-dynamic-relocs.so
+#readelf: --symbols
+
+#failif
+#...
+.* __rela_dyn_start
+#...
diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-local-got.s b/ld/testsuite/ld-aarch64/morello-dynamic-local-got.s
new file mode 100644
index 00000000000..e846bb7422c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-dynamic-local-got.s
@@ -0,0 +1,23 @@
+ .text
+ .global x
+ .bss
+ .align 2
+ .type x, %object
+ .size x, 4
+x:
+ .zero 4
+ .text
+ .align 2
+ .global _start
+ .type _start, %function
+_start:
+.LFB0:
+ .cfi_startproc purecap
+ adrp c0, :got:x
+ ldr c0, [c0, #:got_lo12:x]
+ ldr w0, [c0]
+ ret
+ .cfi_endproc
+.LFE0:
+ .size _start, .-_start
+
diff --git a/ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s b/ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s
new file mode 100644
index 00000000000..80e84e5bc84
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-dynamic-relocs-lib.s
@@ -0,0 +1,9 @@
+ .arch morello+crc+c64
+ .text
+ .global var
+ .bss
+ .align 2
+ .type var, %object
+ .size var, 4
+var:
+ .zero 4
diff --git a/ld/testsuite/ld-aarch64/morello-static-got.d b/ld/testsuite/ld-aarch64/morello-static-got.d
new file mode 100644
index 00000000000..0e24d97f2d1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-static-got.d
@@ -0,0 +1,13 @@
+# This testcase is just to exercise some code rather than to test for an
+# observable. We may as well check that the __rela_dyn_start symbol exists.
+#as: -march=morello+c64
+#ld: -static
+#readelf: --symbols --relocs
+
+Relocation section '\.rela\.dyn' at offset .* contains 1 entry:
+ Offset Info Type Sym\. Value Sym\. Name \+ Addend
+.* 00000000e803 R_MORELLO_RELATIV 0
+
+#...
+.* __rela_dyn_start
+#...
diff --git a/ld/testsuite/ld-aarch64/morello-static-got.s b/ld/testsuite/ld-aarch64/morello-static-got.s
new file mode 100644
index 00000000000..2a4e410bb46
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-static-got.s
@@ -0,0 +1,12 @@
+.data
+val:
+ .byte 0x42
+ .byte 0x42
+ .byte 0x42
+ .size val, .-val
+
+.text
+.global _start
+_start:
+ ldr c0, [c0, :got_lo12:val]
+
diff --git a/ld/testsuite/ld-aarch64/no-morello-syms-static.d b/ld/testsuite/ld-aarch64/no-morello-syms-static.d
new file mode 100644
index 00000000000..e1b495b34a4
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/no-morello-syms-static.d
@@ -0,0 +1,13 @@
+# The emit-relocs-28 test was creating space for unnecessary relocations and
+# correspondingly adding the __rela_dyn_{start,end} symbols to span them.
+# This was happening because of Morello changes which applied on non-Morello
+# links by mistake. This testcase is to ensure that that does not happen.
+#source: emit-relocs-28.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] --defsym globala=0x11000 --defsym globalb=0x45000 --defsym globalc=0x1234 -e0 --emit-relocs
+#readelf: --symbols
+
+#failif
+#...
+.* __rela_dyn_start
+#...