diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 92a539afcc8f3e15f3700046f6800853993657ab..3e0562b72bc69a9c43f01c80c604b85c582f4f7b 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -3049,6 +3049,13 @@ struct elf_c64_tls_data_stub_hash_entry bfd_boolean populated; }; +struct elf_c64_ifunc_capinit_record +{ + struct elf_link_hash_entry *h; + /* Number of CAPINIT relocations this hash entry has against it. */ + unsigned long count; +}; + /* Used to build a map of a section. This is required for mixed-endian code/data. */ @@ -3349,6 +3356,11 @@ struct elf_aarch64_link_hash_table bfd_boolean c64_output; htab_t c64_tls_data_stub_hash_table; void * tls_data_stub_memory; + + /* Used for CAPINIT relocations on a STT_GNU_IFUNC symbols in a static PDE. + * */ + htab_t c64_ifunc_capinit_hash_table; + void * c64_ifunc_capinit_memory; }; /* Create an entry in an AArch64 ELF linker hash table. */ @@ -3535,6 +3547,55 @@ c64_tls_stub_find (struct elf_link_hash_entry *h, return (struct elf_c64_tls_data_stub_hash_entry *)ret; } +static hashval_t +c64_ifunc_capinit_hash (const void *ptr) +{ + struct elf_c64_ifunc_capinit_record *entry + = (struct elf_c64_ifunc_capinit_record *) ptr; + return htab_hash_pointer (entry->h); +} + +static int +c64_ifunc_capinit_eq (const void *ptr1, const void *ptr2) +{ + struct elf_c64_ifunc_capinit_record *entry1 + = (struct elf_c64_ifunc_capinit_record *) ptr1; + struct elf_c64_ifunc_capinit_record *entry2 + = (struct elf_c64_ifunc_capinit_record *) ptr2; + + return entry1->h == entry2->h; +} + +static bfd_boolean +c64_record_ifunc_capinit (struct elf_aarch64_link_hash_table *htab, + struct elf_link_hash_entry *h) +{ + BFD_ASSERT (h && h->type == STT_GNU_IFUNC); + struct elf_c64_ifunc_capinit_record e, *new_entry; + e.h = h; + void **slot = htab_find_slot (htab->c64_ifunc_capinit_hash_table, &e, + INSERT); + if (!slot) + return FALSE; + if (*slot) + { + ((struct elf_c64_ifunc_capinit_record *)*slot)->count += 1; + return TRUE; + } + + new_entry = (struct elf_c64_ifunc_capinit_record *) + objalloc_alloc ((struct objalloc *) htab->c64_ifunc_capinit_memory, + sizeof (struct elf_c64_ifunc_capinit_record)); + if (new_entry) + { + new_entry->h = h; + new_entry->count = 1; + *slot = new_entry; + return TRUE; + } + return FALSE; +} + /* Compute a hash of a local hash entry. We use elf_link_hash_entry for local symbol so that we can handle local STT_GNU_IFUNC symbols as global symbol. We reuse indx and dynstr_index for local symbol @@ -3677,6 +3738,11 @@ elfNN_aarch64_link_hash_table_free (bfd *obfd) if (ret->tls_data_stub_memory) objalloc_free ((struct objalloc *) ret->tls_data_stub_memory); + if (ret->c64_ifunc_capinit_hash_table) + htab_delete (ret->c64_ifunc_capinit_hash_table); + if (ret->c64_ifunc_capinit_memory) + objalloc_free ((struct objalloc *) ret->c64_ifunc_capinit_memory); + bfd_hash_table_free (&ret->stub_hash_table); _bfd_elf_link_hash_table_free (obfd); } @@ -3726,6 +3792,16 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd) return NULL; } + ret->c64_ifunc_capinit_hash_table + = htab_try_create (256, c64_ifunc_capinit_hash, c64_ifunc_capinit_eq, + NULL); + ret->c64_ifunc_capinit_memory = objalloc_create (); + if (!ret->c64_ifunc_capinit_hash_table || !ret->c64_ifunc_capinit_memory) + { + elfNN_aarch64_link_hash_table_free (abfd); + return NULL; + } + ret->loc_hash_table = htab_try_create (1024, elfNN_aarch64_local_htab_hash, elfNN_aarch64_local_htab_eq, @@ -6967,6 +7043,26 @@ c64_symbol_adjust (struct elf_link_hash_entry *h, return FALSE; } +static bfd_boolean +c64_ifunc_reloc_static_irelative (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + return (static_pde (info) && !h->pointer_equality_needed); +} + +static asection * +c64_ifunc_got_reloc_section (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + struct elf_aarch64_link_hash_table *htab; + htab = elf_aarch64_hash_table (info); + if (c64_ifunc_reloc_static_irelative (info, h)) + return htab->root.irelplt; + if (static_pde (info)) + return htab->srelcaps; + return htab->root.srelgot; +} + /* Perform a relocation as part of a final link. The input relocation type should be TLS relaxed. */ @@ -7097,6 +7193,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, bfd_set_error (bfd_error_bad_value); return bfd_reloc_notsupported; + case BFD_RELOC_MORELLO_CAPINIT: case BFD_RELOC_AARCH64_NN: if (rel->r_addend != 0) { @@ -7114,9 +7211,29 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, return bfd_reloc_notsupported; } - /* Generate dynamic relocation only when there is a - non-GOT reference in a shared object. */ - if (bfd_link_pic (info) && h->non_got_ref) + /* N.b. Having an AARCH64_NN relocation (i.e. an ABS64 + relocation) against a capability ifunc is not yet defined. */ + if (globals->c64_rel && bfd_r_type == BFD_RELOC_AARCH64_NN) + { + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_bfd, symtab_hdr, + sym, NULL); + _bfd_error_handler (_("%pB: relocation %s against a C64 " + "STT_GNU_IFUNC symbol `%s'"), + input_bfd, howto->name, name); + bfd_set_error (bfd_error_bad_value); + return bfd_reloc_notsupported; + } + + /* Generate dynamic relocation for AArch64 only when there is a + non-GOT reference in a shared object. + Need a dynamic relocation for a CAPINIT whenever + c64_needs_relocation. */ + if ((bfd_link_pic (info) && h->non_got_ref) + || (bfd_r_type == BFD_RELOC_MORELLO_CAPINIT + && c64_needs_relocation (info, h))) { Elf_Internal_Rela outrel; asection *sreloc; @@ -7134,17 +7251,57 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); + if (h->dynindx == -1 || h->forced_local || bfd_link_executable (info)) { - /* This symbol is resolved locally. */ - 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 - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); + /* This symbol is resolved locally. + N.b. a MORELLO_IRELATIVE relocation is not suitable for + populating an 8-byte value. We don't handle ABS64 + relocations against a capability IFUNC. */ + bfd_vma resolver_loc = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + + if (bfd_r_type == BFD_RELOC_MORELLO_CAPINIT) + { + bfd_vma frag_value = 0, value_tmp; + if (h->pointer_equality_needed && !bfd_link_pic (info)) + { + outrel.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE)); + /* Use the PLT as the canonical address. */ + value_tmp = value; + } + else + { + outrel.r_info = ELFNN_R_INFO (0, MORELLO_R (IRELATIVE)); + value_tmp = resolver_loc; + } + BFD_ASSERT (c64_symbol_adjust (h, value_tmp, sym_sec, info, + &frag_value)); + outrel.r_addend + = (value_tmp | h->target_internal) - frag_value; + /* Can feel safe asserting things here since we've + created all of the values. I.e. nothing is coming + from the user and hence we don't need gracious error + handling. */ + BFD_ASSERT (_bfd_aarch64_elf_put_addend (input_bfd, + hit_data, + bfd_r_type, + howto, frag_value) + == bfd_reloc_ok); + BFD_ASSERT (c64_fixup_frag (input_bfd, info, bfd_r_type, + sym, h, sym_sec, + input_section, hit_data + 8, + value_tmp, 0, rel->r_offset) + == bfd_reloc_continue); + } + else + { + outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)); + outrel.r_addend = resolver_loc; + } } else { @@ -7152,8 +7309,21 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, outrel.r_addend = 0; } - sreloc = globals->root.irelifunc; - elf_append_rela (output_bfd, sreloc, &outrel); + if (c64_ifunc_reloc_static_irelative (info, h)) + { + /* In the same way as TLS descriptor PLT stubs, we want + IRELATIVE relocations coming from CAPINIT relocations to + be after all the relocations for PLT stub entries. */ + BFD_ASSERT (bfd_r_type == BFD_RELOC_MORELLO_CAPINIT); + sreloc = globals->root.irelplt; + bfd_byte *loc = sreloc->contents + + sreloc->reloc_count++ * RELOC_SIZE (globals); + bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc); + } + else if (bfd_link_pic (info)) + elf_append_rela (output_bfd, globals->root.irelifunc, &outrel); + else + elf_append_rela (output_bfd, globals->srelcaps, &outrel); /* If this reloc is against an external symbol, we do not want to fiddle with the addend. Otherwise, @@ -7190,6 +7360,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, if (base_got == NULL) abort (); + value |= h->target_internal; if (off == (bfd_vma) -1) { bfd_vma plt_index; @@ -9784,6 +9955,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, h->ref_regular = 1; h->forced_local = 1; h->root.type = bfd_link_hash_defined; + h->target_internal = isym->st_target_internal; } else h = NULL; @@ -9874,6 +10046,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: case BFD_RELOC_AARCH64_NN: + case BFD_RELOC_MORELLO_CAPINIT: if (htab->root.dynobj == NULL) htab->root.dynobj = abfd; if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info)) @@ -10218,6 +10391,13 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, /* If this symbol does not need a relocation, then there's no reason to increase the srelcaps size for a relocation. */ break; + /* Always create srelcaps, even if there's the possibility that this + relocation will not end up in srelcaps (i.e. in the special case + that our CAPINIT relocation will end up as an IRELATIVE relocation + in .rela.iplt for static PDE). If we don't actually put anything + into this section it will be empty and won't appear in the output + (similar to how we use `_bfd_elf_create_ifunc_sections` above). + */ if (htab->srelcaps == NULL) { if (htab->root.dynobj == NULL) @@ -10232,6 +10412,49 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, htab->srelcaps = sreloc; } + + /* Mark any IFUNC symbol as requiring a PLT. + We do not want to use dyn_relocs since generic code ignores this + when not linking PIC but we need the dynamic relocation for + capabilities. + We would not benefit from using dyn_relocs since a CAPINIT + relocation will never be reduced to a hand-coded value and hence + can't be garbage collected (even if it may turn from a CAPINIT to + an IRELATIVE). + However, without dyn_relocs or a greater than zero plt.refcount, + _bfd_elf_allocate_ifunc_dyn_relocs would garbage collect the PLT + entry for this symbol believing that it is not used. */ + if (h && h->type == STT_GNU_IFUNC) + { + h->needs_plt = 1; + h->plt.refcount = h->plt.refcount < 0 + ? 1 : h->plt.refcount + 1; + /* The only time that a CAPINIT relocation should not trigger + some dynamic relocation in the srelcaps section of the output + binary is when the relocation is against an STT_GNU_IFUNC in + a static PDE. In this case we need to emit the relocations in + the .rela.iplt section. */ + if (static_pde (info)) + { + /* As yet we do not know whether this symbol needs pointer + equality or not. This means that we don't know which + symbols (either __rela_dyn_{start,end} or + __rela_iplt_{start,end}) we need to put this relocation + between. + + This problem does not exist outside of a static_pde since + there the runtime reads all relocs rather than relying on + symbols to point to where relocations are. */ + BFD_ASSERT (c64_record_ifunc_capinit (htab, h)); + break; + } + else if (bfd_link_pic (info)) + { + htab->root.irelifunc->size += RELOC_SIZE (htab); + break; + } + /* Otherwise put into the srelcaps section. */ + } htab->srelcaps->size += RELOC_SIZE (htab); break; @@ -10585,12 +10808,22 @@ elfNN_aarch64_output_arch_local_syms (bfd *output_bfd, } /* Finally, output mapping symbols for the PLT. */ - if (!htab->root.splt || htab->root.splt->size == 0) + if ((!htab->root.splt || htab->root.splt->size == 0) + && (!htab->root.iplt || htab->root.iplt->size == 0)) return TRUE; - osi.sec_shndx = _bfd_elf_section_from_bfd_section - (output_bfd, htab->root.splt->output_section); - osi.sec = htab->root.splt; + if (htab->root.splt && htab->root.splt->size != 0) + { + osi.sec_shndx = _bfd_elf_section_from_bfd_section + (output_bfd, htab->root.splt->output_section); + osi.sec = htab->root.splt; + } + else + { + osi.sec_shndx = _bfd_elf_section_from_bfd_section + (output_bfd, htab->root.iplt->output_section); + osi.sec = htab->root.iplt; + } elfNN_aarch64_output_map_sym (&osi, (htab->c64_rel ? AARCH64_MAP_C64 : AARCH64_MAP_INSN), 0); @@ -10726,7 +10959,9 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) entries are placed by computing their PLT index (0 .. reloc_count). While other none PLT relocs are placed at the slot indicated by reloc_count and reloc_count is - updated. */ + updated. + For reference, a similar abuse of the reloc_count is done for the + irelplt section for Morello CAPINIT relocations. */ htab->root.srelplt->reloc_count++; @@ -10995,12 +11230,29 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, here if it is defined and referenced in a non-shared object. */ if (h->type == STT_GNU_IFUNC && h->def_regular) - return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, - &h->dyn_relocs, - htab->plt_entry_size, - htab->plt_header_size, - GOT_ENTRY_SIZE (htab), - FALSE); + { + bfd_boolean ret + = _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs, + htab->plt_entry_size, + htab->plt_header_size, + GOT_ENTRY_SIZE (htab), FALSE); + if (htab->c64_rel + && ret + && h->got.offset != (bfd_vma)-1 + && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h) + && !bfd_link_pic (info) + && !bfd_link_relocatable (info)) + /* got.offset is not -1 which indicates we have an entry in the got. + For non-capabilities we would manually populate the GOT with the + known location of the PLT in finish_dynamic_symbol, since this is a + non-PIC executable. For capabilities we need to emit a relocation + to populate that entry. */ + { + asection *reloc_sec = c64_ifunc_got_reloc_section (info, h); + reloc_sec->size += RELOC_SIZE (htab); + } + return ret; + } return TRUE; } @@ -11023,6 +11275,34 @@ elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf) return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf); } +/* Allocate space for CAPINIT relocations against IFUNC symbols in a static + PDE. This case is special since the IRELATIVE relocations and RELATIVE + relocations need to be placed in different sections, and the decision about + whether we need to emit an IRELATIVE or RELATIVE relocation is dependent on + whether there are *other* relocations. */ +static bfd_boolean +c64_allocate_ifunc_capinit_static_relocs (void **slot, void *inf) +{ + struct elf_link_hash_entry *h; + struct elf_c64_ifunc_capinit_record *rec + = (struct elf_c64_ifunc_capinit_record *) *slot; + h = rec->h; + + if (h->type != STT_GNU_IFUNC + || !h->def_regular + || !h->ref_regular + || h->root.type != bfd_link_hash_defined) + abort (); + + struct bfd_link_info *info = (struct bfd_link_info *) inf; + struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info); + if (c64_ifunc_reloc_static_irelative (info, h)) + htab->root.irelplt->size += rec->count * RELOC_SIZE (htab); + else + htab->srelcaps->size += rec->count * RELOC_SIZE (htab); + return TRUE; +} + /* This is the most important function of all . Innocuosly named though ! */ @@ -11179,6 +11459,14 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd, elfNN_aarch64_allocate_local_ifunc_dynrelocs, info); + if (static_pde (info)) + { + htab_traverse (htab->c64_ifunc_capinit_hash_table, + c64_allocate_ifunc_capinit_static_relocs, + info); + htab_empty (htab->c64_ifunc_capinit_hash_table); + } + if (static_pde (info) && htab->srelcaps && htab->srelcaps->size > 0) @@ -11260,7 +11548,8 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd, /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ - if (s != htab->root.srelplt) + if (s != htab->root.srelplt + && s != htab->root.irelplt) s->reloc_count = 0; } else @@ -11474,12 +11763,32 @@ 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 = (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 + h->root.u.def.section->output_section->vma + h->root.u.def.section->output_offset); + if (htab->c64_rel) + { + /* A MORELLO_IRELATIVE relocation is the only kind of relocation that + wants something other than PLT0 in the fragment. It requires the + PCC base with associated permissions and size information. */ + bfd_vma frag_value = 0; + bfd_vma orig_value = rela.r_addend; + rela.r_info = ELFNN_R_INFO (0, MORELLO_R (IRELATIVE)); + BFD_ASSERT (c64_symbol_adjust (h, orig_value, plt, info, + &frag_value)); + rela.r_addend = (orig_value | 1) - frag_value; + bfd_put_NN (output_bfd, frag_value, gotplt->contents + got_offset); + BFD_ASSERT (c64_fixup_frag (output_bfd, info, + BFD_RELOC_MORELLO_CAPINIT, + NULL, h, plt, gotplt, + gotplt->contents + got_offset + 8, + orig_value, 0, rela.r_offset) + == bfd_reloc_continue); + } + else + { + rela.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)); + } } else { @@ -11641,11 +11950,37 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd, contains the real function address if we need pointer equality. We load the GOT entry with the PLT entry. */ plt = htab->root.splt ? htab->root.splt : htab->root.iplt; - bfd_put_NN (output_bfd, (plt->output_section->vma - + plt->output_offset - + h->plt.offset), - htab->root.sgot->contents - + (h->got.offset & ~(bfd_vma) 1)); + + bfd_vma value = (plt->output_section->vma + plt->output_offset + + h->plt.offset); + bfd_vma got_offset = h->got.offset & ~(bfd_vma)1; + if (htab->c64_rel) + { + bfd_vma base_value = 0; + BFD_ASSERT (c64_symbol_adjust (h, value, plt, info, + &base_value)); + rela.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE)); + rela.r_addend = (value | h->target_internal) - base_value; + asection *s = c64_ifunc_got_reloc_section (info, h); + elf_append_rela (output_bfd, s, &rela); + + /* N.b. we do not use c64_fixup_frag since in includes a + bunch of features we do not use like error checking the + size and ensuring figuring out whether we need to extend + things depending on the kind of symbol. We know these due + to the fact this is a STT_GNU_IFUNC symbol. + In order to implement those features it requires quite a + lot of arguments which we don't happen to have here. */ + bfd_boolean guessed = FALSE; + bfd_vma meta = cap_meta (pcc_high - pcc_low, plt, &guessed); + BFD_ASSERT (!guessed); + bfd_put_NN (output_bfd, meta, + htab->root.sgot->contents + got_offset + 8); + value = base_value; + } + + bfd_put_NN (output_bfd, value, + htab->root.sgot->contents + got_offset); return TRUE; } } diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index c48164d9cb358e4eb5f21fbdebe20f3610cdf3be..4200c1d17e97ac9b54f2a0a051f15f0d51d47c06 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -106,7 +106,7 @@ proc aarch64_page_plus_decimal_offset { page offset } { # Return the 8-hexdigit truncation of an address. proc aarch64_8digit_addr { addr { plusLSB 0 } } { if { $plusLSB } { - return [aarch64_8digit_addr [format %08x [expr "0x$addr + 1"]]]; + return [format %08x [expr "0x$addr + 1"]]; } return [format %08x "0x$addr"]; } @@ -312,6 +312,25 @@ if { [check_shared_lib_support] 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-ifunc-a" + run_dump_test_lp64 "morello-ifunc1-a" +} +run_dump_test_lp64 "morello-ifunc" +run_dump_test_lp64 "morello-ifunc-b" +run_dump_test_lp64 "morello-ifunc1" +run_dump_test_lp64 "morello-ifunc1-b" +run_dump_test_lp64 "morello-ifunc1-c" +run_dump_test_lp64 "morello-ifunc2" +run_dump_test_lp64 "morello-ifunc2-b" +run_dump_test_lp64 "morello-ifunc3" +run_dump_test_lp64 "morello-ifunc4" +run_dump_test_lp64 "morello-ifunc4a" + +if { [check_shared_lib_support] + && [ld_assemble_flags $as -march=morello+c64 $srcdir/$subdir/morello-ifunc-shared.s tmpdir/morello-ifunc-shared.o] + && [ld_link $ld tmpdir/morello-ifunc-shared.so "--shared tmpdir/morello-ifunc-shared.o"] } { + run_dump_test_lp64 "morello-ifunc-dynlink" + run_dump_test_lp64 "morello-ifunc-dynlink-pie" } if { [check_shared_lib_support] diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d b/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d index c85443fe71acb15f04d749cbb159fc002893d46c..6f00498390bd7420f3a48e4410c14a4d19b077d6 100644 --- a/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d +++ b/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d @@ -1,13 +1,30 @@ #target: [check_shared_lib_support] #as: -march=morello+c64 --defsym C64MODE=1 #ld: -shared --hash-style=sysv -#objdump: -dw +#objdump: -dw --section-headers #source: ifunc-2-local.s +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn Flags +#record: PCC_START + 0 \.[^ ]* *[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*[0-9] CONTENTS, ALLOC, LOAD, READONLY, DATA +#... +Disassembly of section \.plt: + +#record: INDIRECT_LOC FOO_LOCATION #... -0+(110|180|1a0|1b8) <__GI_foo>: +0+([0-9a-f]{3}).*0x([0-9a-f]+)@plt>: +#... +Disassembly of section \.text: + +#check: FOO_LOC string tolower $FOO_LOCATION +#check: FOO_ADDR format %016x [expr "0x$PCC_START + 0x$FOO_LOCATION & ~1"] +#check: INDIRECT_POS format %x [expr "0x$INDIRECT_LOC + 1"] +FOO_ADDR <__GI_foo>: #... -[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0x(110|180|1a0|1b8)@plt> +[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0xFOO_LOC@plt> [ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+c0, 0 <.*> -[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+c0, c0, #0x(101|171|191|1a9) +[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+c0, c0, #0xINDIRECT_POS #pass diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-2.d b/ld/testsuite/ld-aarch64/c64-ifunc-2.d index 2954f67b0c50ece30e2e7a002fc7e03f2afb9f4c..1214c310639726d805f99da34a597679f008653f 100644 --- a/ld/testsuite/ld-aarch64/c64-ifunc-2.d +++ b/ld/testsuite/ld-aarch64/c64-ifunc-2.d @@ -1,18 +1,28 @@ #target: [check_shared_lib_support] #as: -march=morello+c64 --defsym C64MODE=1 #ld: -shared --hash-style=sysv -#objdump: -dw +#objdump: -dw --section-headers #source: ifunc-2.s +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn Flags +#record: PCC_START + 0 \.[^ ]* *[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*[0-9] CONTENTS, ALLOC, LOAD, READONLY, DATA +#... +Disassembly of section \.plt: + #record: INDIRECT_LOC FOO_LOCATION #... -0+([0-9a-f]{3}).*0x([0-9a-f]{3})@plt>: +0+([0-9a-f]{3}).*0x([0-9a-f]+)@plt>: #... Disassembly of section \.text: #check: FOO_LOC string tolower $FOO_LOCATION +#check: FOO_ADDR format %016x [expr "0x$PCC_START + 0x$FOO_LOCATION & ~1"] #check: INDIRECT_POS format %x [expr "0x$INDIRECT_LOC + 1"] -0+FOO_LOC : +FOO_ADDR : #... [ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0xFOO_LOC@plt> [ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+c0, 0 <.*> diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-3a.d b/ld/testsuite/ld-aarch64/c64-ifunc-3a.d index 7690b42edd576039c6e455fcf5bb7a480ee0f8bd..905612ccec2d058713960f185ba4490e2e1dee8e 100644 --- a/ld/testsuite/ld-aarch64/c64-ifunc-3a.d +++ b/ld/testsuite/ld-aarch64/c64-ifunc-3a.d @@ -2,14 +2,27 @@ #target: [check_shared_lib_support] #as: -march=morello+c64 #ld: -shared --hash-style=sysv -#objdump: -dw +#objdump: -dw --section-headers +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn Flags +#record: PCC_START + 0 \.[^ ]* *[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*[0-9] CONTENTS, ALLOC, LOAD, READONLY, DATA +#... +Disassembly of section \.plt: + +#record: INDIRECT_LOC FOO_LOCATION +#... +0+([0-9a-f]{3}).*0x([0-9a-f]+)@plt>: #... Disassembly of section \.text: -#record: INDIRECT_FOO -([0-9a-f]+) <__GI_foo>: -#check: FOO_POS format %x 0x$INDIRECT_FOO +#check: FOO_LOC string tolower $FOO_LOCATION +#check: FOO_ADDR format %016x [expr "0x$PCC_START + 0x$FOO_LOCATION & ~1"] +#check: INDIRECT_POS string tolower $INDIRECT_LOC +FOO_ADDR <__GI_foo>: #... -[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0xFOO_POS@plt> +[ \t0-9a-f]+:[ \t0-9a-f]+bl\tINDIRECT_POS <\*ABS\*\+0xFOO_LOC@plt> #pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc-a.d b/ld/testsuite/ld-aarch64/morello-ifunc-a.d new file mode 100644 index 0000000000000000000000000000000000000000..f36b0945cb554a841fa16dd58f96d7bec7da29ee --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc-a.d @@ -0,0 +1,111 @@ +# Checking that the introduction of a CAPINIT relocation against an IFUNC does +# not change the behaviour of us requiring pointer equality, and checking that +# the CAPINIT relocation respects that pointer equality requirement by pointing +# at the PLT stub. +#source: morello-ifunc.s +#as: -march=morello+c64 +#ld: tmpdir/morello-dynamic-relocs.so +#objdump: -DR --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]* +[0-9a-f]* ([0-9a-f]+) .* + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt *([0-9a-f]+) ([0-9a-f]+) .* + CONTENTS, ALLOC, LOAD, DATA +#... +Disassembly of section \.plt: + +#record: PLT0_ADDR +([0-9a-f]+) <\.plt>: +#... +.*nop +.*nop +.*nop +# Note that for a none-linux-gnu target we don't emit a symbol specific to the +# PLT stub for an IFUNC, but for a none-elf target we do. That means we can't +# generally check the offset in the symbols name matches the `foo` address +# below. +#? +#?[0-9a-f]+ <\*ABS\*\+0x[0-9a-f]+@plt>: +#record: PLTADDR PLTGOT_PAGE + *([0-9a-f]+): .* adrp c16, ([0-9a-f]+) .* +#record: FOO_PLTGOT_OFFSET + *[0-9a-f]+: .* ldr c17, \[c16, #([0-9]+)\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: c2c21220 br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#record: FOO_ADDR +([0-9a-f]+) : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* b .* + +[0-9a-f]+ <_start>: +#check: PLTLOC string tolower $PLTADDR +#check: PLT_PAGE format %x [expr "0x$PLTADDR & ~0xfff"] +#check: FOO_PLT_OFF format %x [expr "(0x$PLTADDR & 0xfff) + 1"] + *[0-9a-f]+: .* bl PLTLOC .* +#record: GOT_PAGE + *[0-9a-f]+: .* adrp c0, ([0-9a-f]+) .* +#record: FOO_GOTOFF_DECIMAL + *[0-9a-f]+: .* ldr c0, \[c0, #([0-9]+)\] + *[0-9a-f]+: .* adrp c0, PLT_PAGE .* + *[0-9a-f]+: .* add c0, c0, #0xFOO_PLT_OFF + *[0-9a-f]+: .* ret c30 + +#... +Disassembly of section \.got: + +#check: PLT_ADDEND format %x [expr "0x$PLTADDR - 0x$PCC_START + 1"] +#check: FRAGBASE format %08x 0x$PCC_START +#check: FRAGSIZE format %08x [expr "0x$PCC_LAST_SIZE + 0x$PCC_LAST_START - 0x$PCC_START"] +#check: FRAGMENT_LOC aarch64_page_plus_decimal_offset $GOT_PAGE $FOO_GOTOFF_DECIMAL +#... + *FRAGMENT_LOC: FRAGBASE .* + [0-9a-f]+: R_MORELLO_RELATIVE \*ABS\*\+0xPLT_ADDEND + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* + +Disassembly of section \.got\.plt: + +#check: PLTGOTLOC aarch64_page_plus_decimal_offset $PLTGOT_PAGE $FOO_PLTGOT_OFFSET +#check: FOO_OFFSET format %x [expr "0x$FOO_ADDR + 1 - 0x$PCC_START"] +[0-9a-f]+ <.*>: + \.\.\. + *PLTGOTLOC: FRAGBASE .* + PLTGOTLOC: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* + \.\.\. + +Disassembly of section \.data: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: FRAGBASE .* + .*: R_MORELLO_RELATIVE \*ABS\*\+0xPLT_ADDEND + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc-b.d b/ld/testsuite/ld-aarch64/morello-ifunc-b.d new file mode 100644 index 0000000000000000000000000000000000000000..c6938e0eb586da8180cf81cba6afa7e012493e00 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc-b.d @@ -0,0 +1,104 @@ +# Checking that the introduction of a CAPINIT relocation against an IFUNC does +# not change the behaviour of us requiring pointer equality, and checking that +# the CAPINIT relocation respects that pointer equality requirement by pointing +# at the PLT stub. +#source: morello-ifunc.s +#as: -march=morello+c64 +#ld: -pie +#objdump: -DR --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]* +[0-9a-f]* ([0-9a-f]+) .* + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt *([0-9a-f]+) ([0-9a-f]+) .* + CONTENTS, ALLOC, LOAD, DATA +#... +Disassembly of section \.plt: + +#record: PLT0_ADDR +([0-9a-f]+) <\.plt>: +#... +.*nop +.*nop +.*nop + +#record: RESOLVER_ADDEND +[0-9a-f]+ <\*ABS\*\+0x([0-9a-f]+)@plt>: +#record: PLTADDR PLTGOT_PAGE + *([0-9a-f]+): .* adrp c16, ([0-9a-f]+) .* +#record: FOO_PLTGOT_OFFSET + *[0-9a-f]+: .* ldr c17, \[c16, #([0-9]+)\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: c2c21220 br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#check: FOO_ADDRESS format %x [expr "0x$PCC_START + 0x$RESOLVER_ADDEND - 1"] +([0-9a-f]+) : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* b .* + +[0-9a-f]+ <_start>: +#check: PLTLOC string tolower $PLTADDR +#check: PLT_PAGE format %x [expr "0x$PLTADDR & ~0xfff"] +#check: FOO_PLT_OFF format %x [expr "(0x$PLTADDR & 0xfff) + 1"] + *[0-9a-f]+: .* bl PLTLOC .* +#record: GOT_PAGE + *[0-9a-f]+: .* adrp c0, ([0-9a-f]+) .* +#record: FOO_GOTOFF_DECIMAL + *[0-9a-f]+: .* ldr c0, \[c0, #([0-9]+)\] + *[0-9a-f]+: .* adrp c0, PLT_PAGE .* + *[0-9a-f]+: .* add c0, c0, #0xFOO_PLT_OFF + *[0-9a-f]+: .* ret c30 + +#... +Disassembly of section \.got: + +[0-9a-f]+ <.*>: + *[0-9a-f]+:.* + \.\.\. + +Disassembly of section \.got\.plt: + +#check: PLT_ADDEND format %x [expr "0x$PLTADDR - 0x$PCC_START + 1"] +#check: FRAGBASE format %08x 0x$PCC_START +#check: FRAGSIZE format %08x [expr "0x$PCC_LAST_SIZE + 0x$PCC_LAST_START - 0x$PCC_START"] +#check: FRAGMENT_LOC aarch64_page_plus_decimal_offset $GOT_PAGE $FOO_GOTOFF_DECIMAL +#check: PLTGOTLOC aarch64_page_plus_decimal_offset $PLTGOT_PAGE $FOO_PLTGOT_OFFSET +#check: FOO_OFFSET string tolower $RESOLVER_ADDEND +[0-9a-f]+ <.*>: + \.\.\. + *PLTGOTLOC: FRAGBASE .* + PLTGOTLOC: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#... +Disassembly of section \.data: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: FRAGBASE .* + .*: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc-dynlink-pie.d b/ld/testsuite/ld-aarch64/morello-ifunc-dynlink-pie.d new file mode 100644 index 0000000000000000000000000000000000000000..e139f02770a1d764ae281a830cc8e0a11116323b --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc-dynlink-pie.d @@ -0,0 +1,20 @@ +# Checking that the sharedfoo symbol is a FUNC and UNDEFINED symbol. +# It should also have 0 as its value (so that we don't make the PLT stub the +# canonical address). +# Also checking that there is a CAPINIT relocation against the sharedfoo symbol +# (i.e. that it has not been relaxed to some other relocation). +#source: morello-ifunc-dynlink.s +#as: -march=morello+c64 +#ld: -pie tmpdir/morello-ifunc-shared.so +#readelf: --relocs --dyn-syms + +Relocation section '\.rela\.dyn' at offset 0x.* contains 1 entry: + Offset Info Type Sym\. Value Sym\. Name \+ Addend +[0-9a-f]+ 00030000e800 R_MORELLO_CAPINIT 0000000000000000 sharedfoo \+ 0 + +#... +Symbol table '\.dynsym' contains [0-9]+ entries: + Num: Value Size Type Bind Vis Ndx Name +#... + +[0-9]+: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sharedfoo +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc-dynlink.d b/ld/testsuite/ld-aarch64/morello-ifunc-dynlink.d new file mode 100644 index 0000000000000000000000000000000000000000..328fe047e030f6c8e7beb6f58d6c1a2497d030c2 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc-dynlink.d @@ -0,0 +1,20 @@ +# Checking that the sharedfoo symbol is a FUNC and UNDEFINED symbol. +# It should also have 0 as its value (so that we don't make the PLT stub the +# canonical address). +# Also checking that there is a CAPINIT relocation against the sharedfoo symbol +# (i.e. that it has not been relaxed to some other relocation). +#source: morello-ifunc-dynlink.s +#as: -march=morello+c64 +#ld: tmpdir/morello-ifunc-shared.so +#readelf: --relocs --dyn-syms + +Relocation section '\.rela\.dyn' at offset 0x.* contains 1 entry: + Offset Info Type Sym\. Value Sym\. Name \+ Addend +[0-9a-f]+ ............ R_MORELLO_CAPINIT 0000000000000000 sharedfoo \+ 0 + +#... +Symbol table '\.dynsym' contains [0-9]+ entries: + Num: Value Size Type Bind Vis Ndx Name +#... + +[0-9]+: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sharedfoo +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc-dynlink.s b/ld/testsuite/ld-aarch64/morello-ifunc-dynlink.s new file mode 100644 index 0000000000000000000000000000000000000000..a6a7e4085ed4f2f565e73c740a699e7e93758feb --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc-dynlink.s @@ -0,0 +1,23 @@ + .text + .p2align 4,,11 +#APP + .type foo, %gnu_indirect_function +#NO_APP + .global foo + .type foo, @function +foo: + ret + .size foo, .-foo + + .global _start + .type _start,%function +_start: + bl sharedfoo + ret + .size _start, .-_start + .data + .align 2 + .type var, %object + .size var, 4 +var: + .chericap sharedfoo diff --git a/ld/testsuite/ld-aarch64/morello-ifunc-shared.s b/ld/testsuite/ld-aarch64/morello-ifunc-shared.s new file mode 100644 index 0000000000000000000000000000000000000000..61c2f5a026eb18f6581b7776059875abf789c44f --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc-shared.s @@ -0,0 +1,23 @@ + .text + .p2align 4,,11 +#APP + .type sharedfoo, %gnu_indirect_function +#NO_APP + .global sharedfoo + .type sharedfoo, @function +sharedfoo: + ret + .size sharedfoo, .-sharedfoo + + .global libfunc + .type libfunc,%function +libfunc: + bl foo + ret + .size libfunc, .-libfunc + .data + .align 2 + .type var, %object + .size var, 4 +var: + .chericap foo diff --git a/ld/testsuite/ld-aarch64/morello-ifunc.d b/ld/testsuite/ld-aarch64/morello-ifunc.d new file mode 100644 index 0000000000000000000000000000000000000000..11ad08d9a2f3c87fc23bb7ba9b3f7ffad07c006a --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc.d @@ -0,0 +1,138 @@ +# Checking that GOT relocations against a PLT which requires pointer equality +# use a GOT entry pointing to the PLT stub rather than just using the .got.plt +# entry. +# +# Things we check are: +# - __rela_dyn_{start,end} are around the RELATIVE relocation against FOO. +# - That RELATIVE relocation initialises a GOT entry. +# - The fragment in that GOT entry plus the addend of the RELATIVE +# relocation total to point to the foo PLT stub. +# - We emit a PLT stub which accesses a PLTGOT entry. +#as: -march=morello+c64 +#ld: +#objdump: -Dr --section-headers --syms + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ \t]* +[0-9a-f]* ([0-9a-f]+) .* + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: LAST_PCC_SEC_SIZE LAST_PCC_SEC_START +#... + *[0-9]+ \.got\.plt *([0-9a-f]+) ([0-9a-f]+) .* + CONTENTS, ALLOC, LOAD, DATA +#... +SYMBOL TABLE: +#record: RELA_DYN_END +#... +([0-9a-f]+) l O \.rela\.dyn 0000000000000000 __rela_dyn_end +#record: RELA_DYN_START +([0-9a-f]+) l O \.rela\.dyn 0000000000000000 __rela_dyn_start +#... +Disassembly of section \.rela\.dyn: + +#check: RELA_START format %016x 0x$RELA_DYN_START +RELA_START <__rela_dyn_start>: +#record: CHERICAP_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e803 .* + *[0-9a-f]+: 00000000 .* +#record: CHERICAP_ADDEND + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* +#record: FOO_GOT + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e803 .* + *[0-9a-f]+: 00000000 .* +#check: CHERICAP_ADDEND string tolower $CHERICAP_ADDEND + *[0-9a-f]+: CHERICAP_ADDEND .* +#check: RELA_DYN_LAST format %x [expr "0x$RELA_DYN_END - 0x4"] + *RELA_DYN_LAST: 00000000 .* + +Disassembly of section \.rela\.plt: + +[0-9a-f]+ <.*>: +#record: PLTGOT_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e804 .* + *[0-9a-f]+: 00000000 .* +#record: PLTGOT_LOC_ADDEND + *[0-9a-f]+: ([0-9a-f]+) .* +#... +Disassembly of section \.plt: + +#check: FOO_PLT format %x [expr "0x$PCC_START + 0x$CHERICAP_ADDEND - 1"] +#check: PLTGOT_PAGE format %x [expr "0x$PLTGOT_LOC & (~0xfff)"] +#check: PLTGOT_DEC_OFF expr "0x$PLTGOT_LOC & 0xfff" +([0-9a-f]+) <\.plt>: +#... + *FOO_PLT: .* adrp c16, PLTGOT_PAGE .* + *[0-9a-f]+: .* ldr c17, \[c16, #PLTGOT_DEC_OFF\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: c2c21220 br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : + *[0-9a-f]+: 52800020 mov w0, #0x1 // #1 + *[0-9a-f]+: c2c253c0 ret c30 + +[0-9a-f]+ : + *[0-9a-f]+: 52800040 mov w0, #0x2 // #2 + *[0-9a-f]+: c2c253c0 ret c30 + +#check: RESOLVER_ADDRESS format %016x [expr "0x$PLTGOT_LOC_ADDEND + 0x$PCC_START - 1"] +RESOLVER_ADDRESS : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* b .* + +#clearcheck: +#check: FOO_PLT format %x [expr "0x$PCC_START + 0x$CHERICAP_ADDEND - 1"] +#check: GOT_PAGE format %x [expr "0x$FOO_GOT & ~0xfff"] +#check: FOO_GOTOFF expr "0x$FOO_GOT & 0xfff" +[0-9a-f]+ <_start>: + *[0-9a-f]+: .* bl FOO_PLT .* + *[0-9a-f]+: .* adrp c0, GOT_PAGE .* + *[0-9a-f]+: .* ldr c0, \[c0, #FOO_GOTOFF\] +#clearcheck: +#check: PLT_PAGE format %x [expr "(0x$PCC_START + 0x$CHERICAP_ADDEND) & ~0xfff"] +#check: FOO_PLT_OFF format %x [expr "(0x$PCC_START + 0x$CHERICAP_ADDEND) & 0xfff"] + *[0-9a-f]+: .* adrp c0, PLT_PAGE .* + *[0-9a-f]+: .* add c0, c0, #0xFOO_PLT_OFF + *[0-9a-f]+: .* ret c30 + +#... +Disassembly of section \.got: + +#clearcheck: +#check: FRAGMENT_BASE aarch64_8digit_addr $PCC_START +#check: FRAGMENT_SIZE format %08x [expr "0x$LAST_PCC_SEC_START + 0x$LAST_PCC_SEC_SIZE - 0x$PCC_START"] +#check: FRAGMENT_LOC format %x 0x$FOO_GOT +#... + *FRAGMENT_LOC: FRAGMENT_BASE .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGMENT_SIZE .* + *[0-9a-f]+: 04000000 .* + +Disassembly of section \.got\.plt: + +#check: PLTGOTLOC format %x 0x$PLTGOT_LOC +[0-9a-f]+ <.*>: + \.\.\. + *PLTGOTLOC: FRAGMENT_BASE .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGMENT_SIZE .* + *[0-9a-f]+: 04000000 .* +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc.s b/ld/testsuite/ld-aarch64/morello-ifunc.s new file mode 100644 index 0000000000000000000000000000000000000000..08efcb3c2125abfdb094c458f98b2985ce972ba0 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc.s @@ -0,0 +1,52 @@ + .text +#APP + .type foo, %gnu_indirect_function +#NO_APP + .align 2 + .type foo_1, %function +foo_1: + mov w0, 1 + ret + .size foo_1, .-foo_1 + .align 2 + .type foo_2, %function +foo_2: + mov w0, 2 + ret + .size foo_2, .-foo_2 + .align 2 + + .global foo + .type foo, %function +foo: + mov x1, 42 + tst x0, x1 + bne .L5 + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 +.L4: + ret +.L5: + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 + b .L4 + .size foo, .-foo + .align 2 + + .global _start + .type _start, %function +_start: + bl foo + adrp c0, :got:foo + ldr c0, [c0, #:got_lo12:foo] + // Adding direct relocation against `foo` to ensure that we need + // pointer equality. This should change the behaviour of the CAPINIT + // and GOT relocations. + adrp c0, foo + add c0, c0, :lo12:foo + ret + .size _start, .-_start + + .data + .align 4 + .chericap foo diff --git a/ld/testsuite/ld-aarch64/morello-ifunc1-a.d b/ld/testsuite/ld-aarch64/morello-ifunc1-a.d new file mode 100644 index 0000000000000000000000000000000000000000..062973bab00df7824f756e8f4ccdf1f051c6e23b --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc1-a.d @@ -0,0 +1,100 @@ +# Checking that when linking as standard, the BL and the GOT access both use +# the PLT. This link does not do anything special to maintain pointer equality +# since there is no access which directly uses the address. +# +# Things this testcase checks: +# 1) Fragment of IRELATIVE relocation is PCC_START with bounds and +# permissions of PCC. +# 2) GOT access uses IRELATIVE relocation in the PLTGOT when no direct access +# to address is used. +# 3) BL to an IFUNC branches to a PLT stub which uses the a PLTGOT slot +# initialised by an IRELATIVE relocation against our resolver. +#source: morello-ifunc1.s +#as: -march=morello+c64 +#ld: -pie +#objdump: -DR --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]+ +[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt +([0-9a-f]+) ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, DATA +#... +Disassembly of section \.plt: + +[0-9a-f]+ <\.plt>: +#... +.*nop +.*nop +.*nop +# Note that for a none-linux-gnu target we don't emit a symbol specific to the +# PLT stub for an IFUNC, but for a none-elf target we do. That means we can't +# generally check the offset in the symbols name matches the `foo` address +# below. +#? +#?[0-9a-f]+ <\*ABS\*\+0x[0-9a-f]+@plt>: +#record: PLTADDR PLTGOT_PAGE + *([0-9a-f]+): .* adrp c16, ([0-9a-f]+) .* +#record: PLTGOT_DEC_OFF + *[0-9a-f]+: .* ldr c17, \[c16, #([0-9]+)\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: .* br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#record: FOO_ADDR +([0-9a-f]+) : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* // b\.any + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, .* + *[0-9a-f]+: .* b .* + +[0-9a-f]+ <_start>: +#check: PLTLOC string tolower $PLTADDR +#check: PLTGOTPAGE string tolower $PLTGOT_PAGE +#check: PLTGOT_DECOFF string tolower $PLTGOT_DEC_OFF + *[0-9a-f]+: .* bl PLTLOC .* + *[0-9a-f]+: .* adrp c0, PLTGOTPAGE .* + *[0-9a-f]+: .* ldr c0, \[c0, #PLTGOT_DECOFF\] + *[0-9a-f]+: .* ret c30 +#... +Disassembly of section \.got\.plt: + +#check: GOTLOC aarch64_page_plus_decimal_offset $PLTGOT_PAGE $PLTGOT_DEC_OFF +#check: FRAGBASE format %08x 0x$PCC_START +#check: FRAGSIZE format %08x [expr "0x$PCC_LAST_SIZE + 0x$PCC_LAST_START - 0x$PCC_START"] +#check: FOO_OFFSET format %x [expr "0x$FOO_ADDR + 1 - 0x$PCC_START"] +[0-9a-f]+ <.*>: + \.\.\. + *GOTLOC: FRAGBASE .* + GOTLOC: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#... +Disassembly of section \.data: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: FRAGBASE .* + [0-9a-f]+: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc1-b.d b/ld/testsuite/ld-aarch64/morello-ifunc1-b.d new file mode 100644 index 0000000000000000000000000000000000000000..062973bab00df7824f756e8f4ccdf1f051c6e23b --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc1-b.d @@ -0,0 +1,100 @@ +# Checking that when linking as standard, the BL and the GOT access both use +# the PLT. This link does not do anything special to maintain pointer equality +# since there is no access which directly uses the address. +# +# Things this testcase checks: +# 1) Fragment of IRELATIVE relocation is PCC_START with bounds and +# permissions of PCC. +# 2) GOT access uses IRELATIVE relocation in the PLTGOT when no direct access +# to address is used. +# 3) BL to an IFUNC branches to a PLT stub which uses the a PLTGOT slot +# initialised by an IRELATIVE relocation against our resolver. +#source: morello-ifunc1.s +#as: -march=morello+c64 +#ld: -pie +#objdump: -DR --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]+ +[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt +([0-9a-f]+) ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, DATA +#... +Disassembly of section \.plt: + +[0-9a-f]+ <\.plt>: +#... +.*nop +.*nop +.*nop +# Note that for a none-linux-gnu target we don't emit a symbol specific to the +# PLT stub for an IFUNC, but for a none-elf target we do. That means we can't +# generally check the offset in the symbols name matches the `foo` address +# below. +#? +#?[0-9a-f]+ <\*ABS\*\+0x[0-9a-f]+@plt>: +#record: PLTADDR PLTGOT_PAGE + *([0-9a-f]+): .* adrp c16, ([0-9a-f]+) .* +#record: PLTGOT_DEC_OFF + *[0-9a-f]+: .* ldr c17, \[c16, #([0-9]+)\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: .* br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#record: FOO_ADDR +([0-9a-f]+) : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* // b\.any + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, .* + *[0-9a-f]+: .* b .* + +[0-9a-f]+ <_start>: +#check: PLTLOC string tolower $PLTADDR +#check: PLTGOTPAGE string tolower $PLTGOT_PAGE +#check: PLTGOT_DECOFF string tolower $PLTGOT_DEC_OFF + *[0-9a-f]+: .* bl PLTLOC .* + *[0-9a-f]+: .* adrp c0, PLTGOTPAGE .* + *[0-9a-f]+: .* ldr c0, \[c0, #PLTGOT_DECOFF\] + *[0-9a-f]+: .* ret c30 +#... +Disassembly of section \.got\.plt: + +#check: GOTLOC aarch64_page_plus_decimal_offset $PLTGOT_PAGE $PLTGOT_DEC_OFF +#check: FRAGBASE format %08x 0x$PCC_START +#check: FRAGSIZE format %08x [expr "0x$PCC_LAST_SIZE + 0x$PCC_LAST_START - 0x$PCC_START"] +#check: FOO_OFFSET format %x [expr "0x$FOO_ADDR + 1 - 0x$PCC_START"] +[0-9a-f]+ <.*>: + \.\.\. + *GOTLOC: FRAGBASE .* + GOTLOC: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#... +Disassembly of section \.data: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: FRAGBASE .* + [0-9a-f]+: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc1-c.d b/ld/testsuite/ld-aarch64/morello-ifunc1-c.d new file mode 100644 index 0000000000000000000000000000000000000000..741fb50ec45dbb07357d3c794358a0a232f747db --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc1-c.d @@ -0,0 +1,97 @@ +# Checking that when linking as standard, the BL and the GOT access both use +# the PLT. This link does not do anything special to maintain pointer equality +# since there is no access which directly uses the address. +# +# Things this testcase checks: +# 1) Fragment of IRELATIVE relocation is PCC_START with bounds and +# permissions of PCC. +# 2) GOT access uses IRELATIVE relocation in the PLTGOT when no direct access +# to address is used. +# 3) BL to an IFUNC branches to a PLT stub which uses the a PLTGOT slot +# initialised by an IRELATIVE relocation against our resolver. +#source: morello-ifunc1.s +#target: [check_shared_lib_support] +#as: -march=morello+c64 +#ld: -shared +#objdump: -DR --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]+ +[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt +([0-9a-f]+) ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, DATA +#... +Disassembly of section \.plt: + +#record: PLT0_ADDR +([0-9a-f]+) <\.plt>: +#... +.*nop +.*nop +.*nop + +[0-9a-f]+ : +#record: PLTADDR PLTGOT_PAGE + *([0-9a-f]+): .* adrp c16, ([0-9a-f]+) .* +#record: PLTGOT_DEC_OFF + *[0-9a-f]+: .* ldr c17, \[c16, #([0-9]+)\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: .* br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#record: FOO_ADDR +([0-9a-f]+) : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* // b\.any + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, .* + *[0-9a-f]+: .* b .* + +[0-9a-f]+ <_start>: +#check: PLTLOC string tolower $PLTADDR + *[0-9a-f]+: .* bl PLTLOC .* +#record: GOT_PAGE + *[0-9a-f]+: .* adrp c0, ([0-9a-f]+) .* +#record: GOT_DEC_OFF + *[0-9a-f]+: .* ldr c0, \[c0, #([0-9]+)\] + *[0-9a-f]+: .* ret c30 +#... +Disassembly of section \.got: + +#check: GOTLOC aarch64_page_plus_decimal_offset $GOT_PAGE $GOT_DEC_OFF +[0-9a-f]+ <.*>: +#... + GOTLOC: R_MORELLO_GLOB_DAT foo +#... +Disassembly of section \.got\.plt: + +#check: PLTGOT_LOC aarch64_page_plus_decimal_offset $PLTGOT_PAGE $PLTGOT_DEC_OFF +#check: FRAGBASE format %08x [expr "0x$PLT0_ADDR + 1"] +[0-9a-f]+ <.*>: + \.\.\. + *PLTGOT_LOC: FRAGBASE .* + PLTGOT_LOC: R_MORELLO_JUMP_SLOT foo +#... +Disassembly of section \.data: + +[0-9a-f]+ <.*>: + \.\.\. + [0-9a-f]+: R_MORELLO_CAPINIT foo +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc1.d b/ld/testsuite/ld-aarch64/morello-ifunc1.d new file mode 100644 index 0000000000000000000000000000000000000000..c205f15a3044c52d9124b3cd6e1114204f49b606 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc1.d @@ -0,0 +1,113 @@ +# Checking that when linking as standard, the BL and the GOT access both use +# the PLT. This link does not do anything special to maintain pointer equality +# since there is no access which directly uses the address. +# +# Things this testcase checks: +# 1) Fragment of IRELATIVE relocation is PCC_START with bounds and +# permissions of PCC. +# 2) GOT access uses IRELATIVE relocation in the PLTGOT when no direct access +# to address is used. +# 3) BL to an IFUNC branches to a PLT stub which uses the a PLTGOT slot +# initialised by an IRELATIVE relocation against our resolver. +#as: -march=morello+c64 +#ld: +#objdump: -Dr --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]+ +[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt +([0-9a-f]+) ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, DATA +#... + +Disassembly of section \.rela\.plt: + +[0-9a-f]+ <.*>: +#record: PLTGOT_LOC + +[0-9a-f]+: ([0-9a-f]+) .* + +[0-9a-f]+: 00000000 .* + +[0-9a-f]+: 0000e804 .* + +[0-9a-f]+: 00000000 .* +#record: IREL_ADDEND + +[0-9a-f]+: ([0-9a-f]+) .* + +[0-9a-f]+: 00000000 .* +#record: CHERICAP_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e804 .* + *[0-9a-f]+: 00000000 .* +#check: CHERICAP_ADDEND string tolower $IREL_ADDEND + *[0-9a-f]+: CHERICAP_ADDEND .* + *[0-9a-f]+: 00000000 .* + +Disassembly of section \.plt: + +#check: PLTGOT_PAGE format %x [expr "0x$PLTGOT_LOC & (~0xfff)"] +#check: PLTGOT_DEC_OFF expr "0x$PLTGOT_LOC & 0xfff" +[0-9a-f]+ <\.plt>: +#record: PLTADDR + *([0-9a-f]+): .* adrp c16, PLTGOT_PAGE .* + *[0-9a-f]+: .* ldr c17, \[c16, #PLTGOT_DEC_OFF\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: .* br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#check: FOO_ADDR format %016x [expr "0x$PCC_START + (0x$IREL_ADDEND & ~1)"] +FOO_ADDR : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* // b\.any + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, .* + *[0-9a-f]+: .* b .* + +[0-9a-f]+ <_start>: +#check: PLTLOC string tolower $PLTADDR + *[0-9a-f]+: .* bl PLTLOC .* + *[0-9a-f]+: .* adrp c0, PLTGOT_PAGE .* + *[0-9a-f]+: .* ldr c0, \[c0, #PLTGOT_DEC_OFF\] + *[0-9a-f]+: .* ret c30 + +Disassembly of section \.got: + +[0-9a-f]+ <.*>: + \.\.\. + +Disassembly of section \.got\.plt: + +#check: GOTLOC format %x 0x$PLTGOT_LOC +#check: FRAGBASE format %08x 0x$PCC_START +#check: FRAGSIZE format %08x [expr "0x$PCC_LAST_SIZE + 0x$PCC_LAST_START - 0x$PCC_START"] +[0-9a-f]+ <.*>: + \.\.\. + *GOTLOC: FRAGBASE .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#... +Disassembly of section \.data: + +#check: CHERICAPLOC format %x 0x$CHERICAP_LOC +[0-9a-f]+ <.*>: + *CHERICAPLOC: FRAGBASE .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#pass + diff --git a/ld/testsuite/ld-aarch64/morello-ifunc1.s b/ld/testsuite/ld-aarch64/morello-ifunc1.s new file mode 100644 index 0000000000000000000000000000000000000000..9e088b5c1359a3977f8f73913a8bb93c0b7550d8 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc1.s @@ -0,0 +1,51 @@ +// Want to check that having a CAPINIT relocation on an IFUNC does not require +// pointer equality (this would mean that a GOT relocation against the symbol +// would end up using a GOT entry which refers to the PLT, but without +// requiring pointer equality we end up using the PLTGOT entry that is already +// around for the use of the PLT). +#APP + .type foo, %gnu_indirect_function +#NO_APP + .align 2 + .type foo_1, %function +foo_1: + mov w0, 1 + ret + .size foo_1, .-foo_1 + .align 2 + .type foo_2, %function +foo_2: + mov w0, 2 + ret + .size foo_2, .-foo_2 + .align 2 + + .global foo + .type foo, %function +foo: + mov x1, 42 + tst x0, x1 + bne .L5 + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 +.L4: + ret +.L5: + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 + b .L4 + .size foo, .-foo + .align 2 + + .global _start + .type _start, %function +_start: + bl foo + adrp c0, :got:foo + ldr c0, [c0, #:got_lo12:foo] + ret + .size _start, .-_start + + .data + .align 4 + .chericap foo diff --git a/ld/testsuite/ld-aarch64/morello-ifunc2-b.d b/ld/testsuite/ld-aarch64/morello-ifunc2-b.d new file mode 100644 index 0000000000000000000000000000000000000000..773274b99901dbf4f500a1d9787c26aedecfe90e --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc2-b.d @@ -0,0 +1,82 @@ +# Checking that having a CAPINIT relocation against an IFUNC symbol stops the +# garbage collection of the IFUNC's PLT. +# In order to show that the PLT stub is indeed the one related to FOO we show +# that the PLT stub loads from the PLTGOT, and that the entry in the PLTGOT it +# loads is initialised with an IRELATIVE relocation pointing to the foo +# resolver. +#source: morello-ifunc2.s +#as: -march=morello+c64 +#ld: -pie +#objdump: -DR --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: TEXT_START +.* .interp [0-9a-f]+ ([0-9a-f]+) .* .* 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: DATA_START +#... +.* .data 00000010 ([0-9a-f]+) .* .* 2\*\*. + CONTENTS, ALLOC, LOAD, DATA + +#... +Disassembly of section \.plt: + +[0-9a-f]+ <\.plt>: +#... + *[0-9a-f]+: d503201f nop + *[0-9a-f]+: d503201f nop + *[0-9a-f]+: d503201f nop + +#record: PLTSTUB_ADDR FOO_OFF +([0-9a-f]+) <\*ABS\*\+0x([0-9a-f]+)@plt>: +#record: PLTGOT_PAGE + *[0-9a-f]+: ........ adrp c16, ([0-9a-f]+) <.* +#record: FOO_PLTGOT_OFF + *[0-9a-f]+: ........ ldr c17, \[c16, #([0-9]+)\] +#check: FOO_PLTGOT_HEXOFF format %x $FOO_PLTGOT_OFF + *[0-9a-f]+: ........ add c16, c16, #0xFOO_PLTGOT_HEXOFF + *[0-9a-f]+: c2c21220 br c17 +#clearcheck: + +Disassembly of section \.text: + +[0-9a-f]+ : + *[0-9a-f]+: 52800020 mov w0, #0x1 // #1 + *[0-9a-f]+: c2c253c0 ret c30 + +[0-9a-f]+ : + *[0-9a-f]+: 52800040 mov w0, #0x2 // #2 + *[0-9a-f]+: c2c253c0 ret c30 + +#check: FOO_LOC format %016x [expr "0x$TEXT_START + 0x$FOO_OFF - 1"] +FOO_LOC : + *[0-9a-f]+: d2800541 mov x1, #0x2a // #42 + *[0-9a-f]+: ea01001f tst x0, x1 + *[0-9a-f]+: ........ b\.ne .* + *[0-9a-f]+: ........ adrp c0, .* + *[0-9a-f]+: ........ add c0, c0, .* + *[0-9a-f]+: c2c253c0 ret c30 + *[0-9a-f]+: ........ adrp c0, .* + *[0-9a-f]+: ........ add c0, c0, .* + *[0-9a-f]+: 17fffffd b .* + +[0-9a-f]+ <_start>: + *[0-9a-f]+: c2c253c0 ret c30 + +#... +Disassembly of section \.got\.plt: +#check: PCC_START aarch64_8digit_addr $TEXT_START +#check: PCC_SIZE format %08x [expr "0x$DATA_START - 0x$TEXT_START"] +#check: FOO_OFFSET string tolower $FOO_OFF + +[0-9a-f]+ <.*>: + \.\.\. + *[0-9a-f]+: PCC_START .* + .*: R_MORELLO_IRELATIVE \*ABS\*\+0xFOO_OFFSET + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: PCC_SIZE .* + *[0-9a-f]+: 04000000 .* +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc2.d b/ld/testsuite/ld-aarch64/morello-ifunc2.d new file mode 100644 index 0000000000000000000000000000000000000000..b706f0f171823f7927d23239afec133cfd9f6c4b --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc2.d @@ -0,0 +1,92 @@ +# Checking that having a CAPINIT relocation against an IFUNC symbol stops the +# garbage collection of the IFUNC's PLT. +# In order to show that the PLT stub is indeed the one related to FOO we show +# that the PLT stub loads from the PLTGOT, and that the entry in the PLTGOT it +# loads is initialised with an IRELATIVE relocation pointing to the foo +# resolver. +#as: -march=morello+c64 +#ld: +#objdump: -Dr --section-headers + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: TEXT_START +.* .[^ ]+ +[0-9a-f]+ ([0-9a-f]+) .* .* 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: DATA_START +#... +.* .data 00000010 ([0-9a-f]+) .* .* 2\*\*. + CONTENTS, ALLOC, LOAD, DATA + +#... +Disassembly of section \.rela\.plt: + +[0-9a-f]+ <\.rela\.plt>: +#record: PLTGOT_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e804 .* + *[0-9a-f]+: 00000000 .* +#record: PLTGOT_IREL_ADDEND + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* +#record: CAPINIT_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e804 .* + *[0-9a-f]+: 00000000 .* +#check: CAPINIT_ADDEND string tolower $PLTGOT_IREL_ADDEND + *[0-9a-f]+: CAPINIT_ADDEND .* + *[0-9a-f]+: 00000000 .* + + +Disassembly of section \.plt: + +#check: PLTGOT_PAGE format %x [expr "0x$PLTGOT_LOC & (~0xfff)"] +#check: PLTGOT_DEC_OFF expr "0x$PLTGOT_LOC & 0xfff" +[0-9a-f]+ <\.plt>: + *[0-9a-f]+: ........ adrp c16, PLTGOT_PAGE <.* + *[0-9a-f]+: ........ ldr c17, \[c16, #PLTGOT_DEC_OFF\] + *[0-9a-f]+: ........ add c16, c16, #0x.* + *[0-9a-f]+: c2c21220 br c17 +#clearcheck: + +Disassembly of section \.text: + +[0-9a-f]+ : + *[0-9a-f]+: 52800020 mov w0, #0x1 // #1 + *[0-9a-f]+: c2c253c0 ret c30 + +[0-9a-f]+ : + *[0-9a-f]+: 52800040 mov w0, #0x2 // #2 + *[0-9a-f]+: c2c253c0 ret c30 + +#check: FOO_LOC format %016x [expr "0x$TEXT_START + 0x$PLTGOT_IREL_ADDEND - 1"] +FOO_LOC : + *[0-9a-f]+: d2800541 mov x1, #0x2a // #42 + *[0-9a-f]+: ea01001f tst x0, x1 + *[0-9a-f]+: ........ b\.ne .* + *[0-9a-f]+: ........ adrp c0, .* + *[0-9a-f]+: ........ add c0, c0, .* + *[0-9a-f]+: c2c253c0 ret c30 + *[0-9a-f]+: ........ adrp c0, .* + *[0-9a-f]+: ........ add c0, c0, .* + *[0-9a-f]+: 17fffffd b .* + +[0-9a-f]+ <_start>: + *[0-9a-f]+: c2c253c0 ret c30 + +#... +Disassembly of section \.got\.plt: + +#check: PLTGOT_LOCATION format %x 0x$PLTGOT_LOC +#check: PCC_START aarch64_8digit_addr $TEXT_START +#check: PCC_SIZE format %08x [expr "0x$DATA_START - 0x$TEXT_START"] +[0-9a-f]+ <.*>: + *PLTGOT_LOCATION: PCC_START .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: PCC_SIZE .* + *[0-9a-f]+: 04000000 .* +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc2.s b/ld/testsuite/ld-aarch64/morello-ifunc2.s new file mode 100644 index 0000000000000000000000000000000000000000..cc111f9962691d808ce6e561adc8ae93bbac2855 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc2.s @@ -0,0 +1,46 @@ +// Want to check that having a CAPINIT relocation on an IFUNC stops the garbage +// collection of the IFUNC's PLT (so that the CAPINIT relocation has something +// to point to). +#APP + .type foo, %gnu_indirect_function +#NO_APP + .align 2 + .type foo_1, %function +foo_1: + mov w0, 1 + ret + .size foo_1, .-foo_1 + .align 2 + .type foo_2, %function +foo_2: + mov w0, 2 + ret + .size foo_2, .-foo_2 + .align 2 + + .global foo + .type foo, %function +foo: + mov x1, 42 + tst x0, x1 + bne .L5 + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 +.L4: + ret +.L5: + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 + b .L4 + .size foo, .-foo + .align 2 + + .global _start + .type _start, %function +_start: + ret + .size _start, .-_start + + .data + .align 4 + .chericap foo diff --git a/ld/testsuite/ld-aarch64/morello-ifunc3.d b/ld/testsuite/ld-aarch64/morello-ifunc3.d new file mode 100644 index 0000000000000000000000000000000000000000..6eaea611499cbb533d1568dafd282421e85c3507 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc3.d @@ -0,0 +1,4 @@ +#as: -march=morello+c64 +#ld: +#error: .*: relocation R_AARCH64_ABS64 against a C64 STT_GNU_IFUNC symbol `foo' +#error: .*: dangerous relocation: unsupported relocation diff --git a/ld/testsuite/ld-aarch64/morello-ifunc3.s b/ld/testsuite/ld-aarch64/morello-ifunc3.s new file mode 100644 index 0000000000000000000000000000000000000000..f6702f1690c613b9ce0c287badf98402d490f96d --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc3.s @@ -0,0 +1,43 @@ +#APP + .type foo, %gnu_indirect_function +#NO_APP + .align 2 + .type foo_1, %function +foo_1: + mov w0, 1 + ret + .size foo_1, .-foo_1 + .align 2 + .type foo_2, %function +foo_2: + mov w0, 2 + ret + .size foo_2, .-foo_2 + .align 2 + + .global foo + .type foo, %function +foo: + mov x1, 42 + tst x0, x1 + bne .L5 + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 +.L4: + ret +.L5: + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 + b .L4 + .size foo, .-foo + .align 2 + + .global _start + .type _start, %function +_start: + ret + .size _start, .-_start + + .data + .align 4 + .xword foo diff --git a/ld/testsuite/ld-aarch64/morello-ifunc4.d b/ld/testsuite/ld-aarch64/morello-ifunc4.d new file mode 100644 index 0000000000000000000000000000000000000000..ceb213b2114e4ae8e4d9388b2f69f500ce67d2aa --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc4.d @@ -0,0 +1,176 @@ +# Checking that the IRELATIVE relocations which are added by CAPINIT +# static relocations end up between the __rela_iplt_start and __rela_iplt_end +# symbols and that RELATIVE relocations added by CAPINIT static relocations end +# up between __rela_dyn_start and __rela_dyn_end. +#as: -march=morello+c64 +#ld: +#objdump: -Dzr --section-headers --syms + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]+ +[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt +([0-9a-f]+) ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, DATA +#... +SYMBOL TABLE: +#record: RELA_IPLT_END +#... +([0-9a-f]+) l \.rela\.plt 0000000000000000 __rela_iplt_end +#record: RELA_IPLT_START +([0-9a-f]+) l \.rela\.plt 0000000000000000 __rela_iplt_start +#record: RELA_DYN_END +([0-9a-f]+) l O \.rela\.dyn 0000000000000000 __rela_dyn_end +#record: RELA_DYN_START +([0-9a-f]+) l O \.rela\.dyn 0000000000000000 __rela_dyn_start +#... + +Disassembly of section \.rela\.dyn: + +#check: RELA_START format %016x 0x$RELA_DYN_START +RELA_START <__rela_dyn_start>: +#record: CHERICAP_A_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e803 .* + *[0-9a-f]+: 00000000 .* +#record: CHERICAP_ADDEND + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* +# __rela_iplt_end and __rela_iplt_start relocations. +# These were just added in order to get the symbols in the output binary. +# There is nothing we want to check around them. + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* +#check: CCAP_ADDEND string tolower $CHERICAP_ADDEND +#record: CHERICAP_B_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e803 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: CCAP_ADDEND .* + *[0-9a-f]+: 00000000 .* +#record: CHERICAP_C_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e803 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: CCAP_ADDEND .* + *[0-9a-f]+: 00000000 .* +#record: GOT_IFUNC_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e803 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: CCAP_ADDEND .* +#check: RELA_DYN_LAST format %x [expr "0x$RELA_DYN_END - 0x4"] + *RELA_DYN_LAST: 00000000 .* + +Disassembly of section \.rela\.plt: + +[0-9a-f]+ <__rela_iplt_start>: +#record: PLTGOT_LOC + +[0-9a-f]+: ([0-9a-f]+) .* + +[0-9a-f]+: 00000000 .* + +[0-9a-f]+: 0000e804 .* + +[0-9a-f]+: 00000000 .* +#record: IREL_ADDEND + +[0-9a-f]+: ([0-9a-f]+) .* + +[0-9a-f]+: 00000000 .* + +Disassembly of section \.plt: + +#check: PLTGOT_PAGE format %x [expr "0x$PLTGOT_LOC & (~0xfff)"] +#check: PLTGOT_DEC_OFF expr "0x$PLTGOT_LOC & 0xfff" +#check: PLTADDR_LOC format %x [expr "0x$PCC_START + (0x$CHERICAP_ADDEND & ~1)"] +[0-9a-f]+ <\.plt>: + *PLTADDR_LOC: .* adrp c16, PLTGOT_PAGE .* + *[0-9a-f]+: .* ldr c17, \[c16, #PLTGOT_DEC_OFF\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: .* br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#check: FOO_ADDR format %016x [expr "0x$PCC_START + (0x$IREL_ADDEND & ~1)"] +FOO_ADDR : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* // b\.any + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, .* + *[0-9a-f]+: .* b .* + +#check: GOT_PAGE format %x [expr "0x$GOT_IFUNC_LOC & (~0xfff)"] +#check: GOT_DEC_OFF expr "0x$GOT_IFUNC_LOC & 0xfff" +#check: PLTADDR_PAGE format %x [expr "(0x$PCC_START + 0x$CHERICAP_ADDEND) & (~0xfff)"] +#check: PLTADDR_OFF format %x [expr "(0x$PCC_START + 0x$CHERICAP_ADDEND) & 0xfff"] +[0-9a-f]+ <_start>: + *[0-9a-f]+: .* bl PLTADDR_LOC .* + *[0-9a-f]+: .* adrp c0, GOT_PAGE .* + *[0-9a-f]+: .* ldr c0, \[c0, #GOT_DEC_OFF\] + *[0-9a-f]+: .* adrp c0, PLTADDR_PAGE .* + *[0-9a-f]+: .* add c0, c0, #0xPLTADDR_OFF + *[0-9a-f]+: .* ret c30 + +Disassembly of section \.got: + +#check: GOTLOC format %x 0x$GOT_IFUNC_LOC +#check: FRAGBASE format %08x 0x$PCC_START +#check: FRAGSIZE format %08x [expr "0x$PCC_LAST_SIZE + 0x$PCC_LAST_START - 0x$PCC_START"] +[0-9a-f]+ <.*>: + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *GOTLOC: FRAGBASE .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* + +Disassembly of section \.got\.plt: + +#check: PLTGOT_ADDR format %x 0x$PLTGOT_LOC +[0-9a-f]+ <.*>: + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *PLTGOT_ADDR: FRAGBASE .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#... +Disassembly of section \.data: +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc4.s b/ld/testsuite/ld-aarch64/morello-ifunc4.s new file mode 100644 index 0000000000000000000000000000000000000000..5040f9a471786e01415aa2e973923b21249116b2 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc4.s @@ -0,0 +1,56 @@ + .text +#APP + .type foo, %gnu_indirect_function +#NO_APP + .align 2 + .type foo_1, %function +foo_1: + mov w0, 1 + ret + .size foo_1, .-foo_1 + .align 2 + .type foo_2, %function +foo_2: + mov w0, 2 + ret + .size foo_2, .-foo_2 + .align 2 + + .global foo + .type foo, %function +foo: + mov x1, 42 + tst x0, x1 + bne .L5 + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 +.L4: + ret +.L5: + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 + b .L4 + .size foo, .-foo + .align 2 + + .global _start + .type _start, %function +_start: + bl foo + adrp c0, :got:foo + ldr c0, [c0, #:got_lo12:foo] + // Adding direct relocation against `foo` to ensure that we need + // pointer equality. This should change the behaviour of the CAPINIT + // and GOT relocations. + adrp c0, foo + add c0, c0, :lo12:foo + ret + .size _start, .-_start + + .data + .align 4 + .chericap foo + .chericap __rela_iplt_start + .chericap __rela_iplt_end + .chericap foo + .chericap foo diff --git a/ld/testsuite/ld-aarch64/morello-ifunc4a.d b/ld/testsuite/ld-aarch64/morello-ifunc4a.d new file mode 100644 index 0000000000000000000000000000000000000000..fd6020d6f20d314ae4e6a7cdf98ff0a6a4c78882 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc4a.d @@ -0,0 +1,161 @@ +# Checking that the IRELATIVE relocations which are added by CAPINIT +# static relocations end up between the __rela_iplt_start and __rela_iplt_end +# symbols and that RELATIVE relocations added by CAPINIT static relocations end +# up between __rela_dyn_start and __rela_dyn_end. +#as: -march=morello+c64 +#ld: +#objdump: -Dzr --section-headers --syms + +.*: file format .* + +Sections: +Idx Name Size VMA LMA File off Algn +#record: PCC_START + 0 \.[^ ]+ +[0-9a-f]+ ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, READONLY, DATA +#record: PCC_LAST_SIZE PCC_LAST_START +#... + *[0-9]+ \.got\.plt +([0-9a-f]+) ([0-9a-f]+) [0-9a-f]+ [0-9a-f]+ 2\*\*. + CONTENTS, ALLOC, LOAD, DATA +#... +SYMBOL TABLE: +#record: RELA_IPLT_END +#... +([0-9a-f]+) l \.rela\.plt 0000000000000000 __rela_iplt_end +#record: RELA_IPLT_START +([0-9a-f]+) l \.rela\.plt 0000000000000000 __rela_iplt_start +#record: RELA_DYN_END +([0-9a-f]+) l O \.rela\.dyn 0000000000000000 __rela_dyn_end +#record: RELA_DYN_START +([0-9a-f]+) l O \.rela\.dyn 0000000000000000 __rela_dyn_start +#... + +Disassembly of section \.rela\.dyn: + +#check: RELA_START format %016x 0x$RELA_DYN_START +RELA_START <__rela_dyn_start>: +# __rela_iplt_end and __rela_iplt_start relocations. +# These were just added in order to get the symbols in the output binary. +# There is nothing we want to check around them. + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* + *[0-9a-f]+: ........ .* +#check: RELA_DYN_LAST format %x [expr "0x$RELA_DYN_END - 0x4"] + *RELA_DYN_LAST: 00000000 .* + +Disassembly of section \.rela\.plt: + +[0-9a-f]+ <__rela_iplt_start>: +#record: PLTGOT_LOC + +[0-9a-f]+: ([0-9a-f]+) .* + +[0-9a-f]+: 00000000 .* + +[0-9a-f]+: 0000e804 .* + +[0-9a-f]+: 00000000 .* +#record: IREL_ADDEND + +[0-9a-f]+: ([0-9a-f]+) .* + +[0-9a-f]+: 00000000 .* +#record: CHERICAP_A_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e804 .* + *[0-9a-f]+: 00000000 .* +#check: CCAP_ADDEND string tolower $IREL_ADDEND + *[0-9a-f]+: CCAP_ADDEND .* + *[0-9a-f]+: 00000000 .* +#record: CHERICAP_B_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e804 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: CCAP_ADDEND .* + *[0-9a-f]+: 00000000 .* +#record: CHERICAP_C_LOC + *[0-9a-f]+: ([0-9a-f]+) .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 0000e804 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: CCAP_ADDEND .* +#check: RELA_IPLT_LAST format %x [expr "0x$RELA_IPLT_END - 0x4"] + *RELA_IPLT_LAST: 00000000 .* + +Disassembly of section \.plt: + +#check: PLTGOT_PAGE format %x [expr "0x$PLTGOT_LOC & (~0xfff)"] +#check: PLTGOT_DEC_OFF expr "0x$PLTGOT_LOC & 0xfff" +[0-9a-f]+ <\.plt>: +#record: PLTADDR + *([0-9a-f]+): .* adrp c16, PLTGOT_PAGE .* + *[0-9a-f]+: .* ldr c17, \[c16, #PLTGOT_DEC_OFF\] + *[0-9a-f]+: .* add c16, c16, #0x.* + *[0-9a-f]+: .* br c17 + +Disassembly of section \.text: + +[0-9a-f]+ : +#... + +[0-9a-f]+ : +#... + +#check: FOO_ADDR format %016x [expr "0x$PCC_START + (0x$IREL_ADDEND & ~1)"] +FOO_ADDR : + *[0-9a-f]+: .* mov x1, #0x2a // #42 + *[0-9a-f]+: .* tst x0, x1 + *[0-9a-f]+: .* b\.ne .* // b\.any + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, c0, .* + *[0-9a-f]+: .* ret c30 + *[0-9a-f]+: .* adrp c0, .* + *[0-9a-f]+: .* add c0, .* + *[0-9a-f]+: .* b .* + +#check: GOT_PAGE format %x [expr "0x$PLTGOT_LOC & (~0xfff)"] +#check: GOT_DEC_OFF expr "0x$PLTGOT_LOC & 0xfff" +#check: PLT_LOC string tolower $PLTADDR +[0-9a-f]+ <_start>: + *[0-9a-f]+: .* bl PLT_LOC .* + *[0-9a-f]+: .* adrp c0, GOT_PAGE .* + *[0-9a-f]+: .* ldr c0, \[c0, #GOT_DEC_OFF\] + *[0-9a-f]+: .* ret c30 + +Disassembly of section \.got: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + +Disassembly of section \.got\.plt: + +#check: FRAGBASE format %08x 0x$PCC_START +#check: FRAGSIZE format %08x [expr "0x$PCC_LAST_SIZE + 0x$PCC_LAST_START - 0x$PCC_START"] +#check: PLTGOT_ADDR format %x 0x$PLTGOT_LOC +[0-9a-f]+ <.*>: + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: 00000000 .* + *PLTGOT_ADDR: FRAGBASE .* + *[0-9a-f]+: 00000000 .* + *[0-9a-f]+: FRAGSIZE .* + *[0-9a-f]+: 04000000 .* +#... +Disassembly of section \.data: +#pass diff --git a/ld/testsuite/ld-aarch64/morello-ifunc4a.s b/ld/testsuite/ld-aarch64/morello-ifunc4a.s new file mode 100644 index 0000000000000000000000000000000000000000..64c3facc6b815091c4205f5a720a5a50de065668 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-ifunc4a.s @@ -0,0 +1,51 @@ + .text +#APP + .type foo, %gnu_indirect_function +#NO_APP + .align 2 + .type foo_1, %function +foo_1: + mov w0, 1 + ret + .size foo_1, .-foo_1 + .align 2 + .type foo_2, %function +foo_2: + mov w0, 2 + ret + .size foo_2, .-foo_2 + .align 2 + + .global foo + .type foo, %function +foo: + mov x1, 42 + tst x0, x1 + bne .L5 + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 +.L4: + ret +.L5: + adrp c0, foo_1 + add c0, c0, :lo12:foo_1 + b .L4 + .size foo, .-foo + .align 2 + + .global _start + .type _start, %function +_start: + bl foo + adrp c0, :got:foo + ldr c0, [c0, #:got_lo12:foo] + ret + .size _start, .-_start + + .data + .align 4 + .chericap foo + .chericap __rela_iplt_start + .chericap __rela_iplt_end + .chericap foo + .chericap foo