I am very excited about the binary release of gcc-toolchain, but I run into problems trying to compile something as simple as:
int main()
{
return 0;
}
$ ~/morello-gnu/bin/aarch64-none-elf-gcc -march=morello -O0 -nostdlib hello.c
/home/lord/morello-gnu/bin/../lib/gcc/aarch64-none-elf/10.1.0/../../../../aarch64-none-elf/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400000
$ ~/morello-gnu/bin/aarch64-none-elf-gcc -march=morello -O0 hello.c
/home/lord/morello-gnu/bin/../lib/gcc/aarch64-none-elf/10.1.0/../../../../aarch64-none-elf/bin/ld: /home/lord/morello-gnu/bin/../lib/gcc/aarch64-none-elf/10.1.0/../../../../aarch64-none-elf/lib/hybridcap/libc.a(lib_a-exit.o): in function `exit':
/data/jenkins/workspace/GNU-toolchain/morello-trunk/src/newlib-cygwin/newlib/libc/stdlib/exit.c:70: undefined reference to `_exit'
/home/lord/morello-gnu/bin/../lib/gcc/aarch64-none-elf/10.1.0/../../../../aarch64-none-elf/bin/ld: /home/lord/morello-gnu/bin/../lib/gcc/aarch64-none-elf/10.1.0/../../../../aarch64-none-elf/lib/hybridcap/crt0.o: in function `_start':
/data/jenkins/workspace/GNU-toolchain/morello-trunk/src/newlib-cygwin/libgloss/aarch64/crt0.S:360: undefined reference to `__init_global_caps'
/home/lord/morello-gnu/bin/../lib/gcc/aarch64-none-elf/10.1.0/../../../../aarch64-none-elf/bin/ld: /data/jenkins/workspace/GNU-toolchain/morello-trunk/src/newlib-cygwin/libgloss/aarch64/crt0.S:361: undefined reference to `__processRelocs'
/home/lord/morello-gnu/bin/../lib/gcc/aarch64-none-elf/10.1.0/../../../../aarch64-none-elf/bin/ld: /data/jenkins/workspace/GNU-toolchain/morello-trunk/src/newlib-cygwin/libgloss/aarch64/crt0.S:365: undefined reference to `initialise_monitor_handles'
collect2: error: ld returned 1 exit status
Any suggestions on what I am doing wrong?
Also, I think it mentions that pure and hybrid capabilities modes are supported, but I could not find option to specify which one to use.
Thanks!
Vadim
--
Senior Research Associate
Department of Computer Science and Technology
University of Cambridge
http://zaliva.org/
I am trying to rung GCC-produced binaries under qemu, with no success. Here is what I did:
dummy.c:
#include <stdio.h>
int main()
{
fprintf(stderr,"hello world!\n");
}
$ ~/morello-gnu/bin/aarch64-none-elf-gcc -march=morello+c64 -mabi=purecap -specs=aem-ve.specs -O0 tests/cheri/dummy.c -o dummy
$ file dummy
dummy: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, with debug_info, not stripped
$ ~/cheri/output/morello-sdk/bin/qemu-system-morello -M virt,gic-version=3 -cpu morello -m 2048 -nographic -device virtio-rng-pci -bios dummy
At this point, qemu hangs up eating a lot of CPU and has to be killed.
Any suggestions on how I can run the binaries?
Vadim
--
Senior Research Associate
Department of Computer Science and Technology
University of Cambridge
http://zaliva.org/
Originally this clause included lines checking `!bfd_link_pic &&
bfd_link_executable`. I left these in to ensure that the new Morello
part to the clause did not interfere with the original stock AArch64
part of the clause.
Now we have split the condition into multiple if statements for clarity,
we can remove the confusing parts of the clause. This clause is to
catch any symbols that go in the GOT but would not be otherwise given a
relocation by finish_dynamic_symbol. We can express that check better
with a modified condition.
What we want to do in this clause is to account for all GOT entries
which would not get a dynamic relocation otherwise, but need a RELATIVE
dynamic relocation for Morello. This is any symbol for which
c64_should_not_relocate is false and WILL_CALL_FINISH_DYNAMIC_SYMBOL is
false. Changing the clause to only mention these two predicates (plus
ensuring that we do not mess around with such relocations when creating
a relocatable object file rather than a final binary) explains the
purpose of this condition much better.
N.b. see the commit message of 8f5baae3d15 for the reasoning for the
original decision to not change the conditional.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index bb17f18e498ae3118c70636b8e6318511b9a0ccd..6d45d5d68a3213bf7f22710271a39e1478b745c5 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -7276,10 +7276,9 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
This clause catches the case when we're not relocating for
GOT, or when we're relocating an undefined weak symbol. */
}
- else if (!bfd_link_pic (info)
+ else if (!bfd_link_relocatable (info)
&& !WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic,
bfd_link_pic (info), h)
- && bfd_link_executable (info)
&& !symbol_got_offset_mark_p (input_bfd, h, r_symndx))
{
/* This clause is here to catch any c64 entries in the GOT which
morello-binutils: Use global GOT type to determine GOT action
In final_link_relocate we currently use whether the relocation we're
looking at is a Morello relocation to decide whether we should treat the
GOT entry as a Morello GOT entry or not.
This is problematic since we can have an AArch64 relocation against a
capability GOT entry (even if it isn't a very useful thing to have).
The current patch decides whether we need to emit a MORELLO RELATIVE
relocation in the GOT based on whether the GOT as a whole contains
capabilities rather than based on whether the first relocation against
this GOT is a Morello relocation.
Until now we did not see any problem from this. Here we add a testcase
that triggers the problem.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 68c88bce0b475a6af2097c3993f9a5753a774fdb..244b837f4458051fc0bce7e878a63a0b5278c26b 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -7220,9 +7220,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
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);
if (signed_addend != 0)
{
@@ -7267,9 +7264,9 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
BFD_ASSERT (!WILL_CALL_FINISH_DYNAMIC_SYMBOL
(is_dynamic, bfd_link_pic (info), h));
relative_reloc = TRUE;
- c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE;
+ c64_needs_frag_fixup = globals->c64_rel ? TRUE : FALSE;
}
- else if (!c64_reloc || !c64_needs_relocation (info, h))
+ else if (!globals->c64_rel || !c64_needs_relocation (info, h))
{
/* Symbol references via GOT in C64 should always have
relocations of some kind unless they are undefined weak
@@ -7308,7 +7305,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
c64_needs_frag_fixup = TRUE;
}
- if (c64_reloc
+ if (globals->c64_rel
&& c64_symbol_adjust (h, value, sym_sec, info, &frag_value))
signed_addend = (value | h->target_internal) - frag_value;
else
@@ -7354,7 +7351,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
{
bfd_vma frag_value;
- if (c64_reloc
+ if (globals->c64_rel
&& c64_symbol_adjust (h, value, sym_sec, info, &frag_value))
signed_addend = (value | sym->st_target_internal) - frag_value;
else
@@ -7375,7 +7372,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
dynamic relocations). */
if (bfd_link_pic (info)
|| (!bfd_link_pic (info) && bfd_link_executable (info)
- && c64_reloc))
+ && globals->c64_rel))
{
/* We have not handled the case for weak undefined symbols in
this clause. That is because we believe there can not be
@@ -7390,7 +7387,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
would not see it in this clause. */
BFD_ASSERT (!weak_undef_p);
relative_reloc = TRUE;
- c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE;
+ c64_needs_frag_fixup = globals->c64_rel ? TRUE : FALSE;
}
symbol_got_offset_mark (input_bfd, h, r_symndx);
@@ -7410,7 +7407,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
if (c64_needs_frag_fixup)
{
- BFD_ASSERT (c64_reloc);
+ BFD_ASSERT (globals->c64_rel);
/* For a C64 relative relocation, also add size and permissions into
the frag. */
bfd_reloc_status_type ret;
@@ -7433,7 +7430,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
s = globals->root.srelgot;
- if (c64_reloc)
+ if (globals->c64_rel)
{
rtype = MORELLO_R (RELATIVE);
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 95c0e1bfec10bfb3810d88c5ae27c279dcbbb3b5..5af3bbfa84151cbfca25dd5580407def9387fba0 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -281,6 +281,7 @@ run_dump_test_lp64 "emit-relocs-morello-6b"
run_dump_test_lp64 "emit-relocs-morello-7"
run_dump_test_lp64 "emit-relocs-morello-8"
run_dump_test_lp64 "emit-relocs-morello-9"
+run_dump_test_lp64 "emit-relocs-morello-10"
run_dump_test_lp64 "emit-relocs-morello-hidden"
run_dump_test_lp64 "emit-morello-reloc-markers-1"
run_dump_test_lp64 "emit-morello-reloc-markers-2"
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-10.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-10.d
new file mode 100644
index 0000000000000000000000000000000000000000..9f423e8b2adff0e331d9e6340ffe85c6c4f5ac5c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-10.d
@@ -0,0 +1,12 @@
+# Checking that we have two RELATIVE relocations, indicating that both the
+# CAPINIT and the GOT entry were given a RELATIVE relocation. As opposed to
+# before when the linker generated one RELATIVE relocation and an
+# R_AARCH64_NONE relocation.
+#as: -march=morello+c64
+#ld:
+#readelf: --relocs
+
+Relocation section '\.rela\.dyn' at offset .* contains 2 entries:
+ Offset Info Type Sym\. Value Sym\. Name \+ Addend
+[0-9a-f]+ [0-9a-f]+ R_MORELLO_RELATIV 0
+[0-9a-f]+ [0-9a-f]+ R_MORELLO_RELATIV 0
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-10.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-10.s
new file mode 100644
index 0000000000000000000000000000000000000000..b04bfe8d17aa291abaed77f9c547f4e9d2a8c36f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-10.s
@@ -0,0 +1,21 @@
+ .data
+str:
+ .string "Hello there big bad world!"
+ .size str,.-str
+ .global ptr
+ptr:
+ .8byte str
+ .align 4
+ .type cap STT_OBJECT
+ .global cap
+cap:
+ .chericap str
+
+ .text
+ .globl _start
+ .type _start STT_FUNC
+_start:
+ ldr x2, [x2, :got_lo12:cap]
+ adrp c2, :got:cap
+ ldr c2, [c2, :got_lo12:cap]
+ ldr c2, [x2, :got_lo12:cap]
Originally we believed we had accounted for these symbols within the
existing if conditional. It turns out that with `-pie
--no-dynamic-linker` on the command line (which causes the `link_info`
member `dynamic_undefined_weak` to be set to 0) such symbols can bypass
elfNN_aarch64_allocate_dynrelocs putting these symbols into the dynamic
symbol table. Hence we can have such symbols without a dynamic index
and our existing conditionals need to be adjusted.
On further inspection we notice that GOT entries for *hidden* undefined
weak symbols were still getting RELATIVE relocations. This is quite
unnecessary since it's known that the entry should be the NULL
capability, but on top of that it relies on the runtime to have a
special case to not add the load displacement to RELATIVE relocations
with completely zero fragments.
We make two logical adjustments.
The first is that in our handling of CAPINIT relocations we add a
clause to avoid emitting a relocation for any undefined weak symbol
which we know for certain should end up with the NULL capability at
runtime. In this clause we ensure that the fragment is completely zero.
The second is around handling GOT entries. For these we ensure that
elfNN_aarch64_allocate_dynrelocs does not allocate a dynamic relocation
for the GOT entry of such symbols and that
elfNN_aarch64_final_link_relocate leaves the GOT entry empty and without
any relocation.
N.b. in implementing this change the conditionals became quite
confusing. We split them up quite unnecessarily into different else/if
statements for clarity at the expense of verbosity.
We also add tests to check the behaviour of undefined weak symbols for
dynamically linked PDE's/PIE's/static executables/shared objects.
N.b.2 We also add an extra assert in final_link_relocate. This function
deals with GOT entries for symbols both in the internal hash table and
not in the hash table. Binutils decides whether symbols should be in
the hash table or not based on their binding. WEAK binding symbols are
put in the hash table. That said, final_link_relocate has a
`weak_undef_p` local flag to describe whether a given symbol is weak
undefined or not. This flag is defined for both symbols in the hash
table and symbols not in the hash table.
I believe that the only time we have weak_undef_p set in
final_link_relocate when the relevant symbol is not in the hash table is
when we have "removed" a relocation from our work list by modifying it
to be a R_AARCH64_NONE relocation against the STN_UNDEF symbol (e.g.
during TLS relaxation).
Such cases would not fall into the GOT relocation clause. Hence I don't
think we can ever see weak_undef_p symbols which are not in the hash
table in this clause. It's worth an assertion to catch the possibility
that this is wrong.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index dd1c28ad7e4352d9407b1b7a1d863a0cb293a9a4..68c88bce0b475a6af2097c3993f9a5753a774fdb 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -292,6 +292,16 @@
(((htab)->root.srelplt == NULL) ? 0 \
: (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE (htab))
+/* The only time that we want the value of a symbol but do not want a
+ relocation for it in Morello is when that symbol is undefined weak. In this
+ case we just need the zero capability and there's no point emitting a
+ relocation for it when we can get an untagged zero capability by just
+ loading some zeros. */
+#define c64_needs_relocation(info, h) \
+ (!((h)->root.type == bfd_link_hash_undefweak \
+ && (UNDEFWEAK_NO_DYNAMIC_RELOC ((info), (h)) \
+ || !elf_hash_table ((info))->dynamic_sections_created)))
+
/* The first entry in a procedure linkage table looks like this
if the distance between the PLTGOT and the PLT is < 4GB use
these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
@@ -7240,58 +7250,61 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
NOTE: one symbol may be referenced by several relocations, we
should only generate one RELATIVE relocation for that symbol.
- Therefore, check GOT offset mark first.
-
- NOTE2: Symbol references via GOT in C64 should always have
- relocations of some kind. Here we try to catch any such GOT
- reference which would not otherwise be caught by
- finish_dynamic_symbol. */
- if (((h->dynindx == -1
- && !h->forced_local
- && h->root.type != bfd_link_hash_undefweak
- && bfd_link_pic (info))
- || (!bfd_link_pic (info)
- && !WILL_CALL_FINISH_DYNAMIC_SYMBOL
- (is_dynamic, bfd_link_pic (info), h)
- && bfd_link_executable (info) && c64_reloc))
+ Therefore, check GOT offset mark first. */
+ if (h->dynindx == -1
+ && !h->forced_local
+ && h->root.type != bfd_link_hash_undefweak
+ && bfd_link_pic (info)
&& !symbol_got_offset_mark_p (input_bfd, h, r_symndx))
{
- /* If we would call finish_dynamic_symbol for this symbol then we
- should not be introducing a relocation for the GOT entry
- (that function handles creating relocations for the GOT entry
- in the usual case, this bit of code is to handle special
- cases where the relocation would not otherwise be generated).
- */
+ /* Here we look for symbols which are not going to have their
+ relocations added by finish_dynamic_symbol, but which still
+ need a dynamic relocation because we're compiling for PIC.
+
+ Action on this clause and the one below is the same.
+ Written that way to make the three different cases and their
+ interpretation clear. */
BFD_ASSERT (!WILL_CALL_FINISH_DYNAMIC_SYMBOL
(is_dynamic, bfd_link_pic (info), h));
relative_reloc = TRUE;
c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE;
}
- /* If this is a dynamic symbol that binds locally then the generic
- code and elfNN_aarch64_finish_dynamic_symbol will already handle
- creating the RELATIVE reloc pointing into the GOT for this symbol.
- That means that this function does not need to handle *creating*
- such a relocation. This function does already handle setting the
- base value as the fragment for that relocation, hence we should
- ensure that we set the fragment correctly for C64 code (i.e.
- including the required permissions and bounds). */
- else if (c64_reloc
- && WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic,
- bfd_link_pic (info), h)
+ else if (!c64_reloc || !c64_needs_relocation (info, h))
+ {
+ /* Symbol references via GOT in C64 should always have
+ relocations of some kind unless they are undefined weak
+ symbols which cannot be provided at runtime. In those cases
+ we need a plain zero.
+
+ This clause catches the case when we're not relocating for
+ GOT, or when we're relocating an undefined weak symbol. */
+ }
+ else if (!bfd_link_pic (info)
+ && !WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic,
+ bfd_link_pic (info), h)
+ && bfd_link_executable (info)
+ && !symbol_got_offset_mark_p (input_bfd, h, r_symndx))
+ {
+ /* This clause is here to catch any c64 entries in the GOT which
+ need a relocation, but whose relocation will not be provided
+ by finish_dynamic_symbol. */
+ relative_reloc = TRUE;
+ c64_needs_frag_fixup = TRUE;
+ }
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dynamic,
+ bfd_link_pic (info), h)
&& bfd_link_pic (info)
&& SYMBOL_REFERENCES_LOCAL (info, h))
{
- /* We believe that if `h` were undefined weak it would not have
- SYMBOL_REFERENCES_LOCAL return true. However this is not 100%
- clear based purely on the members that we check in the code.
- The reason it matters is if we could have a
- SYMBOL_REFERENCES_LOCAL symbol which is also
- !UNDEFWEAK_NO_DYNAMIC_RELOC then the check above would
- determine that we need to fix up the fragment for the RELATIVE
- relocation that elfNN_aarch64_finish_dynamic_symbol will
- create, but in actual fact elfNN_aarch64_finish_dynamic_symbol
- would not create that relocation. */
- BFD_ASSERT (!UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+ /* If this is a dynamic symbol that binds locally then the
+ generic code and elfNN_aarch64_finish_dynamic_symbol will
+ already handle creating the RELATIVE reloc pointing into the
+ GOT for this symbol. That means that this function does not
+ need to handle *creating* such a relocation. We already
+ handle setting the base value in the fragment for that
+ relocation below, but we also need to make sure we set the
+ rest of the fragment correctly for C64 code (i.e. including
+ the required permissions and bounds). */
c64_needs_frag_fixup = TRUE;
}
@@ -7364,6 +7377,18 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|| (!bfd_link_pic (info) && bfd_link_executable (info)
&& c64_reloc))
{
+ /* We have not handled the case for weak undefined symbols in
+ this clause. That is because we believe there can not be
+ weak undefined symbols as we reach this clause. We believe
+ that any symbol with WEAK binding in an object file would be
+ put into the hash table (and hence go into the `h != NULL`
+ clause above). The only time that `weak_undef_p` should be
+ set for something not in the hash table is when we have
+ removed a relocation by marking it as against the undefined
+ symbol (e.g. during TLS relaxation). We only ever do that
+ while also setting the relocation to R_AARCH64_NONE, so we
+ would not see it in this clause. */
+ BFD_ASSERT (!weak_undef_p);
relative_reloc = TRUE;
c64_needs_frag_fixup = c64_reloc ? TRUE : FALSE;
}
@@ -7613,12 +7638,25 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
outrel.r_addend = signed_addend;
+ if (h && !c64_needs_relocation (info, h))
+ {
+ /* If we know this symbol does not need a C64 dynamic relocation
+ then it must be because this is an undefined weak symbol which
+ can not find a definition at runtime.
+
+ To handle that we just ensure that we've put a zero into the
+ binary file at this point and mark the relocation as resolved.
+ */
+ value = 0;
+ *unresolved_reloc_p = FALSE;
+ break;
+ }
/* Emit a dynamic relocation if we are handling a symbol which the
dynamic linker will be told about. */
- if (h != NULL
- && h->dynindx != -1
- && globals->root.dynamic_sections_created
- && !SYMBOL_REFERENCES_LOCAL (info, h))
+ else if (h != NULL
+ && h->dynindx != -1
+ && globals->root.dynamic_sections_created
+ && !SYMBOL_REFERENCES_LOCAL (info, h))
{
outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
/* Dynamic symbols will be handled by the dynamic loader. Hence
@@ -9674,6 +9712,10 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
break;
case BFD_RELOC_MORELLO_CAPINIT:
+ if (h && !c64_needs_relocation (info, h))
+ /* If this symbol does not need a relocation, then there's no
+ reason to increase the srelcaps size for a relocation. */
+ break;
if (htab->srelcaps == NULL)
{
if (htab->root.dynobj == NULL)
@@ -10232,23 +10274,37 @@ 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))
- /* Any capability relocations required in a dynamic binary
- should go in the srelgot. */
- || (htab->c64_rel && dyn))
+
+ 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))
+ {
+ htab->root.srelgot->size += RELOC_SIZE (htab);
+ }
+ else if (!htab->c64_rel || !c64_needs_relocation (info, h))
+ {
+ /* Either not relocating for C64, and hence all problematic
+ relocations are handled above, or this is an undefined weak
+ symbol that we know will not be resolved to anything by the
+ runtime do not need a relocation. */
+ }
+ else if (dyn)
{
+ /* Any capability relocations required in a dynamic binary
+ should go in the srelgot. N.b. many capability relocations
+ would be caught by the first clause in this if chain. */
htab->root.srelgot->size += RELOC_SIZE (htab);
}
- else if (bfd_link_executable (info) && htab->c64_rel)
+ else if (bfd_link_executable (info))
{
/* If we have a capability relocation that is not handled by the
- case above then this must be a statically linked executable. */
+ case above then this must be a statically linked executable.
+ We want capability relocations in a statically linked
+ executable to go in the srelcaps section. */
BFD_ASSERT (!bfd_link_pic (info) && !dyn);
htab->srelcaps->size += RELOC_SIZE (htab);
}
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 235df2872084b5115239b671c5107b56a36b446f..f6d579dab0ad88ee9e778a09cf7e3bf69a2f0be7 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -301,6 +301,15 @@ if { [ld_assemble_flags $as -march=morello+c64 $srcdir/$subdir/morello-dynamic-r
run_dump_test_lp64 "morello-dataptr-code-and-data"
}
+if { [ld_assemble_flags $as -march=morello+c64 $srcdir/$subdir/morello-weakdefinitions.s tmpdir/morello-weakdefinitions.o]
+ && [ld_link $ld tmpdir/morello-weakdefinitions.so "--shared tmpdir/morello-weakdefinitions.o"] } {
+ run_dump_test_lp64 "morello-undefweak-relocs-PDE"
+}
+run_dump_test_lp64 "morello-undefweak-relocs-no-dyn-linker"
+run_dump_test_lp64 "morello-undefweak-relocs-PIE"
+run_dump_test_lp64 "morello-undefweak-relocs-static"
+run_dump_test_lp64 "morello-undefweak-relocs-static-relocs"
+
run_dump_test_lp64 "morello-static-got"
run_dump_test_lp64 "morello-dynamic-got"
run_dump_test_lp64 "morello-dt-init-fini"
diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PDE.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PDE.d
new file mode 100644
index 0000000000000000000000000000000000000000..a209418cf2406e2d64afd95f6092c45c9122aec5
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PDE.d
@@ -0,0 +1,61 @@
+# Exercise a corner case of handling morello GOT relocations against weak undef
+# symbols.
+#
+# What we want to check is:
+# 1) The adrp/ldr insns point to the relevant entries in the GOT.
+# 2) There are relocations for all except the hidden weak undef symbol in the
+# GOT (the only symbol which can never be given a value at runtime since
+# it is hidden).
+# 3) The GOT entry for this weak undefined symbol is zero.
+# 4) The values in .data are initialized as zero.
+# 5) There are relocations to initialize the non-hidden .data variables and
+# no relocation to initialize the value of the hidden symbol.
+#
+# (1) is checked by ensuring that the adrp/ldr combinations point to increments
+# of 0x10 past the start of the got section.
+# (2) and (3) are checked by the fact that objdump prints nothing except
+# relocations for the non-hidden symbols after the first line in the .got
+# section.
+# (4) and (5) is checked by the fact that objdump prints nothing except
+# relocations for the non-hidden symbols for the data section contents.
+#source: morello-undefweak-relocs.s
+#as: -march=morello+c64
+#ld: tmpdir/morello-weakdefinitions.so
+#objdump: -DR -j .got -j .data -j .text
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <_start>:
+#record: GOTPAGE
+.* adrp c0, ([0-9a-f]+) .*
+#record: GOTOFFSET
+.* ldr c0, \[c0, #([0-9]+)\]
+#check: PAGEG string tolower $GOTPAGE
+#check: GOTOFF2 expr "$GOTOFFSET - 0x10"
+#check: GOTOFF3 expr "$GOTOFFSET - 0x20"
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF2\]
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF3\]
+.* ret c30
+
+Disassembly of section \.got:
+
+.* <_GLOBAL_OFFSET_TABLE_>:
+#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"]
+#check: GOTGLOBAL format %x [expr "0x$GOTPAGE + $GOTOFFSET"]
+#check: GOTLOCAL format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x20"]
+ *GOTSTART: .*
+ \.\.\.
+ GOTLOCAL: R_MORELLO_GLOB_DAT localsym
+ GOTGLOBAL: R_MORELLO_GLOB_DAT globalsym
+
+Disassembly of section \.data:
+
+.* <.*>:
+ \.\.\.
+ [0-9a-f]*: R_MORELLO_CAPINIT globalsym
+ [0-9a-f]*: R_MORELLO_CAPINIT localsym
diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PIE.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PIE.d
new file mode 100644
index 0000000000000000000000000000000000000000..1ef2021def59fd021599acbbc0df4cf4916a3c73
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-PIE.d
@@ -0,0 +1,61 @@
+# Exercise a corner case of handling morello GOT relocations against weak undef
+# symbols.
+#
+# What we want to check is:
+# 1) The adrp/ldr insns point to the relevant entries in the GOT.
+# 2) There are relocations for all except the hidden weak undef symbol in the
+# GOT (the only symbol which can never be given a value at runtime since
+# it is hidden).
+# 3) The GOT entry for this weak undefined symbol is zero.
+# 4) The values in .data are initialized as zero.
+# 5) There are relocations to initialize the non-hidden .data variables and
+# no relocation to initialize the value of the hidden symbol.
+#
+# (1) is checked by ensuring that the adrp/ldr combinations point to increments
+# of 0x10 past the start of the got section.
+# (2) and (3) are checked by the fact that objdump prints nothing except
+# relocations for the non-hidden symbols after the first line in the .got
+# section.
+# (4) and (5) is checked by the fact that objdump prints nothing excepet
+# relocations for the non-hidden symbols for the data section contents.
+#source: morello-undefweak-relocs.s
+#as: -march=morello+c64
+#ld: -pie
+#objdump: -DR -j .got -j .data -j .text
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <_start>:
+#record: GOTPAGE
+.* adrp c0, ([0-9a-f]+) .*
+#record: GOTOFFSET
+.* ldr c0, \[c0, #([0-9]+)\]
+#check: PAGEG string tolower $GOTPAGE
+#check: GOTOFF2 expr "$GOTOFFSET - 0x10"
+#check: GOTOFF3 expr "$GOTOFFSET - 0x20"
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF2\]
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF3\]
+.* ret c30
+
+Disassembly of section \.got:
+
+.* <.got>:
+#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"]
+#check: GOTGLOBAL format %x [expr "0x$GOTPAGE + $GOTOFFSET"]
+#check: GOTLOCAL format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x20"]
+ *GOTSTART: .*
+ \.\.\.
+ GOTLOCAL: R_MORELLO_GLOB_DAT localsym
+ GOTGLOBAL: R_MORELLO_GLOB_DAT globalsym
+
+Disassembly of section \.data:
+
+.* <.*>:
+ \.\.\.
+ [0-9a-f]*: R_MORELLO_CAPINIT globalsym
+ [0-9a-f]*: R_MORELLO_CAPINIT localsym
diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-no-dyn-linker.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-no-dyn-linker.d
new file mode 100644
index 0000000000000000000000000000000000000000..8e562d41f9d3c87fa48dcd524fcb4d95ec765a83
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-no-dyn-linker.d
@@ -0,0 +1,50 @@
+# Exercise a corner case of handling morello GOT relocations against weak undef
+# symbols.
+#
+# What we want to check is:
+# 1) The adrp/ldr insns point to the relevant entries in the GOT.
+# 2) There are no relocations in the GOT.
+# 3) The GOT entries used by these weak undefined symbols are all zero.
+# 4) The values in .data are all zero.
+#
+# (1) is checked by ensuring that the adrp/ldr combinations point to increments
+# of 0x10 past the start of the got section.
+# (2) and (3) are checked by the fact that objdump prints nothing after the
+# first entry in the .got section (the pointer to the dynamic section).
+# (4) is checked by the fact that objdump prints nothing for the data section
+# contents.
+#source: morello-undefweak-relocs.s
+#as: -march=morello+c64
+#ld: -pie --no-dynamic-linker
+#objdump: -DR -j .got -j .data -j .text
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <_start>:
+#record: GOTPAGE
+.* adrp c0, ([0-9a-f]+) .*
+#record: GOTOFFSET
+.* ldr c0, \[c0, #([0-9]+)\]
+#check: PAGEG string tolower $GOTPAGE
+#check: GOTOFF2 expr "$GOTOFFSET - 0x10"
+#check: GOTOFF3 expr "$GOTOFFSET - 0x20"
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF2\]
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF3\]
+.* ret c30
+
+Disassembly of section \.got:
+
+.* <.got>:
+#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"]
+ GOTSTART: .*
+ \.\.\.
+
+Disassembly of section \.data:
+
+.* <.*>:
+ \.\.\.
diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static-relocs.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static-relocs.d
new file mode 100644
index 0000000000000000000000000000000000000000..7c81233db93d4a462c1792dc94fbe1e9fb13f532
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static-relocs.d
@@ -0,0 +1,16 @@
+# Exercise handling morello relocations against weak undef symbols.
+#
+# What we want to check is:
+# 1) The adrp/ldr instructions point to entries in the GOT.
+# 2) There are no relocations in the GOT.
+# 3) The GOT entries for weak undefined symbols are zero.
+# 4) The values in .data are zero.
+#
+# The testcase morello-undefweak-relocs-static.d checks all except that there
+# are no relocations in the file. This testcase checks that last part.
+#source: morello-undefweak-relocs.s
+#as: -march=morello+c64
+#ld: -static
+#readelf: --relocs
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static.d b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static.d
new file mode 100644
index 0000000000000000000000000000000000000000..a7c5556d7b9d86946a346f2a0f7ccbaa2ba57bd0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs-static.d
@@ -0,0 +1,51 @@
+# Exercise handling morello relocations against weak undef symbols.
+#
+# What we want to check is:
+# 1) The adrp/ldr instructions point to entries in the GOT.
+# 2) There are no relocations in the GOT.
+# 3) The GOT entries for weak undefined symbols are zero.
+# 4) The values in .data are zero.
+#
+# (1) is checked by ensuring that the adrp/ldr combinations point to increments
+# of 0x10 past the start of the got section.
+# (3) is checked by the fact that objdump prints for the .got section.
+# (4) is checked by the fact that objdump prints nothing for the data section
+# contents.
+#
+# Since objdump refuses to print out dynamic relocations for non-dynamic
+# executables, we check (2) in a separate testcase.
+#source: morello-undefweak-relocs.s
+#as: -march=morello+c64
+#ld: -static
+#objdump: -D -j .got -j .data -j .text
+
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <_start>:
+#record: GOTPAGE
+.* adrp c0, ([0-9a-f]+) .*
+#record: GOTOFFSET
+.* ldr c0, \[c0, #([0-9]+)\]
+#check: PAGEG string tolower $GOTPAGE
+#check: GOTOFF2 expr "$GOTOFFSET - 0x10"
+#check: GOTOFF3 expr "$GOTOFFSET - 0x20"
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF2\]
+.* adrp c0, PAGEG .*
+.* ldr c0, \[c0, #GOTOFF3\]
+.* ret c30
+
+Disassembly of section \.got:
+
+#check: GOTSTART format %x [expr "0x$GOTPAGE + $GOTOFFSET - 0x30"]
+0*GOTSTART <_GLOBAL_OFFSET_TABLE_>:
+ \.\.\.
+
+Disassembly of section \.data:
+
+.* <.*>:
+ \.\.\.
diff --git a/ld/testsuite/ld-aarch64/morello-undefweak-relocs.s b/ld/testsuite/ld-aarch64/morello-undefweak-relocs.s
new file mode 100644
index 0000000000000000000000000000000000000000..7912c01aaa4fdce5ef3e8af526cfa8a0eda3d3ae
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-undefweak-relocs.s
@@ -0,0 +1,21 @@
+ .weak globalsym
+ .global globalsym
+ .weak localsym
+ .weak hiddensym
+ .hidden hiddensym
+
+ .data
+ .chericap globalsym
+ .chericap localsym
+ .chericap hiddensym
+
+ .text
+ .globl _start
+_start:
+ adrp c0, :got:globalsym
+ ldr c0, [c0, #:got_lo12:globalsym]
+ adrp c0, :got:hiddensym
+ ldr c0, [c0, #:got_lo12:hiddensym]
+ adrp c0, :got:localsym
+ ldr c0, [c0, #:got_lo12:localsym]
+ ret
diff --git a/ld/testsuite/ld-aarch64/morello-weakdefinitions.s b/ld/testsuite/ld-aarch64/morello-weakdefinitions.s
new file mode 100644
index 0000000000000000000000000000000000000000..5fba13ec7d48d5aecf0b89089689420a65a457b6
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/morello-weakdefinitions.s
@@ -0,0 +1,18 @@
+# N.b. It should not matter what is contained in this file for the tests we
+# run. What we want to show is that the behavior of weak undefined symbols is
+# correct for dynamically linked PDE's. That requires linking to a shared
+# object which is the point of this separate assembly file.
+ .global globalsym
+ .type globalsym, %object
+globalsym:
+ .xword 100
+
+ .global hiddensym
+ .type hiddensym, %object
+hiddensym:
+ .xword 100
+
+ .global localsym
+ .type localsym, %object
+localsym:
+ .xword 100
Until now CAPINIT relocations were only emitted for position independent
code. For a data relocation against a symbol in some other shared
object this was problematic since we don't know the address that said
symbol will be at. We ended up emitting a broken RELATIVE relocation.
This also happened to be problematic for function pointers, since a
CAPINIT relocation did not ensure that a PLT entry was created in this
binary. When a PLT entry was not created we again had a broken RELATIVE
relocation.
We could have fixed the problem with function pointers by ensuring that
a CAPINIT relocation caused a PLT entry to be emitted and the RELATIVE
relocation hence to point to that PLT entry. Here we choose to always
emit a CAPINIT relocation and let the dynamic linker resolve that to a
local PLT entry if one exists, but if one does not exist let the dynamic
linker resolve it to the actual function in some other shared library.
Alongside this change we ensure that we leave 0 as the value in the
fragment for a CAPINIT relocation. The dynamic linker already has to
decide which symbol to use, and it would have the value of the local
symbol available if it chooses to use it. Hence there is no reason for
the static linker to leave the value of one option in the fragment of
this CAPINIT relocation.
This patch also introduces quite a few new testcases.
These are to check that we should only add a special PLT entry as the
canonical address for pointer equality when a function pointer is
accessed via code relocations -- and we ensure this does not happen for
accessing data pointers or accesses via CAPINIT data relocations.
Outside of the new testcases, we also adjust
emit-relocs-morello-3{,-a64c}.d. These testcases checked for a CAPINIT
relocation in a shared object. Now we no longer populate that fragment
we need to adjust the testcase accordingly.
############### Attachment also inlined for ease of reply ###############
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 .*
.* <cap>:
-.*: [0-9a-f]+ .*
+ \.\.\.
.*: R_MORELLO_CAPINIT str
-.*: 00000000 .*
-.*: 0000001b .*
-.*: 02000000 .*
.* <cap2>:
- ...
+ \.\.\.
.*: 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 .*
.* <cap>:
-.*: [0-9a-f]+ .*
+ \.\.\.
.*: R_MORELLO_CAPINIT str
-.*: 00000000 .*
-.*: 0000001b .*
-.*: 02000000 .*
.* <cap2>:
- ...
+ \.\.\.
.*: 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>:
+ \.\.\.
+ 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>:
+ \.\.\.
+ 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:
+#...
+.* <memcpy@plt>:
+#...
+Disassembly of section \.got\.plt:
+#...
+.*: R_MORELLO_JUMP_SLOT memcpy
+#...
+Disassembly of section \.data:
+
+.* <p>:
+ \.\.\.
+ .*: 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:
+#...
+.* <memcpy@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:
+
+.* <p>:
+ \.\.\.
+ .*: 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:
+
+.* <p>:
+ \.\.\.
+ .*: 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
+
Each symbol that has a reference in the GOT has an associated got_type.
For capabilities we currently have a new got_type of GOT_CAP for
capability entries in the GOT.
We do not allow capability entries in the GOT for an A64 (or hybrid)
binary, and only allow capability entries in the GOT for a purecap
binary. Hence there is no need to maintain a per-symbol indication of
whether the associated GOT entry for this symbol is a capability or not.
There is already an existing flag on the hash table to indicate whether
the GOT contains capabilities or addresses. We can replace every use of
the existing GOT_CAP with a check of this flag.
Doing such a transformation means we can not express an invalid state
(there is no longer any way to express a GOT which contains some
addresses and some capabilities). It also solves a bug where we
introduce a PLT to be the canonical address of a function after having
seen a R_AARCH64_LDST128_ABS_LO12_NC relocation. The existing manner of
deciding whether an entry in the GOT should be a capability or address
based on the relocation we generated it from could not work in a binary
when we only have this relocation. It should be determined based on the
flags of the input object files we saw (i.e. are these purecap object
files or not).
N.b. this also fixes an observed problem that could have been fixed in
the existing regime. In this case the JUMP_SLOT of a PLT entry added to
be the canonical address of a function which was addressed directly in
code (with both a Morello and AArch64 relocation) had got_type of
GOT_UNKNOWN (because it was simply not marked) and hence
elfNN_aarch64_create_small_pltn_entry was generating an AArch64
relocation because the GOT entry was not GOT_CAP.
This patch also adjusts the "should this GOT contain capabilities" flag
to report yes/no based on the EF_AARCH64_CHERI_PURECAP flag of the
inputs rather than based on whether we've seen any morello relocations
pointing into the GOT.
NOTE: We do not remove the existing times where we set this flag based
on MORELLO relocations. This is left for a future patch when we look
into the handling of hybrid code and the GOT.
N.b. this required two changes in the testsuite.
morello-capinit.d required updating since the size of the GOT section
was previously incorrectly calculated. There is no GOT relocation in
this testcase, which meant that the existing method of finding the size
of the dummy first GOT entry was incorrect (gave the size of an AArch64
entry). Since the size of the GOT is now different the PCC bounds is
now different, and we hence need to update the values checking for the
PCC bounds in this testcase.
We take this opportunity to make the testcase more robust by using the
new record/check testsuite feature. This means the testcase now passes
on other targets (i.e. both bare-metal and for none-linux).
emit-relocs-morello.d had a minor change for the same reason. Since the
alignment requirement of the GOT changed this changed the start position
too. When the start position changed objdump decided not to output an
extra line of 0000000.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 76216f8f00125e8c22cacbe8b5610b4b1d105eb4..16447f15b05af3165b8bb2354437aa337ea3e304 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -3000,7 +3000,6 @@ elfNN_aarch64_mkobject (bfd *abfd)
#define GOT_TLS_GD 2
#define GOT_TLS_IE 4
#define GOT_TLSDESC_GD 8
-#define GOT_CAP 16
#define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
@@ -5915,7 +5914,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
- return GOT_CAP;
+ return GOT_NORMAL;
case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
@@ -5930,7 +5929,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
case BFD_RELOC_MORELLO_TLSDESC_CALL:
case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
- return GOT_TLSDESC_GD | GOT_CAP;
+ return GOT_TLSDESC_GD | GOT_NORMAL;
case BFD_RELOC_AARCH64_TLSDESC_ADD:
case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
@@ -6775,8 +6774,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
|| bfd_link_executable (info))
{
/* This symbol is resolved locally. */
- outrel.r_info = (elf_aarch64_hash_entry (h)->got_type
- == GOT_CAP
+ outrel.r_info = (globals->c64_rel
? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE))
: ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)));
outrel.r_addend = (h->root.u.def.value
@@ -8827,6 +8825,15 @@ elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
return TRUE;
elf_elfheader (obfd)->e_flags = in_flags;
+ /* Determine if we are linking purecap or not based on the flags of the
+ input binaries. Among other things this decides the size of GOT
+ entries. */
+ if (in_flags & EF_AARCH64_CHERI_PURECAP)
+ {
+ struct elf_aarch64_link_hash_table *globals;
+ globals = elf_aarch64_hash_table (info);
+ globals->c64_rel = 1;
+ }
if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
&& bfd_get_arch_info (obfd)->the_default)
@@ -9295,12 +9302,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case BFD_RELOC_MORELLO_CALL26:
case BFD_RELOC_MORELLO_JUMP26:
- /* For dynamic symbols record caller information so that we can
- decide what kind of PLT stubs to emit. */
- if (h != NULL)
- elf_aarch64_hash_entry (h)->got_type = GOT_CAP;
- /* Fall through. */
-
case BFD_RELOC_AARCH64_ADD_LO12:
case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
@@ -9581,9 +9582,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* We will already have issued an error message if there
is a TLS/non-TLS mismatch, based on the symbol type.
So just combine any TLS types needed. */
- if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
- && got_type != GOT_NORMAL && old_got_type != GOT_CAP
- && got_type != GOT_CAP)
+ if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL &&
+ got_type != GOT_NORMAL)
got_type |= old_got_type;
/* If the symbol is accessed by both IE and GD methods, we
@@ -9593,13 +9593,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
- /* Prefer the capability reference. */
- if ((old_got_type & GOT_CAP) && (got_type & GOT_NORMAL))
- {
- got_type &= ~GOT_NORMAL;
- got_type |= GOT_CAP;
- }
-
if (old_got_type != got_type)
{
if (h != NULL)
@@ -9623,9 +9616,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case BFD_RELOC_MORELLO_CALL26:
case BFD_RELOC_MORELLO_JUMP26:
htab->c64_rel = 1;
- if (h != NULL)
- elf_aarch64_hash_entry (h)->got_type = GOT_CAP;
-
/* Fall through. */
case BFD_RELOC_AARCH64_CALL26:
case BFD_RELOC_AARCH64_JUMP26:
@@ -10221,8 +10211,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (got_type == GOT_UNKNOWN)
{
}
- else if (got_type == GOT_NORMAL
- || got_type == GOT_CAP)
+ else if (got_type == GOT_NORMAL)
{
h->got.offset = htab->root.sgot->size;
htab->root.sgot->size += GOT_ENTRY_SIZE (htab);
@@ -10235,11 +10224,11 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
&& !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->c64_rel && dyn))
{
htab->root.srelgot->size += RELOC_SIZE (htab);
}
- else if (bfd_link_executable (info) && (got_type == GOT_CAP))
+ else if (bfd_link_executable (info) && htab->c64_rel)
{
/* If we have a capability relocation that is not handled by the
case above then this must be a statically linked executable. */
@@ -10279,7 +10268,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)
/* On Morello support only TLSDESC_GD to TLSLE relaxation;
for everything else we must emit a dynamic relocation. */
- || got_type & GOT_CAP))
+ || htab->c64_rel))
{
if (got_type & GOT_TLSDESC_GD)
{
@@ -10562,8 +10551,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd,
}
if (got_type & GOT_TLS_IE
- || got_type & GOT_NORMAL
- || got_type & GOT_CAP)
+ || got_type & GOT_NORMAL)
{
locals[i].got_offset = htab->root.sgot->size;
htab->root.sgot->size += GOT_ENTRY_SIZE (htab);
@@ -10586,17 +10574,16 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd,
htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
if (got_type & GOT_TLS_IE
- || got_type & GOT_NORMAL
- || got_type & GOT_CAP)
+ || got_type & GOT_NORMAL)
htab->root.srelgot->size += RELOC_SIZE (htab);
}
/* Static binary; put relocs into srelcaps. */
else if (bfd_link_executable (info)
&& !htab->root.dynamic_sections_created
- && (got_type & GOT_CAP))
+ && htab->c64_rel)
htab->srelcaps->size += RELOC_SIZE (htab);
/* Else capability relocation needs to go into srelgot. */
- else if (got_type & GOT_CAP)
+ else if (htab->c64_rel)
htab->root.srelgot->size += RELOC_SIZE (htab);
}
else
@@ -10917,7 +10904,7 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
{
/* If an STT_GNU_IFUNC symbol is locally defined, generate
R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
- rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP
+ rela.r_info = (htab->c64_rel
? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE))
: ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)));
rela.r_addend = (h->root.u.def.value
@@ -10927,7 +10914,7 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
else
{
/* Fill in the entry in the .rela.plt section. */
- rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP
+ rela.r_info = (htab->c64_rel
? ELFNN_R_INFO (h->dynindx, MORELLO_R (JUMP_SLOT))
: ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT)));
rela.r_addend = 0;
@@ -11047,11 +11034,8 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
}
}
- bfd_boolean is_c64 = elf_aarch64_hash_entry (h)->got_type == GOT_CAP;
-
if (h->got.offset != (bfd_vma) - 1
- && (elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL
- || elf_aarch64_hash_entry (h)->got_type == GOT_CAP)
+ && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL
/* Undefined weak symbol in static PIE resolves to 0 without
any dynamic relocations. */
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
@@ -11104,7 +11088,7 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
bfd_vma value = h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset;
- if (is_c64)
+ if (htab->c64_rel)
{
rela.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE));
bfd_vma base_value = 0;
@@ -11127,7 +11111,8 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
bfd_put_NN (output_bfd, (bfd_vma) 0,
htab->root.sgot->contents + h->got.offset);
rela.r_info = ELFNN_R_INFO (h->dynindx,
- (is_c64 ? MORELLO_R (GLOB_DAT)
+ (htab->c64_rel
+ ? MORELLO_R (GLOB_DAT)
: AARCH64_R (GLOB_DAT)));
rela.r_addend = 0;
}
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello.d b/ld/testsuite/ld-aarch64/emit-relocs-morello.d
index 4613b776edbe5b900386da94b450b3f16d416440..1a9be9b60bb9fcf15d74e65e9ebe224ac3d769b8 100644
--- a/ld/testsuite/ld-aarch64/emit-relocs-morello.d
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello.d
@@ -21,7 +21,7 @@ Disassembly of section .got:
.* <.got>:
.*: [0-9a-f]+ .*
-.*: 00000000 .*
+ \.\.\.
Disassembly of section .data:
diff --git a/ld/testsuite/ld-aarch64/morello-capinit.d b/ld/testsuite/ld-aarch64/morello-capinit.d
index 0050df311ac03275d00d69bb57ad7ab48f92eeea..edb0f42d9eeb83e4cd81018ab3de1932d07bbb45 100644
--- a/ld/testsuite/ld-aarch64/morello-capinit.d
+++ b/ld/testsuite/ld-aarch64/morello-capinit.d
@@ -1,6 +1,6 @@
-# This testsuite is used largely to check our handling of linker script defined
+# This testcase is used largely to check our handling of linker script defined
# symbols. In the general case we want to be able to access the entire output
-# section following this symbol (i.e. we treat this symbol as a start symbol).
+# section following the symbol (i.e. we treat the symbol as a start symbol).
#
# There is an exception for a symbol that points into an executable section --
# we want this to have the bounds of the PCC as we see it.
@@ -8,6 +8,12 @@
# There is also an exception for a symbol which is *outside* of an output
# section where we have a compatibility hack to try and guess whether it
# represents the start of the next section or end of the previous section.
+#
+# Rather than check the PCC bounds exactly, we check that the PCC bounds are
+# consistent for all symbols pointing into the text section (which allows for
+# variation between aarch64-linux-gnu and aarch64-none-elf coming from an extra
+# GNU_HASH section or a differing start position of the text causing a
+# differing bounds action).
#source: morello-capinit.s
#as: -march=morello+c64
#ld: -static -pie -T morello-capinit.ld
@@ -22,35 +28,37 @@ Disassembly of section \.inspectionsection:
.*: [0-9a-f]+ .*
.*: R_MORELLO_RELATIVE \*ABS\*
.*: 00000000 .*
-.*: 00000278 .*
+#record: PCC_BOUNDS
+.*: ([0-9a-f]+) .*
.*: 04000000 .*
+#check: PCC_SIZE string tolower $PCC_BOUNDS
[0-9a-f]+ <ct_start>:
.*: [0-9a-f]+ .*
.*: R_MORELLO_RELATIVE \*ABS\*
.*: 00000000 .*
-.*: 00000278 .*
+.*: PCC_SIZE .*
.*: 04000000 .*
[0-9a-f]+ <ct1_start>:
.*: [0-9a-f]+ .*
.*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
.*: 00000000 .*
-.*: 00000278 .*
+.*: PCC_SIZE .*
.*: 04000000 .*
[0-9a-f]+ <ct1_end>:
.*: [0-9a-f]+ .*
.*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
.*: 00000000 .*
-.*: 00000278 .*
+.*: PCC_SIZE .*
.*: 04000000 .*
[0-9a-f]+ <ct_end>:
.*: [0-9a-f]+ .*
.*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+
.*: 00000000 .*
-.*: 00000278 .*
+.*: PCC_SIZE .*
.*: 04000000 .*
[0-9a-f]+ <cd_outer_start>: