From: Siddhesh Poyarekar Date: Fri, 11 Sep 2020 03:48:11 +0000 (+0530) Subject: [Morello] TLS Descriptor support X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1b5fb87b2c8a9023657eb912ab44c0490acd431;p=thirdparty%2Fbinutils-gdb.git [Morello] TLS Descriptor support This change adds basic support for TLS descriptors. Relaxation of TLSDESC_GD to other relocations is limited to TLS_LE, other cases end up retaining TLSDESC_GD. There is one key difference from A64 for TLSDESC_GD -> LE transition and that is in the case of static non-pie binaries. Morello TLSDESC_GD relocations are relaxed to LE for static non-pie binaries since it ought to be safe to do so and it aligns with llvm behaviour. bfd/ChangeLog: 2020-10-20 Siddhesh Poyarekar * elfnn-aarch64.c (IS_AARCH64_TLSDESC_RELOC): Add Morello relocations. (elfNN_aarch64_tlsdesc_small_plt_c64_entry): New Morello tlsdesc PLT entry. (elfNN_aarch64_howto_table): Add TLSDESC_ADR_PAGE20, TLSDESC_LD128_LO12, TLSDESC_CALL, TLSDESC relocations for Morello. (aarch64_tls_transition_without_check): Add INFO and MORELLO_RELOC arguments. Add morello TLSDESC relocations. (aarch64_reloc_got_type, elfNN_aarch64_final_link_relocate, elfNN_aarch64_tls_relax, elfNN_aarch64_check_relocs, aarch64_can_relax_tls): Add morello TLSDESC relocations. (aarch64_tls_transition): Add transitions for morello TLSDESC relocations. (elfNN_aarch64_tls_relax): Add relaxations for morello TLSDESC. (elfNN_aarch64_relocate_section): Emit dynamic relocation for Morello static relocations. (elfNN_aarch64_allocate_dynrelocs): Allocate dynamic relocation space for Morello TLSDESC. (elfNN_aarch64_finish_dynamic_sections): Emit Morello tlsdesc PLT entry. * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend, _bfd_aarch64_elf_resolve_relocation): Add Morello relocations. * reloc.c: Add Morello relocations. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. gas/ChangeLog: 2020-10-20 Siddhesh Poyarekar * config/tc-aarch64.c (s_tlsdesccall): Emit Morello TLSDESC_CALL in C64 code. (reloc_table): Add Morello relocation. (md_apply_fix): Emit Morello TLSDESC_LD128_LO12 in C64 code. (aarch64_force_relocation): Add Morello TLSDESC relocations. * testsuite/gas/aarch64/morello-tlsdesc-c64.d: New file. * testsuite/gas/aarch64/morello-tlsdesc.d: New file. * testsuite/gas/aarch64/morello-tlsdesc.s: New file. include/ChangeLog: 2020-10-20 Siddhesh Poyarekar * elf/aarch64.h: New Morello TLSDESC relocations. ld/ChangeLog: 2020-10-20 Siddhesh Poyarekar * testsuite/ld-aarch64/morello-tlsdesc.s: New file. * testsuite/ld-aarch64/morello-tlsdesc.d: New test. * testsuite/ld-aarch64/morello-tlsdesc-static.d: New test. * testsuite/ld-aarch64/morello-tlsdesc-staticpie.d: New test. * testsuite/ld-aarch64/aarch64-elf.exp: Add them. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d8312a4e2f4..e4a674e4fc4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,33 @@ +2020-10-20 Siddhesh Poyarekar + + * elfnn-aarch64.c (IS_AARCH64_TLSDESC_RELOC): Add Morello + relocations. + (elfNN_aarch64_tlsdesc_small_plt_c64_entry): New Morello + tlsdesc PLT entry. + (elfNN_aarch64_howto_table): Add TLSDESC_ADR_PAGE20, + TLSDESC_LD128_LO12, TLSDESC_CALL, TLSDESC relocations for + Morello. + (aarch64_tls_transition_without_check): Add INFO and + MORELLO_RELOC arguments. Add morello TLSDESC relocations. + (aarch64_reloc_got_type, elfNN_aarch64_final_link_relocate, + elfNN_aarch64_tls_relax, elfNN_aarch64_check_relocs, + aarch64_can_relax_tls): Add morello TLSDESC relocations. + (aarch64_tls_transition): Add transitions for morello TLSDESC + relocations. + (elfNN_aarch64_tls_relax): Add relaxations for morello + TLSDESC. + (elfNN_aarch64_relocate_section): Emit dynamic relocation for + Morello static relocations. + (elfNN_aarch64_allocate_dynrelocs): Allocate dynamic + relocation space for Morello TLSDESC. + (elfNN_aarch64_finish_dynamic_sections): Emit Morello tlsdesc + PLT entry. + * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend, + _bfd_aarch64_elf_resolve_relocation): Add Morello relocations. + * reloc.c: Add Morello relocations. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + 2020-10-20 Siddhesh Poyarekar * elfnn-aarch64.c (elf_aarch64_link_hash_table): New member. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 715013762f7..c296277db88 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -5947,6 +5947,16 @@ instructions. */ /* AArch64 TLS DESC relocation. */ BFD_RELOC_AARCH64_TLSDESC_CALL, +/* Morello TLS DESC relocation. */ + BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20, + +/* bit[11:4] of byte offset to TLS base address, encoded in ldst instructions. */ + BFD_RELOC_MORELLO_TLSDESC_LD128_LO12, + +/* Relocation to identify the BLR call which performs an indirect call to the +TLS descriptor function. */ + BFD_RELOC_MORELLO_TLSDESC_CALL, + /* AArch64 TLS relocation. */ BFD_RELOC_AARCH64_COPY, @@ -5989,6 +5999,9 @@ instructions. */ /* C64 support for STT_GNU_IFUNC. */ BFD_RELOC_MORELLO_IRELATIVE, +/* Morello TLS relocation, identifies the TLS descriptor to be filled. */ + BFD_RELOC_MORELLO_TLSDESC, + /* AArch64 pseudo relocation code to mark the end of the AArch64 relocation enumerators that have direct mapping to ELF reloc codes. There are a few more enumerators after this one; those are mainly diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 949b08bfa10..d3b53395d93 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -225,10 +225,13 @@ #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE) \ ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \ + || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \ + || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_CALL \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \ + || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_LD128_LO12 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \ @@ -251,10 +254,13 @@ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \ + || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \ + || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_CALL \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12 \ + || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_LD128_LO12 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \ @@ -447,6 +453,19 @@ elfNN_aarch64_tlsdesc_small_plt_bti_entry[PLT_TLSDESC_ENTRY_SIZE] = 0x1f, 0x20, 0x03, 0xd5, /* nop */ }; +static const bfd_byte +elfNN_aarch64_tlsdesc_small_plt_c64_entry[PLT_TLSDESC_ENTRY_SIZE] = +{ + 0xe2, 0x8f, 0xbf, 0x62, /* stp c2, c3, [sp, #-16]! */ + 0x02, 0x00, 0x80, 0x90, /* adrp c2, 0 */ + 0x03, 0x00, 0x80, 0x90, /* adrp c3, 0 */ + 0x42, 0x00, 0x40, 0xc2, /* ldr c2, [c2, #0] */ + 0x63, 0x00, 0x00, 0x02, /* add c3, c3, 0 */ + 0x40, 0x10, 0xc2, 0xc2, /* br c2 */ + 0x1f, 0x20, 0x03, 0xd5, /* nop */ + 0x1f, 0x20, 0x03, 0xd5, /* nop */ +}; + #define elf_info_to_howto elfNN_aarch64_info_to_howto #define elf_info_to_howto_rel elfNN_aarch64_info_to_howto @@ -2173,6 +2192,51 @@ static reloc_howto_type elfNN_aarch64_howto_table[] = 0x0, /* dst_mask */ false), /* pcrel_offset */ + /* Get to the page for the GOT entry for the symbol + (G(S) - P) using an ADRP instruction. */ + HOWTO64 (MORELLO_R (TLSDESC_ADR_PAGE20), /* type */ + 12, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 20, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (TLSDESC_ADR_PAGE20), /* name */ + false, /* partial_inplace */ + 0xfffff, /* src_mask */ + 0xfffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* LD128: GOT offset G(S) & 0xff0. */ + HOWTO64 (MORELLO_R (TLSDESC_LD128_LO12), /* type */ + 4, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (TLSDESC_LD128_LO12), /* name */ + false, /* partial_inplace */ + 0xff0, /* src_mask */ + 0xff0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO64 (MORELLO_R (TLSDESC_CALL), /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (TLSDESC_CALL), /* name */ + false, /* partial_inplace */ + 0x0, /* src_mask */ + 0x0, /* dst_mask */ + false), /* pcrel_offset */ + HOWTO (AARCH64_R (COPY), /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -2381,6 +2445,20 @@ static reloc_howto_type elfNN_aarch64_howto_table[] = ALL_ONES, /* dst_mask */ false), /* pcrel_offset */ + HOWTO64 (MORELLO_R (TLSDESC), /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (TLSDESC), /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + false), /* pcrel_offset */ + EMPTY_HOWTO (0), }; @@ -5701,12 +5779,19 @@ aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h, static bfd_reloc_code_real_type aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type, - struct elf_link_hash_entry *h) + struct bfd_link_info *info, + struct elf_link_hash_entry *h, + bool morello_reloc) { bool is_local = h == NULL; switch (r_type) { + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: + return (is_local || !bfd_link_pic (info) + ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 + : r_type); + case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: return (is_local @@ -5738,6 +5823,10 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type, ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1); + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: + return ((is_local || !bfd_link_pie (info) + ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type)); + case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC: case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: return (is_local @@ -5758,10 +5847,19 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type, ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19); - case BFD_RELOC_AARCH64_TLSDESC_ADD: + case BFD_RELOC_MORELLO_TLSDESC_CALL: + return ((is_local || !bfd_link_pie (info)) + ? BFD_RELOC_AARCH64_NONE : r_type); + case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: + if (morello_reloc && !is_local && bfd_link_pie (info)) + return r_type; + /* Fall through. */ + case BFD_RELOC_AARCH64_TLSDESC_ADD: case BFD_RELOC_AARCH64_TLSDESC_CALL: - /* Instructions with these relocations will become NOPs. */ + /* Instructions with these relocations will be fully resolved during the + transition into either a NOP in the A64 case or movk and add in + C64. */ return BFD_RELOC_AARCH64_NONE; case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC: @@ -5818,6 +5916,11 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type) case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: return GOT_TLS_GD; + 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; + case BFD_RELOC_AARCH64_TLSDESC_ADD: case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: @@ -5848,18 +5951,22 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type) static bool aarch64_can_relax_tls (bfd *input_bfd, struct bfd_link_info *info, - bfd_reloc_code_real_type r_type, + const Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, unsigned long r_symndx) { unsigned int symbol_got_type; unsigned int reloc_got_type; - if (! IS_AARCH64_TLS_RELAX_RELOC (r_type)) + bfd_reloc_code_real_type bfd_r_type + = elfNN_aarch64_bfd_reloc_from_type (input_bfd, + ELFNN_R_TYPE (rel->r_info)); + + if (! IS_AARCH64_TLS_RELAX_RELOC (bfd_r_type)) return false; symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx); - reloc_got_type = aarch64_reloc_got_type (r_type); + reloc_got_type = aarch64_reloc_got_type (bfd_r_type); if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type)) return true; @@ -5879,17 +5986,29 @@ aarch64_can_relax_tls (bfd *input_bfd, static bfd_reloc_code_real_type aarch64_tls_transition (bfd *input_bfd, struct bfd_link_info *info, - unsigned int r_type, + const Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, unsigned long r_symndx) { bfd_reloc_code_real_type bfd_r_type - = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type); + = elfNN_aarch64_bfd_reloc_from_type (input_bfd, + ELFNN_R_TYPE (rel->r_info)); + + if (! aarch64_can_relax_tls (input_bfd, info, rel, h, r_symndx)) + return bfd_r_type; - if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx)) + bool morello_reloc = (bfd_r_type == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12 + && (ELFNN_R_TYPE (rel[1].r_info) + == MORELLO_R (TLSDESC_CALL))); + + /* GD -> IE is not supported for Morello TLSDESC yet. We do however allow + lowering of GD -> LE for static non-pie executables. XXX It ought to be + safe to do this for A64 as well but it is not implemented yet. */ + if (h != NULL && morello_reloc && bfd_link_pie (info)) return bfd_r_type; - return aarch64_tls_transition_without_check (bfd_r_type, h); + return aarch64_tls_transition_without_check (bfd_r_type, info, h, + morello_reloc); } /* Return the base VMA address which should be subtracted from real addresses @@ -6664,6 +6783,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, case BFD_RELOC_AARCH64_TLSDESC_ADD: case BFD_RELOC_AARCH64_TLSDESC_CALL: case BFD_RELOC_AARCH64_TLSDESC_LDR: + case BFD_RELOC_MORELLO_TLSDESC_CALL: *unresolved_reloc_p = false; return bfd_reloc_ok; @@ -7211,10 +7331,12 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: if (globals->root.sgot == NULL) return bfd_reloc_notsupported; value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx) @@ -7402,6 +7524,11 @@ clear_erratum_843419_entry (struct elf_aarch64_link_hash_table *globals, } } +#define BUILD_MOVZ(_reg, _imm) (movz_R0 \ + | ((((_imm) >> 16) & 0xffff) << 5) \ + | (_reg)) +#define BUILD_MOVK(_reg, _imm) (movk_R0 | (((_imm) & 0xffff) << 5) | (_reg)) + /* Handle TLS relaxations. Relaxing is possible for symbols that use R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static link. @@ -7411,19 +7538,56 @@ clear_erratum_843419_entry (struct elf_aarch64_link_hash_table *globals, case of error. */ static bfd_reloc_status_type -elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals, - bfd *input_bfd, asection *input_section, +elfNN_aarch64_tls_relax (bfd *input_bfd, struct bfd_link_info *info, + asection *input_section, bfd_byte *contents, Elf_Internal_Rela *rel, - struct elf_link_hash_entry *h) + struct elf_link_hash_entry *h, unsigned long r_symndx) { bool is_local = h == NULL; + unsigned int r_type = ELFNN_R_TYPE (rel->r_info); unsigned long insn; + bfd_vma sym_size = 0; + struct elf_aarch64_link_hash_table *globals = elf_aarch64_hash_table (info); BFD_ASSERT (globals && input_bfd && contents && rel); + if (is_local) + { + if (h != NULL) + sym_size = h->size; + else + { + Elf_Internal_Sym *sym; + + sym = bfd_sym_from_r_symndx (&globals->root.sym_cache, input_bfd, + r_symndx); + BFD_ASSERT (sym != NULL); + sym_size = sym->st_size; + } + } + switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type)) { + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: + if (is_local || !bfd_link_pic (info)) + { + /* GD->LE relaxation: + nop => movz x1, objsize_hi16 + adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var */ + bfd_putl32 (BUILD_MOVZ(1, sym_size), contents + rel->r_offset - 4); + bfd_putl32 (movz_R0, contents + rel->r_offset); + + /* We have relaxed the adrp into a mov, we may have to clear any + pending erratum fixes. */ + clear_erratum_843419_entry (globals, rel->r_offset, input_section); + return bfd_reloc_continue; + } + else + { + /* GD->IE relaxation: Not implemented. */ + return bfd_reloc_continue; + } case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: if (is_local) @@ -7592,6 +7756,19 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals, case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: return bfd_reloc_continue; + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: + if (is_local || !bfd_link_pic (info)) + { + /* GD->LE relaxation: + ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var */ + bfd_putl32 (movk_R0, contents + rel->r_offset); + return bfd_reloc_continue; + } + else + { + /* GD->IE relaxation: not implemented. */ + return bfd_reloc_continue; + } case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC: if (is_local) { @@ -7656,13 +7833,35 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals, return bfd_reloc_continue; } - case BFD_RELOC_AARCH64_TLSDESC_ADD: + case BFD_RELOC_MORELLO_TLSDESC_CALL: + /* GD->LE relaxation: + blr cd => add c0, c2, x0 */ + if (is_local || !bfd_link_pic (info)) + { + bfd_putl32 (0xc2a06040, contents + rel->r_offset); + return bfd_reloc_ok; + } + else + goto set_nop; + case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: + /* GD->LE relaxation: + ldr cd, [c0, #:tlsdesc_lo12:var] => movk x1, objsize_lo16 */ + if ((is_local || !bfd_link_pic (info)) + && ELFNN_R_TYPE (rel[1].r_info) == MORELLO_R (TLSDESC_CALL)) + { + bfd_putl32 (BUILD_MOVK(1, sym_size), contents + rel->r_offset); + return bfd_reloc_continue; + } + + /* Fall through. */ + case BFD_RELOC_AARCH64_TLSDESC_ADD: case BFD_RELOC_AARCH64_TLSDESC_CALL: /* GD->IE/LE relaxation: add x0, x0, #:tlsdesc_lo12:var => nop blr xd => nop */ +set_nop: bfd_putl32 (INSN_NOP, contents + rel->r_offset); return bfd_reloc_ok; @@ -7947,7 +8146,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd, We call elfNN_aarch64_final_link_relocate unless we're completely done, i.e., the relaxation produced the final output we want. */ - relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type, + relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, rel, h, r_symndx); if (relaxed_bfd_r_type != bfd_r_type) { @@ -7955,8 +8154,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd, howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type); BFD_ASSERT (howto != NULL); r_type = howto->type; - r = elfNN_aarch64_tls_relax (globals, input_bfd, input_section, - contents, rel, h); + r = elfNN_aarch64_tls_relax (input_bfd, info, input_section, + contents, rel, h, r_symndx); unresolved_reloc = 0; } else @@ -7980,6 +8179,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd, h, &unresolved_reloc, save_addend, &addend, sym); + bool c64_rtype = false; + switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type)) { case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: @@ -8133,6 +8334,11 @@ elfNN_aarch64_relocate_section (bfd *output_bfd, } break; + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: + c64_rtype = true; + /* Fall through. */ + case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: @@ -8157,7 +8363,10 @@ elfNN_aarch64_relocate_section (bfd *output_bfd, { bfd_byte *loc; Elf_Internal_Rela rela; - rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC)); + + rela.r_info = ELFNN_R_INFO (indx, + (c64_rtype ? MORELLO_R (TLSDESC) + : AARCH64_R (TLSDESC))); rela.r_addend = 0; rela.r_offset = (globals->root.sgotplt->output_section->vma @@ -8741,12 +8950,10 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, { struct elf_link_hash_entry *h; unsigned int r_symndx; - unsigned int r_type; bfd_reloc_code_real_type bfd_r_type; Elf_Internal_Sym *isym; r_symndx = ELFNN_R_SYM (rel->r_info); - r_type = ELFNN_R_TYPE (rel->r_info); if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) { @@ -8790,7 +8997,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, } /* Could be done earlier, if h were already available. */ - bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx); + bfd_r_type = aarch64_tls_transition (abfd, info, rel, h, r_symndx); if (h != NULL) { @@ -9038,6 +9245,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, there are no dangling GOT_PAGE relocs. */ case BFD_RELOC_MORELLO_ADR_GOT_PAGE: case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC: + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: htab->c64_rel = 1; /* Fall through. */ @@ -9117,10 +9326,14 @@ 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); - /* GOT_CAP has higher precedence due to higher alignment and size - requirements, so do not overwrite it. XXX This should be - revisited when we add TLS relocations. */ - if (old_got_type != got_type && old_got_type != GOT_CAP) + /* 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) elf_aarch64_hash_entry (h)->got_type = got_type; @@ -9879,7 +10092,10 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) || h->root.type != bfd_link_hash_undefweak) && (!bfd_link_executable (info) || indx != 0 - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) + || 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)) { if (got_type & GOT_TLSDESC_GD) { @@ -10927,8 +11143,17 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, const bfd_byte *entry = elfNN_aarch64_tlsdesc_small_plt_entry; htab->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE; + unsigned adrp_rtype = BFD_RELOC_AARCH64_ADR_HI21_PCREL; + unsigned ldr_rtype = BFD_RELOC_AARCH64_LDSTNN_LO12; + aarch64_plt_type type = elf_aarch64_tdata (output_bfd)->plt_type; - if (type == PLT_BTI || type == PLT_BTI_PAC) + if (htab->c64_rel) + { + entry = elfNN_aarch64_tlsdesc_small_plt_c64_entry; + adrp_rtype = BFD_RELOC_MORELLO_ADR_HI20_PCREL; + ldr_rtype = BFD_RELOC_AARCH64_LDST128_LO12; + } + else if (type == PLT_BTI || type == PLT_BTI_PAC) { entry = elfNN_aarch64_tlsdesc_small_plt_bti_entry; } @@ -10968,21 +11193,21 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, /* adrp x2, DT_TLSDESC_GOT */ elf_aarch64_update_plt_entry (output_bfd, - BFD_RELOC_AARCH64_ADR_HI21_PCREL, + adrp_rtype, plt_entry + 4, (PG (dt_tlsdesc_got) - PG (adrp1_addr))); /* adrp x3, 0 */ elf_aarch64_update_plt_entry (output_bfd, - BFD_RELOC_AARCH64_ADR_HI21_PCREL, + adrp_rtype, plt_entry + 8, (PG (pltgot_addr) - PG (adrp2_addr))); /* ldr x2, [x2, #0] */ elf_aarch64_update_plt_entry (output_bfd, - BFD_RELOC_AARCH64_LDSTNN_LO12, + ldr_rtype, plt_entry + 12, PG_OFFSET (dt_tlsdesc_got)); diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c index f3dae319682..db3ed690652 100644 --- a/bfd/elfxx-aarch64.c +++ b/bfd/elfxx-aarch64.c @@ -263,11 +263,13 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, break; case BFD_RELOC_AARCH64_TLSDESC_CALL: + case BFD_RELOC_MORELLO_TLSDESC_CALL: break; case BFD_RELOC_MORELLO_ADR_GOT_PAGE: case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL: case BFD_RELOC_MORELLO_ADR_HI20_PCREL: + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: contents = _bfd_aarch64_reencode_adr_imm (contents, addend, 1); break; @@ -315,6 +317,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, case BFD_RELOC_AARCH64_LDST8_LO12: case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: @@ -447,6 +450,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd, { case BFD_RELOC_AARCH64_NONE: case BFD_RELOC_AARCH64_TLSDESC_CALL: + case BFD_RELOC_MORELLO_TLSDESC_CALL: break; case BFD_RELOC_MORELLO_LD_LO17_PCREL: @@ -543,6 +547,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd, break; case BFD_RELOC_MORELLO_ADR_GOT_PAGE: + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: case BFD_RELOC_AARCH64_ADR_GOT_PAGE: case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: @@ -575,6 +580,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd, case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: case BFD_RELOC_AARCH64_TLSDESC_LDR: case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: diff --git a/bfd/libbfd.h b/bfd/libbfd.h index b1e045faf98..e86a2152d98 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -3124,6 +3124,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_AARCH64_TLSDESC_LDR", "BFD_RELOC_AARCH64_TLSDESC_ADD", "BFD_RELOC_AARCH64_TLSDESC_CALL", + "BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20", + "BFD_RELOC_MORELLO_TLSDESC_LD128_LO12", + "BFD_RELOC_MORELLO_TLSDESC_CALL", "BFD_RELOC_AARCH64_COPY", "BFD_RELOC_AARCH64_GLOB_DAT", "BFD_RELOC_AARCH64_JUMP_SLOT", @@ -3138,6 +3141,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MORELLO_JUMP_SLOT", "BFD_RELOC_MORELLO_RELATIVE", "BFD_RELOC_MORELLO_IRELATIVE", + "BFD_RELOC_MORELLO_TLSDESC", "BFD_RELOC_AARCH64_RELOC_END", "BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP", "BFD_RELOC_AARCH64_LDST_LO12", diff --git a/bfd/reloc.c b/bfd/reloc.c index 8c9bdcd122e..1694459ed60 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -7536,6 +7536,19 @@ ENUM BFD_RELOC_AARCH64_TLSDESC_CALL ENUMDOC AArch64 TLS DESC relocation. +ENUM + BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20 +ENUMDOC + Morello TLS DESC relocation. +ENUM + BFD_RELOC_MORELLO_TLSDESC_LD128_LO12 +ENUMDOC + bit[11:4] of byte offset to TLS base address, encoded in ldst instructions. +ENUM + BFD_RELOC_MORELLO_TLSDESC_CALL +ENUMDOC + Relocation to identify the BLR call which performs an indirect call to the + TLS descriptor function. ENUM BFD_RELOC_AARCH64_COPY ENUMDOC @@ -7592,6 +7605,10 @@ ENUM BFD_RELOC_MORELLO_IRELATIVE ENUMDOC C64 support for STT_GNU_IFUNC. +ENUM + BFD_RELOC_MORELLO_TLSDESC +ENUMDOC + Morello TLS relocation, identifies the TLS descriptor to be filled. ENUM BFD_RELOC_AARCH64_RELOC_END ENUMDOC diff --git a/gas/ChangeLog b/gas/ChangeLog index f4470e7e253..bdbf538e691 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2020-10-20 Siddhesh Poyarekar + + * config/tc-aarch64.c (s_tlsdesccall): Emit Morello + TLSDESC_CALL in C64 code. + (reloc_table): Add Morello relocation. + (md_apply_fix): Emit Morello TLSDESC_LD128_LO12 in C64 code. + (aarch64_force_relocation): Add Morello TLSDESC relocations. + * testsuite/gas/aarch64/morello-tlsdesc-c64.d: New file. + * testsuite/gas/aarch64/morello-tlsdesc.d: New file. + * testsuite/gas/aarch64/morello-tlsdesc.s: New file. + 2020-10-20 Siddhesh Poyarekar * config/tc-aarch64.c (REG_DW_CSP, REG_DW_CLR): New macros. diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index d5777556169..2270b40727d 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -2112,7 +2112,8 @@ s_tlsdesccall (int ignored ATTRIBUTE_UNUSED) the .tlsdesc directive. */ frag_grow (4); fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 4, &exp, 0, - BFD_RELOC_AARCH64_TLSDESC_CALL); + (IS_C64 ? BFD_RELOC_MORELLO_TLSDESC_CALL + : BFD_RELOC_AARCH64_TLSDESC_CALL)); demand_empty_rest_of_line (); } @@ -2885,7 +2886,7 @@ static struct reloc_table_entry reloc_table[] = {"tlsdesc", 0, BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21, /* adr_type */ BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21, - 0, + BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20, 0, 0, 0, @@ -3222,10 +3223,12 @@ aarch64_force_reloc (unsigned int type) case BFD_RELOC_AARCH64_LDST64_LO12: case BFD_RELOC_AARCH64_LDST8_LO12: case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: @@ -7603,7 +7606,8 @@ addr_uimm: inst.reloc.type = ldst_lo12_determine_real_reloc_type (); } - else if (inst.reloc.type == BFD_RELOC_AARCH64_LD_GOT_LO12_NC + else if ((inst.reloc.type == BFD_RELOC_AARCH64_LD_GOT_LO12_NC + || inst.reloc.type == BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC) && inst.base.operands[0].qualifier == AARCH64_OPND_QLF_CA) inst.reloc.flags = FIXUP_F_C64; @@ -9648,9 +9652,12 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) break; case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC: - fixP->fx_r_type = (ilp32_p - ? BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC - : BFD_RELOC_AARCH64_TLSDESC_LD64_LO12); + if (fixP->tc_fix_data.c64) + fixP->fx_r_type = BFD_RELOC_MORELLO_TLSDESC_LD128_LO12; + else if (ilp32_p) + fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC; + else + fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD64_LO12; S_SET_THREAD_LOCAL (fixP->fx_addsy); /* Should always be exported to object file, see aarch64_force_relocation(). */ @@ -9659,10 +9666,12 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) break; case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: + case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: + case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: @@ -9757,6 +9766,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) case BFD_RELOC_AARCH64_TLSDESC_ADD: case BFD_RELOC_AARCH64_TLSDESC_CALL: + case BFD_RELOC_MORELLO_TLSDESC_CALL: case BFD_RELOC_AARCH64_TLSDESC_LDR: case BFD_RELOC_MORELLO_CAPINIT: break; diff --git a/gas/testsuite/gas/aarch64/morello-tlsdesc.d b/gas/testsuite/gas/aarch64/morello-tlsdesc.d new file mode 100644 index 00000000000..64364a0a2ab --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-tlsdesc.d @@ -0,0 +1,16 @@ +#source: morello-tlsdesc.s +#as: -march=morello+c64 +#objdump: -dr + +.*: file format .* + + +Disassembly of section .text: + +.*: +.*: 90800000 adrp c0, 0 + .*: R_MORELLO_TLSDESC_ADR_PAGE20 foo +.*: c2400001 ldr c1, \[c0\] + .*: R_MORELLO_TLSDESC_LD128_LO12 foo +.*: c2c23020 blr c1 + .*: R_MORELLO_TLSDESC_CALL foo diff --git a/gas/testsuite/gas/aarch64/morello-tlsdesc.s b/gas/testsuite/gas/aarch64/morello-tlsdesc.s new file mode 100644 index 00000000000..c5b8fea3b36 --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-tlsdesc.s @@ -0,0 +1,5 @@ +bar: + adrp c0, :tlsdesc:foo + ldr c1, [c0, #:tlsdesc_lo12:foo] + .tlsdesccall foo + blr c1 diff --git a/include/ChangeLog b/include/ChangeLog index 4fa1f3c5329..67f10a9f290 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2020-10-20 Siddhesh Poyarekar + + * elf/aarch64.h: New Morello TLSDESC relocations. + 2020-10-20 Siddhesh Poyarekar * elf/aarch64.h: New relocations R_MORELLO_TSTBR14, diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h index 4feac6711e2..4eb4691ed10 100644 --- a/include/elf/aarch64.h +++ b/include/elf/aarch64.h @@ -472,6 +472,10 @@ RELOC_NUMBER (R_MORELLO_ADR_GOT_PAGE, 57351) RELOC_NUMBER (R_MORELLO_LD128_GOT_LO12_NC, 57352) +RELOC_NUMBER (R_MORELLO_TLSDESC_ADR_PAGE20, 57600) +RELOC_NUMBER (R_MORELLO_TLSDESC_LD128_LO12, 57601) +RELOC_NUMBER (R_MORELLO_TLSDESC_CALL, 57602) + /* Morello dynamic relocations. */ RELOC_NUMBER (R_MORELLO_CAPINIT, 59392) @@ -479,6 +483,7 @@ RELOC_NUMBER (R_MORELLO_GLOB_DAT, 59393) RELOC_NUMBER (R_MORELLO_JUMP_SLOT, 59394) RELOC_NUMBER (R_MORELLO_RELATIVE, 59395) RELOC_NUMBER (R_MORELLO_IRELATIVE, 59396) +RELOC_NUMBER (R_MORELLO_TLSDESC, 59397) END_RELOC_NUMBERS (R_AARCH64_end) diff --git a/ld/ChangeLog b/ld/ChangeLog index d81c6939c49..72693ed03f0 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2020-10-20 Siddhesh Poyarekar + + * testsuite/ld-aarch64/morello-tlsdesc.s: New file. + * testsuite/ld-aarch64/morello-tlsdesc.d: New test. + * testsuite/ld-aarch64/morello-tlsdesc-static.d: New test. + * testsuite/ld-aarch64/morello-tlsdesc-staticpie.d: New test. + * testsuite/ld-aarch64/aarch64-elf.exp: Add them. + 2020-10-20 Siddhesh Poyarekar * emultempl/aarch64elf.em (elf64_c64_pad_section): New diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index ee965d11fae..df1b6dbc2e9 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -249,6 +249,9 @@ run_dump_test_lp64 "morello-capinit" run_dump_test_lp64 "morello-stubs" run_dump_test_lp64 "morello-stubs-static" run_dump_test_lp64 "morello-sec-round" +run_dump_test_lp64 "morello-tlsdesc" +run_dump_test_lp64 "morello-tlsdesc-static" +run_dump_test_lp64 "morello-tlsdesc-staticpie" run_dump_test "reloc-overflow-bad" diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc-static.d b/ld/testsuite/ld-aarch64/morello-tlsdesc-static.d new file mode 100644 index 00000000000..372f369e7a2 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-tlsdesc-static.d @@ -0,0 +1,29 @@ +#source: morello-tlsdesc.s +#as: -march=morello+c64 --defsym STATIC=1 +#ld: +#objdump: -D -j .got.plt -j .text -j .plt + + +.*: file format .* + + +Disassembly of section .text: + +.*: +.*: 94000008 bl .* <_start> +.*: c29bd042 mrs c2, ctpidr_el0 +.*: d2a00001 movz x1, #0x0, lsl #16 +.*: d2a00000 movz x0, #0x0, lsl #16 +.*: f2800200 movk x0, #0x10 +.*: f2800001 movk x1, #0x0 +.*: c2a06040 add c0, c2, x0, uxtx +.*: c2c10000 scbnds c0, c0, x1 + +.*<_start>: +.*: c29bd042 mrs c2, ctpidr_el0 +.*: d2a00001 movz x1, #0x0, lsl #16 +.*: d2a00000 movz x0, #0x0, lsl #16 +.*: f2800280 movk x0, #0x14 +.*: f2800281 movk x1, #0x14 +.*: c2a06040 add c0, c2, x0, uxtx +.*: c2c10000 scbnds c0, c0, x1 diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc-staticpie.d b/ld/testsuite/ld-aarch64/morello-tlsdesc-staticpie.d new file mode 100644 index 00000000000..e391d86962c --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-tlsdesc-staticpie.d @@ -0,0 +1,54 @@ +#source: morello-tlsdesc.s +#as: -march=morello+c64 --defsym STATIC=1 +#ld: -pie +#objdump: -DR -j .got.plt -j .text -j .plt + +.*: file format .* + + +Disassembly of section .plt: + +.*<.plt>: +.*: 62bf7bf0 stp c16, c30, \[csp, #-32\]! +.*: 908...90 adrp c16, .* +.*: c2....11 ldr c17, \[c16, #[0-9]+\] +.*: 02....10 add c16, c16, #0x[0-9a-f]+ +.*: c2c21220 br c17 +.*: d503201f nop +.*: d503201f nop +.*: d503201f nop +.*: 62bf8fe2 stp c2, c3, \[csp, #-16\]! +.*: 908...82 adrp c2, .* +.*: 908...83 adrp c3, .* +.*: c2....42 ldr c2, \[c2, #[0-9]+\] +.*: 02....63 add c3, c3, #0x[0-9a-f]+ +.*: c2c21040 br c2 +.*: d503201f nop +.*: d503201f nop + +Disassembly of section .text: + +.*: +.*: 94000008 bl .* <_start> +.*: c29bd042 mrs c2, ctpidr_el0 +.*: d503201f nop +.*: 908...80 adrp c0, .* +.*: c2....01 ldr c1, \[c0, #[0-9]+\] +.*: 02....00 add c0, c0, #0x[0-9a-f]+ +.*: c2c23020 blr c1 +.*: c2c10000 scbnds c0, c0, x1 + +.*<_start>: +.*: c29bd042 mrs c2, ctpidr_el0 +.*: d2a00001 movz x1, #0x0, lsl #16 +.*: d2a00000 movz x0, #0x0, lsl #16 +.*: f2800280 movk x0, #0x14 +.*: f2800281 movk x1, #0x14 +.*: c2....40 add c0, c2, x0, uxtx +.*: c2c10000 scbnds c0, c0, x1 + +Disassembly of section .got.plt: + +.*: + ... + .*: R_MORELLO_TLSDESC \*ABS\* diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc.d b/ld/testsuite/ld-aarch64/morello-tlsdesc.d new file mode 100644 index 00000000000..58336a7cbc8 --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-tlsdesc.d @@ -0,0 +1,89 @@ +#source: morello-tlsdesc.s +#as: -march=morello+c64 +#ld: -shared +#objdump: -DR -j .got.plt -j .text -j .plt + + +.*: file format .* + + +Disassembly of section .plt: + +.*<.plt>: +.*: 62bf7bf0 stp c16, c30, \[csp, #-32\]! +.*: 908...90 adrp c16, .* +.*: c2....11 ldr c17, \[c16, #[0-9]+\] +.*: 02....10 add c16, c16, #0x[0-9a-f]+ +.*: c2c21220 br c17 +.*: d503201f nop +.*: d503201f nop +.*: d503201f nop + +.*<_start@plt>: +.*: 908...90 adrp c16, .* +.*: c2....11 ldr c17, \[c16, #[0-9]+\] +.*: 02....10 add c16, c16, #0x[0-9a-f]+ +.*: c2c21220 br c17 + +.*: +.*: 908...90 adrp c16, .* +.*: c2....11 ldr c17, \[c16, #[0-9]+\] +.*: 02....10 add c16, c16, #0x[0-9a-f]+ +.*: c2c21220 br c17 + +.*: +.*: 62bf8fe2 stp c2, c3, \[csp, #-16\]! +.*: 908...82 adrp c2, .* +.*: 908...83 adrp c3, .* +.*: c2....42 ldr c2, \[c2, #[0-9]+\] + +.*: +.*: 02....63 add c3, c3, #0x[0-9a-f]+ +.*: c2c21040 br c2 +.*: d503201f nop +.*: d503201f nop + +Disassembly of section .text: + +.*: +.*: 97fffff4 bl .* +.*: c29bd042 mrs c2, ctpidr_el0 +.*: d503201f nop +.*: 908...80 adrp c0, .* +.*: c2....01 ldr c1, \[c0, #[0-9]+\] +.*: 02....00 add c0, c0, #0x[0-9a-f]+ +.*: c2c23020 blr c1 +.*: c2c10000 scbnds c0, c0, x1 + +.*: +.*: 97ffffe8 bl .* <_start@plt> +.*: c29bd042 mrs c2, ctpidr_el0 +.*: d503201f nop +.*: 908...80 adrp c0, .* +.*: c2....01 ldr c1, \[c0, #[0-9]+\] +.*: 02....00 add c0, c0, #0x[0-9a-f]+ +.*: c2c23020 blr c1 +.*: c2c10000 scbnds c0, c0, x1 + +.*<_start>: +.*: c29bd042 mrs c2, ctpidr_el0 +.*: d503201f nop +.*: 908...80 adrp c0, .* +.*: c2....01 ldr c1, \[c0, #[0-9]+\] +.*: 02....00 add c0, c0, #0x[0-9a-f]+ +.*: c2c23020 blr c1 +.*: c2c10000 scbnds c0, c0, x1 + +Disassembly of section .got.plt: + +.*: + ... +.*: [0-9a-f]+ .* + .*: R_MORELLO_JUMP_SLOT _start + ... +.*: [0-9a-f]+ .* + .*: R_MORELLO_JUMP_SLOT extf + ... + .*: R_MORELLO_TLSDESC \*ABS\*\+0x4 + .*: R_MORELLO_TLSDESC var1 + .*: R_MORELLO_TLSDESC var2 diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc.s b/ld/testsuite/ld-aarch64/morello-tlsdesc.s new file mode 100644 index 00000000000..5eab58a059d --- /dev/null +++ b/ld/testsuite/ld-aarch64/morello-tlsdesc.s @@ -0,0 +1,50 @@ +.section .tbss +.globl var2 +var2: + .word 0 + .size var2, .-var2 + +var3: + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .size var3, .-var3 + +.section .text +.ifndef STATIC +f1: + bl extf + mrs c2, CTPIDR_EL0 + nop + adrp c0, :tlsdesc:var1 + ldr c1, [c0, #:tlsdesc_lo12:var1] + add c0, c0, #:tlsdesc_lo12:var1 + .tlsdesccall var1 + blr c1 + scbnds c0, c0, x1 +.endif + +f2: + bl _start + mrs c2, CTPIDR_EL0 + nop + adrp c0, :tlsdesc:var2 + ldr c1, [c0, #:tlsdesc_lo12:var2] + add c0, c0, #:tlsdesc_lo12:var2 + .tlsdesccall var2 + blr c1 + scbnds c0, c0, x1 + +.globl _start +.type _start, STT_FUNC +_start: + mrs c2, CTPIDR_EL0 + nop + adrp c0, :tlsdesc:var3 + ldr c1, [c0, #:tlsdesc_lo12:var3] + add c0, c0, #:tlsdesc_lo12:var3 + .tlsdesccall var3 + blr c1 + scbnds c0, c0, x1