From: Matthew Malcomson Date: Fri, 1 Jul 2022 10:48:56 +0000 (+0100) Subject: Use global GOT type to determine GOT action X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6497edeafcf4c296b7ab393bc50dfb4476124b77;p=thirdparty%2Fbinutils-gdb.git Use global GOT type to determine GOT action 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. --- diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index ac13ce98f3d..a215f6bf833 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -7223,9 +7223,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, base_got = globals->root.sgot; bool is_dynamic = elf_hash_table (info)->dynamic_sections_created; - bool 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) { @@ -7270,9 +7267,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 @@ -7311,7 +7308,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 @@ -7357,7 +7354,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 @@ -7378,7 +7375,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 @@ -7393,7 +7390,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); @@ -7413,7 +7410,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; @@ -7436,7 +7433,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 1a99fa4a84b..683f27779c2 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 00000000000..9f423e8b2ad --- /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 00000000000..b04bfe8d17a --- /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]