From: Siddhesh Poyarekar Date: Fri, 11 Sep 2020 03:48:10 +0000 (+0530) Subject: [Morello] Implement branch relocations X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e19e91991191ef3e02bfb9b16b87b81f9db5c44e;p=thirdparty%2Fbinutils-gdb.git [Morello] Implement branch relocations This implements the following static relocations: - R_MORELLO_CALL26, R_MORELLO_JUMP26 - R_MORELLO_TSTBR14, R_MORELLO_CONDBR19 and the following dynamic relocations: - R_MORELLO_JUMP_SLOT and R_MORELLO_IRELATIVE Some notes on the implementation: - The linker selects morello PLT stubs when it finds at least one static relocation that needs a capability GOT slot. - It is assumed that C64 is not compatible with BTI/PAC, so the latter gets overridden. To allow this, the call to setup_plt_values is delayed to take into account htab->c64_plt. - If the caller is A64, the assembler emits R_AARCH64_JUMP_SLOT, otherwise it emits R_MORELLO_JUMP_SLOT. - The PLT stub is A64-compatible, in that it should do the right thing when the execution state is A64. - If the slots are 16-bytes (this happens when there is at least one Morello relocation on the GOT), the references in .plt.got and in .got are always capabilities; the dynamic linker will take care of that. For PLT, the default trampoline is a capability. This is true for A64 as well as C64. - At present it is assumed that there is no interworking between A64 and C64 functions. bfd/ChangeLog: 2020-10-20 Siddhesh Poyarekar * elfnn-aarch64.c (elfNN_c64_small_plt0_entry, elfNN_c64_small_plt_entry): New variables. (elfNN_aarch64_howto_table): Add relocations. (setup_plt_values): Choose C64 PLT when appropriate. (bfd_elfNN_aarch64_set_options): Defer setup_plt_values call... (elfNN_aarch64_link_setup_gnu_properties) ... from here as well... (elfNN_aarch64_size_dynamic_sections): ... to here. (elfNN_aarch64_final_link_relocate, elfNN_aarch64_check_relocs, elfNN_aarch64_reloc_type_class): Support new relocations. (map_symbol_type): New member AARCH64_MAP_C64. (elfNN_aarch64_output_arch_local_syms): Use it. (aarch64_update_c64_plt_entry): New function. (elfNN_aarch64_create_small_pltn_entry): Use it. (elfNN_aarch64_init_small_plt0_entry): Emit C64 PLT when appropriate. * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend, _bfd_aarch64_elf_resolve_relocation): Add new relocations. * libbfd.h (bfd_reloc_code_real_names): Likewise. * reloc.c: New relocations BFD_RELOC_MORELLO_TSTBR14, BFD_RELOC_MORELLO_BRANCH19, BFD_RELOC_MORELLO_JUMP26, BFD_RELOC_MORELLO_CALL26, BFD_RELOC_MORELLO_JUMP_SLOT and BFD_RELOC_MORELLO_IRELATIVE. * bfd-in2.h: Regenerate. gas/ChangeLog: 2020-10-20 Siddhesh Poyarekar * config/tc-aarch64.c (parse_operands): Choose C64 branch relocations when appropriate. (md_apply_fix, aarch64_force_relocation, aarch64_fix_adjustable): Support C64 branch relocations. include/ChangeLog: 2020-10-20 Siddhesh Poyarekar * elf/aarch64.h: New relocations R_MORELLO_TSTBR14, R_MORELLO_CONDBR19, R_MORELLO_JUMP26, R_MORELLO_CALL26, R_MORELLO_JUMP_SLOT and R_MORELLO_IRELATIVE. ld/ChangeLog: 2020-10-20 Siddhesh Poyarekar * testsuite/ld-aarch64/aarch64-elf.exp: Add new tests. * testsuite/ld-aarch64/c64-ifunc-2-local.d: New file. * testsuite/ld-aarch64/c64-ifunc-2.d: New file. * testsuite/ld-aarch64/c64-ifunc-3a.d: New file. * testsuite/ld-aarch64/c64-ifunc-3b.d: New file. * testsuite/ld-aarch64/c64-ifunc-4.d: New file. * testsuite/ld-aarch64/c64-ifunc-4a.d: New file. * testsuite/ld-aarch64/ifunc-2-local.s: Support capabilities. * testsuite/ld-aarch64/ifunc-2.s: Likewise. opcodes/ChangeLog: 2020-10-20 Siddhesh Poyarekar * aarch64-dis.c (get_sym_code_type): Fix C64 PLT disassembly. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5e4d909d941..6648a26cc3e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,32 @@ +2020-10-20 Siddhesh Poyarekar + + * elfnn-aarch64.c (elfNN_c64_small_plt0_entry, + elfNN_c64_small_plt_entry): New variables. + (elfNN_aarch64_howto_table): Add relocations. + (setup_plt_values): Choose C64 PLT when appropriate. + (bfd_elfNN_aarch64_set_options): Defer setup_plt_values + call... + (elfNN_aarch64_link_setup_gnu_properties) ... from here as + well... + (elfNN_aarch64_size_dynamic_sections): ... to here. + (elfNN_aarch64_final_link_relocate, + elfNN_aarch64_check_relocs, elfNN_aarch64_reloc_type_class): + Support new relocations. + (map_symbol_type): New member AARCH64_MAP_C64. + (elfNN_aarch64_output_arch_local_syms): Use it. + (aarch64_update_c64_plt_entry): New function. + (elfNN_aarch64_create_small_pltn_entry): Use it. + (elfNN_aarch64_init_small_plt0_entry): Emit C64 PLT when + appropriate. + * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend, + _bfd_aarch64_elf_resolve_relocation): Add new relocations. + * libbfd.h (bfd_reloc_code_real_names): Likewise. + * reloc.c: New relocations BFD_RELOC_MORELLO_TSTBR14, + BFD_RELOC_MORELLO_BRANCH19, BFD_RELOC_MORELLO_JUMP26, + BFD_RELOC_MORELLO_CALL26, BFD_RELOC_MORELLO_JUMP_SLOT and + BFD_RELOC_MORELLO_IRELATIVE. + * bfd-in2.h: Regenerate. + 2020-10-20 Siddhesh Poyarekar * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Emit diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 5f44b187d56..1b0cf5a8e7d 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -5664,6 +5664,26 @@ The lowest two bits must be zero and are not stored in the instruction, giving a 28 bit signed byte offset. */ BFD_RELOC_AARCH64_CALL26, +/* A64C 14 bit pc-relative test bit and branch. +The lowest two bits must be zero and are not stored in the instruction, +giving a 16 bit signed byte offset. */ + BFD_RELOC_MORELLO_TSTBR14, + +/* A64C 19 bit pc-relative conditional branch and compare & branch. +The lowest two bits must be zero and are not stored in the instruction, +giving a 21 bit signed byte offset. */ + BFD_RELOC_MORELLO_BRANCH19, + +/* AArch64 26 bit pc-relative unconditional branch to capability. +The lowest two bits must be zero and are not stored in the instruction, +giving a 28 bit signed byte offset. */ + BFD_RELOC_MORELLO_JUMP26, + +/* AArch64 26 bit pc-relative unconditional branch and link to capability. +The lowest two bits must be zero and are not stored in the instruction, +giving a 28 bit signed byte offset. */ + BFD_RELOC_MORELLO_CALL26, + /* AArch64 16-bit load/store instruction, holding bits 0 to 11 of the address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */ BFD_RELOC_AARCH64_LDST16_LO12, @@ -5950,9 +5970,15 @@ instructions. */ /* Morello Capability global data. */ BFD_RELOC_MORELLO_GLOB_DAT, +/* Morello Jump Slot. */ + BFD_RELOC_MORELLO_JUMP_SLOT, + /* Morello relative relocation for capabilities. */ BFD_RELOC_MORELLO_RELATIVE, +/* C64 support for STT_GNU_IFUNC. */ + BFD_RELOC_MORELLO_IRELATIVE, + /* 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 897dc1c704a..c926dba170b 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -325,6 +325,19 @@ static const bfd_byte elfNN_aarch64_small_plt0_bti_entry[PLT_ENTRY_SIZE] = 0x1f, 0x20, 0x03, 0xd5, /* nop */ }; +/* The C64 PLT0. */ +static const bfd_byte elfNN_c64_small_plt0_entry[PLT_ENTRY_SIZE] = +{ + 0xf0, 0x7b, 0xbf, 0x62, /* stp c16, c30, [csp, #-32]! */ + 0x10, 0x00, 0x80, 0x90, /* adrp c16, (GOT+16) */ + 0x11, 0x0a, 0x40, 0xc2, /* ldr c17, [c16, #PLT_GOT+0x10] */ + 0x10, 0x02, 0x00, 0x02, /* add c16, c16,#PLT_GOT+0x10 */ + 0x20, 0x12, 0xc2, 0xc2, /* br c17 */ + 0x1f, 0x20, 0x03, 0xd5, /* nop */ + 0x1f, 0x20, 0x03, 0xd5, /* nop */ + 0x1f, 0x20, 0x03, 0xd5, /* nop */ +}; + /* Per function entry in a procedure linkage table looks like this if the distance between the PLTGOT and the PLT is < 4GB use these PLT entries. Use BTI versions of the PLTs when enabled. */ @@ -341,6 +354,15 @@ static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] = 0x20, 0x02, 0x1f, 0xd6, /* br x17. */ }; +/* The C64 PLT. */ +static const bfd_byte elfNN_c64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] = +{ + 0x10, 0x00, 0x80, 0x90, /* adrp c16, PLTGOT + offset */ + 0x11, 0x02, 0x40, 0xc2, /* ldr c17, [c16, PLTGOT + offset] */ + 0x10, 0x02, 0x00, 0x02, /* add c16, c16, :lo12:PLTGOT + offset */ + 0x20, 0x12, 0xc2, 0xc2, /* br c17. */ +}; + static const bfd_byte elfNN_aarch64_small_plt_bti_entry[PLT_BTI_SMALL_ENTRY_SIZE] = { @@ -1026,6 +1048,66 @@ static reloc_howto_type elfNN_aarch64_howto_table[] = 0x3ffffff, /* dst_mask */ TRUE), /* pcrel_offset */ + /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */ + HOWTO64 (MORELLO_R (TSTBR14), /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 14, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (TSTBR14), /* name */ + FALSE, /* partial_inplace */ + 0x3fff, /* src_mask */ + 0x3fff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* B.cond: ((S+A-P) >> 2) & 0x7ffff */ + HOWTO64 (MORELLO_R (CONDBR19), /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 19, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (CONDBR19), /* name */ + FALSE, /* partial_inplace */ + 0x7ffff, /* src_mask */ + 0x7ffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* B: ((S+A-P) >> 2) & 0x3ffffff */ + HOWTO64 (MORELLO_R (JUMP26), /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (JUMP26), /* name */ + FALSE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* BL: ((S+A-P) >> 2) & 0x3ffffff */ + HOWTO64 (MORELLO_R (CALL26), /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (CALL26), /* name */ + FALSE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + /* LD/ST16: (S+A) & 0xffe */ HOWTO (AARCH64_R (LDST16_ABS_LO12_NC), /* type */ 1, /* rightshift */ @@ -2257,7 +2339,21 @@ static reloc_howto_type elfNN_aarch64_howto_table[] = 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ - HOWTO64 (MORELLO_R (RELATIVE),/* type */ + HOWTO64 (MORELLO_R (JUMP_SLOT), /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (JUMP_SLOT), /* name */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO64 (MORELLO_R (RELATIVE), /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ @@ -2271,6 +2367,20 @@ static reloc_howto_type elfNN_aarch64_howto_table[] = ALL_ONES, /* dst_mask */ FALSE), /* pcrel_offset */ + HOWTO64 (MORELLO_R (IRELATIVE), /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + MORELLO_R_STR (IRELATIVE), /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + FALSE), /* pcrel_offset */ + EMPTY_HOWTO (0), }; @@ -4951,6 +5061,21 @@ setup_plt_values (struct bfd_link_info *link_info, struct elf_aarch64_link_hash_table *globals; globals = elf_aarch64_hash_table (link_info); + /* Set up plt stubs in case we need C64 PLT. Override BTI/PAC since they're + not compatible. PLT stub sizes are the same as the default ones. */ + if (globals->c64_rel) + { + if (plt_type != PLT_NORMAL) + _bfd_error_handler + (_("ignoring C64-incompatible extensions: %s"), + (plt_type == PLT_BTI_PAC ? "BTI, PAC" + : plt_type == PLT_BTI ? "BTI" : "PAC")); + + globals->plt0_entry = elfNN_c64_small_plt0_entry; + globals->plt_entry = elfNN_c64_small_plt_entry; + return; + } + if (plt_type == PLT_BTI_PAC) { globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry; @@ -5024,7 +5149,6 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd, break; } elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type; - setup_plt_values (link_info, bp_info.plt_type); elf_aarch64_tdata (output_bfd)->secmaps_initialised = FALSE; } @@ -5957,7 +6081,10 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, || bfd_link_executable (info)) { /* This symbol is resolved locally. */ - outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)); + outrel.r_info = (elf_aarch64_hash_entry (h)->got_type + == GOT_CAP + ? 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); @@ -5979,6 +6106,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, return bfd_reloc_ok; } /* FALLTHROUGH */ + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, @@ -6192,6 +6321,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, value += signed_addend; break; + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: { @@ -6291,6 +6422,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, value |= 1; break; + case BFD_RELOC_MORELLO_BRANCH19: + case BFD_RELOC_MORELLO_TSTBR14: case BFD_RELOC_AARCH64_BRANCH19: case BFD_RELOC_AARCH64_TSTBR14: if (h && h->root.type == bfd_link_hash_undefined) @@ -8206,6 +8339,14 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, default: break; + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: + /* For dynamic symbols record caller information so that we can + decide what kind of PLT stubs to emit. */ + if (h != NULL) + elf_aarch64_hash_entry (h)->got_type = GOT_CAP; + /* Fall through. */ + case BFD_RELOC_AARCH64_ADD_LO12: case BFD_RELOC_AARCH64_ADR_GOT_PAGE: case BFD_RELOC_MORELLO_ADR_GOT_PAGE: @@ -8519,6 +8660,13 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, break; } + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: + htab->c64_rel = 1; + if (h != NULL) + elf_aarch64_hash_entry (h)->got_type = GOT_CAP; + + /* Fall through. */ case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: if (h == NULL) @@ -8698,10 +8846,13 @@ elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSE switch ((int) ELFNN_R_TYPE (rela->r_info)) { case AARCH64_R (IRELATIVE): + case MORELLO_R (IRELATIVE): return reloc_class_ifunc; case AARCH64_R (RELATIVE): + case MORELLO_R (RELATIVE): return reloc_class_relative; case AARCH64_R (JUMP_SLOT): + case MORELLO_R (JUMP_SLOT): return reloc_class_plt; case AARCH64_R (COPY): return reloc_class_copy; @@ -8752,7 +8903,8 @@ typedef struct enum map_symbol_type { AARCH64_MAP_INSN, - AARCH64_MAP_DATA + AARCH64_MAP_DATA, + AARCH64_MAP_C64, }; @@ -8914,7 +9066,8 @@ elfNN_aarch64_output_arch_local_syms (bfd *output_bfd, (output_bfd, htab->root.splt->output_section); osi.sec = htab->root.splt; - elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0); + elfNN_aarch64_output_map_sym (&osi, (htab->c64_rel ? AARCH64_MAP_C64 + : AARCH64_MAP_INSN), 0); return TRUE; @@ -9355,6 +9508,8 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd, aarch64_elf_init_got_section (output_bfd, info); + setup_plt_values (info, elf_aarch64_tdata (output_bfd)->plt_type); + /* Set up .got offsets for local syms, and space for local dynamic relocs. */ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) @@ -9626,6 +9781,26 @@ elf_aarch64_update_plt_entry (bfd *output_bfd, (void) _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value); } +static void +aarch64_update_c64_plt_entry (bfd *output_bfd, bfd_byte *plt_entry, + bfd_vma plt_base, bfd_vma plt_got_ent) +{ + /* Fill in the top 20 bits for this: ADRP c16, PLT_GOT + n * 16. + ADRP: ((PG(S+A)-PG(P)) >> 12) & 0xfffff */ + elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_MORELLO_ADR_HI20_PCREL, + plt_entry, + PG (plt_got_ent) - PG (plt_base)); + + elf_aarch64_update_plt_entry (output_bfd, + BFD_RELOC_AARCH64_LDST128_LO12, + plt_entry + 4, + PG_OFFSET (plt_got_ent)); + + elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12, + plt_entry + 8, + PG_OFFSET (plt_got_ent)); +} + static void elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h, struct elf_aarch64_link_hash_table @@ -9687,33 +9862,42 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h, /* Copy in the boiler-plate for the PLTn entry. */ memcpy (plt_entry, htab->plt_entry, htab->plt_entry_size); - /* First instruction in BTI enabled PLT stub is a BTI - instruction so skip it. */ - if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI - && elf_elfheader (output_bfd)->e_type == ET_EXEC) - plt_entry = plt_entry + 4; + if (htab->c64_rel) + aarch64_update_c64_plt_entry (output_bfd, plt_entry, plt_entry_address, + gotplt_entry_address); + else + { - /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8. - ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */ - elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL, - plt_entry, - PG (gotplt_entry_address) - - PG (plt_entry_address)); + /* First instruction in BTI enabled PLT stub is a BTI + instruction so skip it. */ + if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI + && elf_elfheader (output_bfd)->e_type == ET_EXEC) + plt_entry = plt_entry + 4; - /* Fill in the lo12 bits for the load from the pltgot. */ - elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12, - plt_entry + 4, - PG_OFFSET (gotplt_entry_address)); + /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8. + ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */ + elf_aarch64_update_plt_entry (output_bfd, + BFD_RELOC_AARCH64_ADR_HI21_PCREL, + plt_entry, + PG (gotplt_entry_address) - + PG (plt_entry_address)); - /* Fill in the lo12 bits for the add from the pltgot entry. */ - elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12, - plt_entry + 8, - PG_OFFSET (gotplt_entry_address)); + /* Fill in the lo12 bits for the load from the pltgot. */ + elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12, + plt_entry + 4, + PG_OFFSET (gotplt_entry_address)); - /* All the GOTPLT Entries are essentially initialized to PLT0. */ - bfd_put_NN (output_bfd, - plt->output_section->vma + plt->output_offset, - gotplt->contents + got_offset); + /* Fill in the lo12 bits for the add from the pltgot entry. */ + elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12, + plt_entry + 8, + PG_OFFSET (gotplt_entry_address)); + } + + /* All the GOTPLT Entries are essentially initialized to PLT0. Set LSB if + the PLT is C64. */ + bfd_vma plt0 = ((plt->output_section->vma + plt->output_offset) + | htab->c64_rel); + bfd_put_NN (output_bfd, plt0, gotplt->contents + got_offset); rela.r_offset = gotplt_entry_address; @@ -9725,7 +9909,9 @@ 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 = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE)); + rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP + ? 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); @@ -9733,7 +9919,9 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h, else { /* Fill in the entry in the .rela.plt section. */ - rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT)); + rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP + ? ELFNN_R_INFO (h->dynindx, MORELLO_R (JUMP_SLOT)) + : ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT))); rela.r_addend = 0; } @@ -10043,9 +10231,17 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED, plt_base = htab->root.splt->output_section->vma + htab->root.splt->output_offset; + bfd_byte *plt0_entry = htab->root.splt->contents; + + if (htab->c64_rel) + { + aarch64_update_c64_plt_entry (output_bfd, plt0_entry + 4, + plt_base + 4, plt_got_2nd_ent); + return; + } + /* First instruction in BTI enabled PLT stub is a BTI instruction so skip it. */ - bfd_byte *plt0_entry = htab->root.splt->contents; if (elf_aarch64_tdata (output_bfd)->plt_type & PLT_BTI) plt0_entry = plt0_entry + 4; @@ -10389,7 +10585,6 @@ elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info *info) elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop; elf_aarch64_tdata (info->output_bfd)->plt_type |= (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ? PLT_BTI : 0; - setup_plt_values (info, elf_aarch64_tdata (info->output_bfd)->plt_type); return pbfd; } diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c index cc58c174196..3163c998315 100644 --- a/bfd/elfxx-aarch64.c +++ b/bfd/elfxx-aarch64.c @@ -230,16 +230,20 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, switch (r_type) { + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: contents = reencode_branch_ofs_26 (contents, addend); break; case BFD_RELOC_AARCH64_BRANCH19: + case BFD_RELOC_MORELLO_BRANCH19: contents = reencode_cond_branch_ofs_19 (contents, addend); break; case BFD_RELOC_AARCH64_TSTBR14: + case BFD_RELOC_MORELLO_TSTBR14: contents = reencode_tst_branch_ofs_14 (contents, addend); break; @@ -451,6 +455,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd, case BFD_RELOC_AARCH64_64_PCREL: case BFD_RELOC_AARCH64_ADR_LO21_PCREL: case BFD_RELOC_AARCH64_BRANCH19: + case BFD_RELOC_MORELLO_BRANCH19: case BFD_RELOC_AARCH64_LD_LO19_PCREL: case BFD_RELOC_AARCH64_MOVW_PREL_G0: case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC: @@ -465,11 +470,14 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd, case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: case BFD_RELOC_AARCH64_TSTBR14: + case BFD_RELOC_MORELLO_TSTBR14: if (weak_undef_p) value = place; value = value + addend - place; break; + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: value = value + addend - place; diff --git a/bfd/libbfd.h b/bfd/libbfd.h index c106292175d..1180071c119 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -3027,6 +3027,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_AARCH64_BRANCH19", "BFD_RELOC_AARCH64_JUMP26", "BFD_RELOC_AARCH64_CALL26", + "BFD_RELOC_MORELLO_TSTBR14", + "BFD_RELOC_MORELLO_BRANCH19", + "BFD_RELOC_MORELLO_JUMP26", + "BFD_RELOC_MORELLO_CALL26", "BFD_RELOC_AARCH64_LDST16_LO12", "BFD_RELOC_AARCH64_LDST32_LO12", "BFD_RELOC_AARCH64_LDST64_LO12", @@ -3110,7 +3114,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_AARCH64_IRELATIVE", "BFD_RELOC_MORELLO_CAPINIT", "BFD_RELOC_MORELLO_GLOB_DAT", + "BFD_RELOC_MORELLO_JUMP_SLOT", "BFD_RELOC_MORELLO_RELATIVE", + "BFD_RELOC_MORELLO_IRELATIVE", "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 a5f64c177ad..fc9e9bef720 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -7174,6 +7174,30 @@ ENUMDOC AArch64 26 bit pc-relative unconditional branch and link. The lowest two bits must be zero and are not stored in the instruction, giving a 28 bit signed byte offset. +ENUM + BFD_RELOC_MORELLO_TSTBR14 +ENUMDOC + A64C 14 bit pc-relative test bit and branch. + The lowest two bits must be zero and are not stored in the instruction, + giving a 16 bit signed byte offset. +ENUM + BFD_RELOC_MORELLO_BRANCH19 +ENUMDOC + A64C 19 bit pc-relative conditional branch and compare & branch. + The lowest two bits must be zero and are not stored in the instruction, + giving a 21 bit signed byte offset. +ENUM + BFD_RELOC_MORELLO_JUMP26 +ENUMDOC + AArch64 26 bit pc-relative unconditional branch to capability. + The lowest two bits must be zero and are not stored in the instruction, + giving a 28 bit signed byte offset. +ENUM + BFD_RELOC_MORELLO_CALL26 +ENUMDOC + AArch64 26 bit pc-relative unconditional branch and link to capability. + The lowest two bits must be zero and are not stored in the instruction, + giving a 28 bit signed byte offset. ENUM BFD_RELOC_AARCH64_LDST16_LO12 ENUMDOC @@ -7543,10 +7567,18 @@ ENUM BFD_RELOC_MORELLO_GLOB_DAT ENUMDOC Morello Capability global data. +ENUM + BFD_RELOC_MORELLO_JUMP_SLOT +ENUMDOC + Morello Jump Slot. ENUM BFD_RELOC_MORELLO_RELATIVE ENUMDOC Morello relative relocation for capabilities. +ENUM + BFD_RELOC_MORELLO_IRELATIVE +ENUMDOC + C64 support for STT_GNU_IFUNC. ENUM BFD_RELOC_AARCH64_RELOC_END ENUMDOC diff --git a/gas/ChangeLog b/gas/ChangeLog index d0ae46139ca..dd8fd72b837 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2020-10-20 Siddhesh Poyarekar + + * config/tc-aarch64.c (parse_operands): Choose C64 branch + relocations when appropriate. + (md_apply_fix, aarch64_force_relocation, + aarch64_fix_adjustable): Support C64 branch relocations. + 2020-10-20 Siddhesh Poyarekar * config/tc-aarch64.c (parse_operands): Emit C64 relocations diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 715ac2d2e9b..4e63ce1594c 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -6623,19 +6623,29 @@ bad_adrdp: case condbranch: /* e.g. CBZ or B.COND */ gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19); - inst.reloc.type = BFD_RELOC_AARCH64_BRANCH19; + inst.reloc.type = (c64 ? BFD_RELOC_MORELLO_BRANCH19 + : BFD_RELOC_AARCH64_BRANCH19); break; case testbranch: /* e.g. TBZ */ gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL14); - inst.reloc.type = BFD_RELOC_AARCH64_TSTBR14; + inst.reloc.type = (c64 ? BFD_RELOC_MORELLO_TSTBR14 + : BFD_RELOC_AARCH64_TSTBR14); break; case branch_imm: /* e.g. B or BL */ - gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL26); - inst.reloc.type = - (opcode->op == OP_BL) ? BFD_RELOC_AARCH64_CALL26 - : BFD_RELOC_AARCH64_JUMP26; + { + enum aarch64_opnd jump, call; + + gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL26); + + jump = (c64 ? BFD_RELOC_MORELLO_JUMP26 + : BFD_RELOC_AARCH64_JUMP26); + call = (c64 ? BFD_RELOC_MORELLO_CALL26 + : BFD_RELOC_AARCH64_CALL26); + + inst.reloc.type = opcode->op == OP_BL ? call : jump; + } break; case loadlit: gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL19 @@ -8516,6 +8526,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) break; case BFD_RELOC_AARCH64_BRANCH19: + case BFD_RELOC_MORELLO_BRANCH19: if (fixP->fx_done || !seg->use_rela_p) { if (value & 3) @@ -8530,6 +8541,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) } break; + case BFD_RELOC_MORELLO_TSTBR14: case BFD_RELOC_AARCH64_TSTBR14: if (fixP->fx_done || !seg->use_rela_p) { @@ -8545,6 +8557,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) } break; + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: if (fixP->fx_done || !seg->use_rela_p) @@ -8997,8 +9011,12 @@ aarch64_force_relocation (struct fix *fixp) return 1; case BFD_RELOC_AARCH64_ADR_LO21_PCREL: + case BFD_RELOC_MORELLO_BRANCH19: + case BFD_RELOC_MORELLO_TSTBR14: case BFD_RELOC_AARCH64_BRANCH19: case BFD_RELOC_AARCH64_TSTBR14: + case BFD_RELOC_MORELLO_CALL26: + case BFD_RELOC_MORELLO_JUMP26: case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: gas_assert (fixp->fx_addsy != NULL); @@ -9175,6 +9193,10 @@ aarch64_fix_adjustable (struct fix *fixP) case BFD_RELOC_AARCH64_TSTBR14: case BFD_RELOC_AARCH64_JUMP26: case BFD_RELOC_AARCH64_CALL26: + case BFD_RELOC_MORELLO_BRANCH19: + case BFD_RELOC_MORELLO_TSTBR14: + case BFD_RELOC_MORELLO_JUMP26: + case BFD_RELOC_MORELLO_CALL26: if (fixP->tc_fix_data.c64 || AARCH64_IS_C64 (fixP->fx_addsy)) return FALSE; break; diff --git a/include/ChangeLog b/include/ChangeLog index d50893b0e2b..232c640915a 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2020-10-20 Siddhesh Poyarekar + + * elf/aarch64.h: New relocations R_MORELLO_TSTBR14, + R_MORELLO_CONDBR19, R_MORELLO_JUMP26, R_MORELLO_CALL26, + R_MORELLO_JUMP_SLOT and R_MORELLO_IRELATIVE. + 2020-10-20 Siddhesh Poyarekar * elf/aarch64.h: New relocations R_MORELLO_LD128_GOT_LO12_NC diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h index 3aa27712aa9..ff91177d4e3 100644 --- a/include/elf/aarch64.h +++ b/include/elf/aarch64.h @@ -444,6 +444,18 @@ RELOC_NUMBER (R_AARCH64_IRELATIVE, 1032) /* Morello Relocations. */ +/* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff. */ +RELOC_NUMBER (R_MORELLO_TSTBR14, 57344) + +/* B.cond: ((S+A-P) >> 2) & 0x7ffff. */ +RELOC_NUMBER (R_MORELLO_CONDBR19, 57345) + +/* B: ((S+A-P) >> 2) & 0x3ffffff. */ +RELOC_NUMBER (R_MORELLO_JUMP26, 57346) + +/* BL: ((S+A-P) >> 2) & 0x3ffffff. */ +RELOC_NUMBER (R_MORELLO_CALL26, 57347) + /* A64C LD-lit: ((S+A-P) >> 4) & 0x1ffff */ RELOC_NUMBER (R_MORELLO_LD_PREL_LO17, 57348) @@ -461,7 +473,9 @@ RELOC_NUMBER (R_MORELLO_LD128_GOT_LO12_NC, 57352) RELOC_NUMBER (R_MORELLO_CAPINIT, 59392) 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) END_RELOC_NUMBERS (R_AARCH64_end) diff --git a/ld/ChangeLog b/ld/ChangeLog index 13e55a71d51..269b09d2d29 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2020-10-20 Siddhesh Poyarekar + + * testsuite/ld-aarch64/aarch64-elf.exp: Add new tests. + * testsuite/ld-aarch64/c64-ifunc-2-local.d: New file. + * testsuite/ld-aarch64/c64-ifunc-2.d: New file. + * testsuite/ld-aarch64/c64-ifunc-3a.d: New file. + * testsuite/ld-aarch64/c64-ifunc-3b.d: New file. + * testsuite/ld-aarch64/c64-ifunc-4.d: New file. + * testsuite/ld-aarch64/c64-ifunc-4a.d: New file. + * testsuite/ld-aarch64/ifunc-2-local.s: Support capabilities. + * testsuite/ld-aarch64/ifunc-2.s: Likewise. + 2020-10-20 Siddhesh Poyarekar * testsuite/ld-aarch64/emit-relocs-morello-2-a64c.d: New test. diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 7604061506e..1d561795055 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -382,6 +382,13 @@ run_dump_test_lp64 "ifunc-20" run_dump_test_lp64 "ifunc-21" run_dump_test_lp64 "ifunc-22" +run_dump_test_lp64 "c64-ifunc-2" +run_dump_test_lp64 "c64-ifunc-2-local" +run_dump_test_lp64 "c64-ifunc-3a" +run_dump_test_lp64 "c64-ifunc-3b" +run_dump_test_lp64 "c64-ifunc-4" +run_dump_test_lp64 "c64-ifunc-4a" + run_dump_test "relasz" run_dump_test_lp64 "relocs-1027-symbolic-func" diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d b/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d new file mode 100644 index 00000000000..8c7fe038cd5 --- /dev/null +++ b/ld/testsuite/ld-aarch64/c64-ifunc-2-local.d @@ -0,0 +1,13 @@ +#target: [check_shared_lib_support] +#as: -march=morello+c64 --defsym C64MODE=1 +#ld: -shared --hash-style=sysv +#objdump: -dw +#source: ifunc-2-local.s + +#... +0+(110|180|1a0) <__GI_foo>: +#... +[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0x(110|180|1a0)@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) +#pass diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-2.d b/ld/testsuite/ld-aarch64/c64-ifunc-2.d new file mode 100644 index 00000000000..64a8b808f91 --- /dev/null +++ b/ld/testsuite/ld-aarch64/c64-ifunc-2.d @@ -0,0 +1,13 @@ +#target: [check_shared_lib_support] +#as: -march=morello+c64 --defsym C64MODE=1 +#ld: -shared --hash-style=sysv +#objdump: -dw +#source: ifunc-2.s + +#... +0+(130|1a0|1c8) : +#... +[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0x(130|1a0|1c8)@plt> +[ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+c0, 0 <.*> +[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+c0, c0, #0x(120|190|1b8) +#pass diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-3a.d b/ld/testsuite/ld-aarch64/c64-ifunc-3a.d new file mode 100644 index 00000000000..d680cde1c76 --- /dev/null +++ b/ld/testsuite/ld-aarch64/c64-ifunc-3a.d @@ -0,0 +1,11 @@ +#source: ifunc-3.s +#target: [check_shared_lib_support] +#as: -march=morello+c64 +#ld: -shared --hash-style=sysv +#objdump: -dw + +#... +0+(150|1d0|1e8) <__GI_foo>: +#... +[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+0x(150|1d0|1e8)@plt> +#pass diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-3b.d b/ld/testsuite/ld-aarch64/c64-ifunc-3b.d new file mode 100644 index 00000000000..99929ede48c --- /dev/null +++ b/ld/testsuite/ld-aarch64/c64-ifunc-3b.d @@ -0,0 +1,9 @@ +#source: ifunc-3.s +#target: [check_shared_lib_support] +#as: -march=morello+c64 +#ld: -shared +#readelf: -r --wide + +#... +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_MORELLO_IRELATIVE[ ]*[0-9a-f]* +#pass diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-4.d b/ld/testsuite/ld-aarch64/c64-ifunc-4.d new file mode 100644 index 00000000000..ec9411a154a --- /dev/null +++ b/ld/testsuite/ld-aarch64/c64-ifunc-4.d @@ -0,0 +1,9 @@ +#source: ifunc-4.s +#as: -march=morello+c64 +#ld: +#readelf: -r --wide +#target: aarch64*-*-* + +#... +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_MORELLO_IRELATIVE[ ]*[0-9a-f]* +#pass diff --git a/ld/testsuite/ld-aarch64/c64-ifunc-4a.d b/ld/testsuite/ld-aarch64/c64-ifunc-4a.d new file mode 100644 index 00000000000..3c240e37e21 --- /dev/null +++ b/ld/testsuite/ld-aarch64/c64-ifunc-4a.d @@ -0,0 +1,9 @@ +#as: -march=morello+c64 +#ld: -s +#readelf: -r --wide +#target: aarch64*-*-* +#source: ifunc-4.s + +#... +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_MORELLO_IRELATIVE[ ]*[0-9a-f]* +#pass diff --git a/ld/testsuite/ld-aarch64/ifunc-2-local.s b/ld/testsuite/ld-aarch64/ifunc-2-local.s index 632c31f4560..5354ad48507 100644 --- a/ld/testsuite/ld-aarch64/ifunc-2-local.s +++ b/ld/testsuite/ld-aarch64/ifunc-2-local.s @@ -1,3 +1,9 @@ + .ifdef C64MODE + REG .req c0 + .else + REG .req x0 + .endif + .type foo, %gnu_indirect_function .set __GI_foo, foo .text @@ -9,7 +15,7 @@ foo: .type bar, @function bar: bl __GI_foo - adrp x0, __GI_foo - add x0, x0, :lo12:__GI_foo + adrp REG, __GI_foo + add REG, REG, :lo12:__GI_foo ret .size bar, .-bar diff --git a/ld/testsuite/ld-aarch64/ifunc-2.s b/ld/testsuite/ld-aarch64/ifunc-2.s index da350df6315..bd65b2305c9 100644 --- a/ld/testsuite/ld-aarch64/ifunc-2.s +++ b/ld/testsuite/ld-aarch64/ifunc-2.s @@ -1,3 +1,9 @@ + .ifdef C64MODE + REG .req c0 + .else + REG .req x0 + .endif + .type foo, %gnu_indirect_function .global __GI_foo .hidden __GI_foo @@ -12,7 +18,7 @@ foo: .type bar, @function bar: bl __GI_foo - adrp x0, __GI_foo - add x0, x0, :lo12:__GI_foo + adrp REG, __GI_foo + add REG, REG, :lo12:__GI_foo ret .size bar, .-bar diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 49a7786b3d5..58df5c059d1 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,7 @@ +2020-10-20 Siddhesh Poyarekar + + * aarch64-dis.c (get_sym_code_type): Fix C64 PLT disassembly. + 2020-10-20 Siddhesh Poyarekar * aarch64-opc.c (operand_general_constraint_met_p): Expect diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 062458a0189..24dea397e83 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -3547,8 +3547,9 @@ get_sym_code_type (struct disassemble_info *info, int n, type = ELF_ST_TYPE (es->internal_elf_sym.st_info); - /* ST_TARGET_INTERNAL is set for C64. */ - if (type == STT_FUNC) + /* ST_TARGET_INTERNAL is set for C64. For PLT stubs, depend only on the + mapping symbol that the linker generated for it. */ + if (type == STT_FUNC && !(es->symbol.flags & BSF_SYNTHETIC)) { *map_type = (es->internal_elf_sym.st_target_internal & ST_BRANCH_TO_C64 ? MAP_C64 : MAP_INSN);