diff options
-rw-r--r-- | bfd/ChangeLog | 37 | ||||
-rw-r--r-- | bfd/bfd-in.h | 38 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 38 | ||||
-rw-r--r-- | bfd/elfnn-aarch64.c | 257 | ||||
-rw-r--r-- | binutils/ChangeLog | 8 | ||||
-rw-r--r-- | binutils/readelf.c | 31 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/elf/aarch64.h | 2 | ||||
-rw-r--r-- | ld/ChangeLog | 19 | ||||
-rw-r--r-- | ld/NEWS | 4 | ||||
-rw-r--r-- | ld/emultempl/aarch64elf.em | 17 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/aarch64-elf.exp | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-1.d | 32 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-1.s | 21 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-2.d | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-2.s | 21 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-3.d | 34 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-4.d | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-5.d | 28 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-6.d | 15 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-7.d | 15 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt-so.s | 41 | ||||
-rw-r--r-- | ld/testsuite/ld-aarch64/bti-plt.ld | 14 |
23 files changed, 687 insertions, 21 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3e5c7c2..6e7748e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,4 +1,41 @@ 2019-03-13 Sudakshina Das <sudi.das@arm.com> + Szabolcs Nagy <szabolcs.nagy@arm.com> + + * bfd-in.h (aarch64_plt_type, aarch64_enable_bti_type): New. + (aarch64_bti_pac_info): New. + (bfd_elf64_aarch64_set_options): Add aarch64_bti_pac_info argument. + (bfd_elf32_aarch64_set_options): Likewise. + * bfd-in2.h: Regenerate + * elfnn-aarch64.c (PLT_BTI_ENTRY_SIZE): New. + (PLT_BTI_SMALL_ENTRY_SIZE, PLT_BTI_TLSDESC_ENTRY_SIZE): New. + (elfNN_aarch64_small_plt0_bti_entry): New. + (elfNN_aarch64_small_plt_bti_entry): New. + (elfNN_aarch64_tlsdesc_small_plt_bti_entry): New. + (elf_aarch64_obj_tdata): Add no_bti_warn and plt_type fields. + (elf_aarch64_link_hash_table): Add plt0_entry, plt_entry and + tlsdesc_plt_entry_size fields. + (elfNN_aarch64_link_hash_table_create): Initialise the new fields. + (setup_plt_values): New helper function. + (bfd_elfNN_aarch64_set_options): Use new bp_info to set plt sizes and + bti enable type. + (elfNN_aarch64_allocate_dynrelocs): Use new size members instead of + fixed macros. + (elfNN_aarch64_size_dynamic_sections): Likewise and add checks. + (elfNN_aarch64_create_small_pltn_entry): Use new generic pointers + to plt stubs instead of fixed ones and update filling them according + to the need for bti. + (elfNN_aarch64_init_small_plt0_entry): Likewise. + (elfNN_aarch64_finish_dynamic_sections): Likewise. + (get_plt_type, elfNN_aarch64_get_synthetic_symtab): New. + (elfNN_aarch64_plt_sym_val): Update size accordingly. + (elfNN_aarch64_link_setup_gnu_properties): Set up plts if BTI GNU NOTE + is set. + (bfd_elfNN_get_synthetic_symtab): Define. + (elfNN_aarch64_merge_gnu_properties): Give out warning with --force-bti + and mising BTI NOTE SECTION. + + +2019-03-13 Sudakshina Das <sudi.das@arm.com> * elf-properties.c (_bfd_elf_link_setup_gnu_properties): Exclude linker created inputs from merge. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index e7c2eaa..b753a9e 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -995,11 +995,45 @@ extern void bfd_elf64_aarch64_init_maps extern void bfd_elf32_aarch64_init_maps (bfd *); +/* Types of PLTs based on the level of security. This would be a + bit-mask to denote which of the combinations of security features + are enabled: + - No security feature PLTs + - PLTs with BTI instruction + - PLTs with PAC instruction +*/ +typedef enum +{ + PLT_NORMAL = 0x0, /* Normal plts. */ + PLT_BTI = 0x1, /* plts with bti. */ + PLT_PAC = 0x2, /* plts with pointer authentication. */ + PLT_BTI_PAC = PLT_BTI | PLT_PAC +} aarch64_plt_type; + +/* To indicate if BTI is enabled with/without warning. */ +typedef enum +{ + BTI_NONE = 0, /* BTI is not enabled. */ + BTI_WARN = 1, /* BTI is enabled with --force-bti. */ +} aarch64_enable_bti_type; + +/* A structure to encompass all information coming from BTI or PAC + related command line options. This involves the "PLT_TYPE" to determine + which version of PLTs to pick and "BTI_TYPE" to determine if + BTI should be turned on with any warnings. */ +typedef struct +{ + aarch64_plt_type plt_type; + aarch64_enable_bti_type bti_type; +} aarch64_bti_pac_info; + extern void bfd_elf64_aarch64_set_options - (bfd *, struct bfd_link_info *, int, int, int, int, int, int); + (bfd *, struct bfd_link_info *, int, int, int, int, int, int, + aarch64_bti_pac_info); extern void bfd_elf32_aarch64_set_options - (bfd *, struct bfd_link_info *, int, int, int, int, int, int); + (bfd *, struct bfd_link_info *, int, int, int, int, int, int, + aarch64_bti_pac_info); /* ELF AArch64 mapping symbol support. */ #define BFD_AARCH64_SPECIAL_SYM_TYPE_MAP (1 << 0) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index e25da50..33a2940 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1002,11 +1002,45 @@ extern void bfd_elf64_aarch64_init_maps extern void bfd_elf32_aarch64_init_maps (bfd *); +/* Types of PLTs based on the level of security. This would be a + bit-mask to denote which of the combinations of security features + are enabled: + - No security feature PLTs + - PLTs with BTI instruction + - PLTs with PAC instruction +*/ +typedef enum +{ + PLT_NORMAL = 0x0, /* Normal plts. */ + PLT_BTI = 0x1, /* plts with bti. */ + PLT_PAC = 0x2, /* plts with pointer authentication. */ + PLT_BTI_PAC = PLT_BTI | PLT_PAC +} aarch64_plt_type; + +/* To indicate if BTI is enabled with/without warning. */ +typedef enum +{ + BTI_NONE = 0, /* BTI is not enabled. */ + BTI_WARN = 1, /* BTI is enabled with --force-bti. */ +} aarch64_enable_bti_type; + +/* A structure to encompass all information coming from BTI or PAC + related command line options. This involves the "PLT_TYPE" to determine + which version of PLTs to pick and "BTI_TYPE" to determine if + BTI should be turned on with any warnings. */ +typedef struct +{ + aarch64_plt_type plt_type; + aarch64_enable_bti_type bti_type; +} aarch64_bti_pac_info; + extern void bfd_elf64_aarch64_set_options - (bfd *, struct bfd_link_info *, int, int, int, int, int, int); + (bfd *, struct bfd_link_info *, int, int, int, int, int, int, + aarch64_bti_pac_info); extern void bfd_elf32_aarch64_set_options - (bfd *, struct bfd_link_info *, int, int, int, int, int, int); + (bfd *, struct bfd_link_info *, int, int, int, int, int, int, + aarch64_bti_pac_info); /* ELF AArch64 mapping symbol support. */ #define BFD_AARCH64_SPECIAL_SYM_TYPE_MAP (1 << 0) diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 5b8cc4c..69b8f83 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -267,6 +267,10 @@ #define PLT_ENTRY_SIZE (32) #define PLT_SMALL_ENTRY_SIZE (16) #define PLT_TLSDESC_ENTRY_SIZE (32) +/* PLT sizes with BTI insn. */ +#define PLT_BTI_ENTRY_SIZE (36) +#define PLT_BTI_SMALL_ENTRY_SIZE (20) +#define PLT_BTI_TLSDESC_ENTRY_SIZE (36) /* Encoding of the nop instruction. */ #define INSN_NOP 0xd503201f @@ -297,9 +301,27 @@ static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] = 0x1f, 0x20, 0x03, 0xd5, /* nop */ }; +static const bfd_byte elfNN_aarch64_small_plt0_bti_entry[PLT_BTI_ENTRY_SIZE] = +{ + 0x5f, 0x24, 0x03, 0xd5, /* bti c. */ + 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */ + 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */ +#if ARCH_SIZE == 64 + 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */ + 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */ +#else + 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */ + 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */ +#endif + 0x20, 0x02, 0x1f, 0xd6, /* br x17 */ + 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. */ + these PLT entries. Use BTI versions of the PLTs when enabled. */ static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] = { 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */ @@ -314,6 +336,21 @@ static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] = }; static const bfd_byte +elfNN_aarch64_small_plt_bti_entry[PLT_BTI_SMALL_ENTRY_SIZE] = +{ + 0x5f, 0x24, 0x03, 0xd5, /* bti c. */ + 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */ +#if ARCH_SIZE == 64 + 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */ + 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */ +#else + 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */ + 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */ +#endif + 0x20, 0x02, 0x1f, 0xd6, /* br x17. */ +}; + +static const bfd_byte elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] = { 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */ @@ -331,6 +368,25 @@ elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] = 0x1f, 0x20, 0x03, 0xd5, /* nop */ }; +static const bfd_byte +elfNN_aarch64_tlsdesc_small_plt_bti_entry[PLT_BTI_TLSDESC_ENTRY_SIZE] = +{ + 0x5f, 0x24, 0x03, 0xd5, /* bti c. */ + 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */ + 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */ + 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */ +#if ARCH_SIZE == 64 + 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */ + 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */ +#else + 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */ + 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */ +#endif + 0x40, 0x00, 0x1f, 0xd6, /* br x2 */ + 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 @@ -2438,6 +2494,13 @@ struct elf_aarch64_obj_tdata /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties. */ uint32_t gnu_and_prop; + + /* Zero to warn when linking objects with incompatible + GNU_PROPERTY_AARCH64_FEATURE_1_BTI. */ + int no_bti_warn; + + /* PLT type based on security. */ + aarch64_plt_type plt_type; }; #define elf_aarch64_tdata(bfd) \ @@ -2543,9 +2606,15 @@ struct elf_aarch64_link_hash_table /* The number of bytes in the initial entry in the PLT. */ bfd_size_type plt_header_size; - /* The number of bytes in the subsequent PLT etries. */ + /* The bytes of the initial PLT entry. */ + const bfd_byte *plt0_entry; + + /* The number of bytes in the subsequent PLT entries. */ bfd_size_type plt_entry_size; + /* The bytes of the subsequent PLT entry. */ + const bfd_byte *plt_entry; + /* Small local sym cache. */ struct sym_cache sym_cache; @@ -2588,6 +2657,9 @@ struct elf_aarch64_link_hash_table yet. */ bfd_vma tlsdesc_plt; + /* The number of bytes in the PLT enty for the TLS descriptor. */ + bfd_size_type tlsdesc_plt_entry_size; + /* The GOT offset for the lazy trampoline. Communicated to the loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1 indicates an offset is not allocated. */ @@ -2831,7 +2903,10 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd) } ret->plt_header_size = PLT_ENTRY_SIZE; + ret->plt0_entry = elfNN_aarch64_small_plt0_entry; ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE; + ret->plt_entry = elfNN_aarch64_small_plt_entry; + ret->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE; ret->obfd = abfd; ret->dt_tlsdesc_got = (bfd_vma) - 1; @@ -4599,6 +4674,28 @@ bfd_elfNN_aarch64_init_maps (bfd *abfd) } } +static void +setup_plt_values (struct bfd_link_info *link_info, + aarch64_plt_type plt_type) +{ + struct elf_aarch64_link_hash_table *globals; + globals = elf_aarch64_hash_table (link_info); + + if (plt_type == PLT_BTI) + { + globals->plt_header_size = PLT_BTI_ENTRY_SIZE; + globals->plt0_entry = elfNN_aarch64_small_plt0_bti_entry; + globals->tlsdesc_plt_entry_size = PLT_BTI_TLSDESC_ENTRY_SIZE; + + /* Only in ET_EXEC we need PLTn with BTI. */ + if (bfd_link_pde (link_info)) + { + globals->plt_entry_size = PLT_BTI_SMALL_ENTRY_SIZE; + globals->plt_entry = elfNN_aarch64_small_plt_bti_entry; + } + } +} + /* Set option values needed during linking. */ void bfd_elfNN_aarch64_set_options (struct bfd *output_bfd, @@ -4607,7 +4704,8 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd, int no_wchar_warn, int pic_veneer, int fix_erratum_835769, int fix_erratum_843419, - int no_apply_dynamic_relocs) + int no_apply_dynamic_relocs, + aarch64_bti_pac_info bp_info) { struct elf_aarch64_link_hash_table *globals; @@ -4621,6 +4719,20 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd, BFD_ASSERT (is_aarch64_elf (output_bfd)); elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn; elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn; + + switch (bp_info.bti_type) + { + case BTI_WARN: + elf_aarch64_tdata (output_bfd)->no_bti_warn = 0; + elf_aarch64_tdata (output_bfd)->gnu_and_prop + |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; + break; + + default: + break; + } + elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type; + setup_plt_values (link_info, bp_info.plt_type); } static bfd_vma @@ -8349,7 +8461,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Make room for this entry. For now we only create the small model PLT entries. We later need to find a way of relaxing into these from the large model PLT entries. */ - s->size += PLT_SMALL_ENTRY_SIZE; + s->size += htab->plt_entry_size; /* We also need to make an entry in the .got.plt section, which will be placed in the .got section by the linker script. */ @@ -8849,10 +8961,10 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (htab->tlsdesc_plt) { if (htab->root.splt->size == 0) - htab->root.splt->size += PLT_ENTRY_SIZE; + htab->root.splt->size += htab->plt_header_size; htab->tlsdesc_plt = htab->root.splt->size; - htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE; + htab->root.splt->size += htab->tlsdesc_plt_entry_size; /* If we're not using lazy TLS relocations, don't generate the GOT entry required. */ @@ -8964,6 +9076,10 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) return FALSE; + + if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI) + && !add_dynamic_entry (DT_AARCH64_BTI_PLT, 0)) + return FALSE; } if (relocs) @@ -9060,7 +9176,13 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h, gotplt->output_offset + got_offset; /* Copy in the boiler-plate for the PLTn entry. */ - memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE); + 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; /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8. ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */ @@ -9365,10 +9487,10 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED, bfd_vma plt_base; - memcpy (htab->root.splt->contents, elfNN_aarch64_small_plt0_entry, - PLT_ENTRY_SIZE); + memcpy (htab->root.splt->contents, htab->plt0_entry, + htab->plt_header_size); elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize = - PLT_ENTRY_SIZE; + htab->plt_header_size; plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma + htab->root.sgotplt->output_offset @@ -9377,18 +9499,24 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED, plt_base = htab->root.splt->output_section->vma + htab->root.splt->output_offset; + /* 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; + /* 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, - htab->root.splt->contents + 4, + plt0_entry + 4, PG (plt_got_2nd_ent) - PG (plt_base + 4)); elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12, - htab->root.splt->contents + 8, + plt0_entry + 8, PG_OFFSET (plt_got_2nd_ent)); elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12, - htab->root.splt->contents + 12, + plt0_entry + 12, PG_OFFSET (plt_got_2nd_ent)); } @@ -9472,9 +9600,18 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgot->contents + htab->dt_tlsdesc_got); + const bfd_byte *entry = elfNN_aarch64_tlsdesc_small_plt_entry; + htab->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE; + + aarch64_plt_type type = elf_aarch64_tdata (output_bfd)->plt_type; + if (type == PLT_BTI) + { + entry = elfNN_aarch64_tlsdesc_small_plt_bti_entry; + htab->tlsdesc_plt_entry_size = PLT_BTI_TLSDESC_ENTRY_SIZE; + } + memcpy (htab->root.splt->contents + htab->tlsdesc_plt, - elfNN_aarch64_tlsdesc_small_plt_entry, - sizeof (elfNN_aarch64_tlsdesc_small_plt_entry)); + entry, htab->tlsdesc_plt_entry_size); { bfd_vma adrp1_addr = @@ -9496,6 +9633,15 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, bfd_byte *plt_entry = htab->root.splt->contents + htab->tlsdesc_plt; + /* First instruction in BTI enabled PLT stub is a BTI + instruction so skip it. */ + if (type & PLT_BTI) + { + plt_entry = plt_entry + 4; + adrp1_addr = adrp1_addr + 4; + adrp2_addr = adrp2_addr + 4; + } + /* adrp x2, DT_TLSDESC_GOT */ elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL, @@ -9574,6 +9720,53 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, return TRUE; } +/* Check if BTI enabled PLTs are needed. Returns the type needed. */ +static aarch64_plt_type +get_plt_type (bfd *abfd) +{ + aarch64_plt_type ret = PLT_NORMAL; + bfd_byte *contents, *extdyn, *extdynend; + asection *sec = bfd_get_section_by_name (abfd, ".dynamic"); + if (!sec || !bfd_malloc_and_get_section (abfd, sec, &contents)) + return ret; + extdyn = contents; + extdynend = contents + sec->size; + for (; extdyn < extdynend; extdyn += sizeof (ElfNN_External_Dyn)) + { + Elf_Internal_Dyn dyn; + bfd_elfNN_swap_dyn_in (abfd, extdyn, &dyn); + + /* Let's check the processor specific dynamic array tags. */ + bfd_vma tag = dyn.d_tag; + if (tag < DT_LOPROC || tag > DT_HIPROC) + continue; + + switch (tag) + { + case DT_AARCH64_BTI_PLT: + ret = PLT_BTI; + break; + + default: break; + } + } + free (contents); + return ret; +} + +static long +elfNN_aarch64_get_synthetic_symtab (bfd *abfd, + long symcount, + asymbol **syms, + long dynsymcount, + asymbol **dynsyms, + asymbol **ret) +{ + elf_aarch64_tdata (abfd)->plt_type = get_plt_type (abfd); + return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms, + dynsymcount, dynsyms, ret); +} + /* Return address for Ith PLT stub in section PLT, for relocation REL or (bfd_vma) -1 if it should not be included. */ @@ -9581,7 +9774,16 @@ static bfd_vma elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt, const arelent *rel ATTRIBUTE_UNUSED) { - return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE; + size_t plt0_size = PLT_ENTRY_SIZE; + size_t pltn_size = PLT_SMALL_ENTRY_SIZE; + + if (elf_aarch64_tdata (plt->owner)->plt_type == PLT_BTI) + { + plt0_size = PLT_BTI_ENTRY_SIZE; + if (elf_elfheader (plt->owner)->e_type == ET_EXEC) + pltn_size = PLT_BTI_SMALL_ENTRY_SIZE; + } + return plt->vma + plt0_size + i * pltn_size; } /* Returns TRUE if NAME is an AArch64 mapping symbol. @@ -9627,6 +9829,9 @@ elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info *info) uint32_t prop = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop; bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop); 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; } @@ -9641,6 +9846,23 @@ elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info, { uint32_t prop = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop; + + /* If output has been marked with BTI using command line argument, give out + warning if necessary. */ + if ((prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) + && (!elf_aarch64_tdata (info->output_bfd)->no_bti_warn)) + { + if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) + || (bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) + /* If either property is NULL, it means its bfd did not have any + property. */ + || !aprop || !bprop) + { + _bfd_error_handler (_("warning: BTI turned on by --force-bti when " + "all inputs do not have BTI in NOTE section.")); + } + } + return _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop, bprop, prop); } @@ -9718,6 +9940,9 @@ const struct elf_size_info elfNN_aarch64_size_info = #define bfd_elfNN_find_nearest_line \ elfNN_aarch64_find_nearest_line +#define bfd_elfNN_get_synthetic_symtab \ + elfNN_aarch64_get_synthetic_symtab + #define bfd_elfNN_mkobject \ elfNN_aarch64_mkobject diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 894eb55..b2adf16 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,4 +1,12 @@ 2019-03-13 Sudakshina Das <sudi.das@arm.com> + Szabolcs Nagy <szabolcs.nagy@arm.com> + + * readelf.c (get_aarch64_dynamic_type): New. + (get_dynamic_type): Use above for EM_AARCH64. + (dynamic_section_aarch64_val): New. + (process_dynamic_section): Use above for EM_AARCH64. + +2019-03-13 Sudakshina Das <sudi.das@arm.com> * readelf.c (decode_aarch64_feature_1_and): New. (print_gnu_property_note): Add case for AArch64 gnu notes. diff --git a/binutils/readelf.c b/binutils/readelf.c index 7446ffe..f4775b4 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -1798,6 +1798,17 @@ dump_relocations (Filedata * filedata, } static const char * +get_aarch64_dynamic_type (unsigned long type) +{ + switch (type) + { + case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT"; + default: + return NULL; + } +} + +static const char * get_mips_dynamic_type (unsigned long type) { switch (type) @@ -2170,6 +2181,9 @@ get_dynamic_type (Filedata * filedata, unsigned long type) switch (filedata->file_header.e_machine) { + case EM_AARCH64: + result = get_aarch64_dynamic_type (type); + break; case EM_MIPS: case EM_MIPS_RS3_LE: result = get_mips_dynamic_type (type); @@ -9345,6 +9359,20 @@ process_unwind (Filedata * filedata) } static void +dynamic_section_aarch64_val (Elf_Internal_Dyn * entry) +{ + switch (entry->d_tag) + { + case DT_AARCH64_BTI_PLT: + break; + default: + print_vma (entry->d_un.d_ptr, PREFIX_HEX); + break; + } + putchar ('\n'); +} + +static void dynamic_section_mips_val (Elf_Internal_Dyn * entry) { switch (entry->d_tag) @@ -10358,6 +10386,9 @@ process_dynamic_section (Filedata * filedata) { switch (filedata->file_header.e_machine) { + case EM_AARCH64: + dynamic_section_aarch64_val (entry); + break; case EM_MIPS: case EM_MIPS_RS3_LE: dynamic_section_mips_val (entry); diff --git a/include/ChangeLog b/include/ChangeLog index cf4353c..d67f80f 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,4 +1,9 @@ 2019-03-13 Sudakshina Das <sudi.das@arm.com> + Szabolcs Nagy <szabolcs.nagy@arm.com> + + * elf/aarch64.h (DT_AARCH64_BTI_PLT): New. + +2019-03-13 Sudakshina Das <sudi.das@arm.com> * elf/common.h (GNU_PROPERTY_AARCH64_FEATURE_1_AND): New. (GNU_PROPERTY_AARCH64_FEATURE_1_BTI): New. diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h index 3133ea6..b86a100 100644 --- a/include/elf/aarch64.h +++ b/include/elf/aarch64.h @@ -35,6 +35,8 @@ entry point. */ #define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step. */ +/* Processor specific dynamic array tags. */ +#define DT_AARCH64_BTI_PLT (DT_LOPROC + 1) /* Relocation types. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 32b5387..151877d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,4 +1,23 @@ 2019-03-13 Sudakshina Das <sudi.das@arm.com> + Szabolcs Nagy <szabolcs.nagy@arm.com> + + * NEWS: Document --force-bti. + * emultempl/aarch64elf.em (plt_type, bti_type, OPTION_FORCE_BTI): New. + (PARSE_AND_LIST_SHORTOPTS, PARSE_AND_LIST_OPTIONS): Add force-bti. + (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_FORCE_BTI. + * testsuite/ld-aarch64/aarch64-elf.exp: Add all the tests below. + * testsuite/ld-aarch64/bti-plt-1.d: New test. + * testsuite/ld-aarch64/bti-plt-1.s: New test. + * testsuite/ld-aarch64/bti-plt-2.d: New test. + * testsuite/ld-aarch64/bti-plt-3.d: New test. + * testsuite/ld-aarch64/bti-plt-4.d: New test. + * testsuite/ld-aarch64/bti-plt-5.d: New test. + * testsuite/ld-aarch64/bti-plt-6.d: New test. + * testsuite/ld-aarch64/bti-plt-7.d: New test. + * testsuite/ld-aarch64/bti-plt-so.s: New test. + * testsuite/ld-aarch64/bti-plt.ld: New test. + +2019-03-13 Sudakshina Das <sudi.das@arm.com> * NEWS: Document GNU_PROPERTY_AARCH64_FEATURE_1_BTI and GNU_PROPERTY_AARCH64_FEATURE_1_PAC. @@ -10,6 +10,10 @@ Changes in 2.33: * Add support for GNU_PROPERTY_AARCH64_FEATURE_1_PAC in ELF GNU program properties in the AArch64 ELF linker. +* Add --force-bti for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI + on output while warning about missing GNU_PROPERTY_AARCH64_FEATURE_1_BTI + on inputs and use PLTs protected with BTI. + Changes in 2.32: * Report property change in linker map file when merging GNU properties. diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em index 45e40b5..02243d9 100644 --- a/ld/emultempl/aarch64elf.em +++ b/ld/emultempl/aarch64elf.em @@ -33,6 +33,8 @@ static int pic_veneer = 0; static int fix_erratum_835769 = 0; static int fix_erratum_843419 = 0; static int no_apply_dynamic_relocs = 0; +static aarch64_plt_type plt_type = PLT_NORMAL; +static aarch64_enable_bti_type bti_type = BTI_NONE; static void gld${EMULATION_NAME}_before_parse (void) @@ -308,12 +310,17 @@ aarch64_elf_create_output_section_statements (void) return; } + aarch64_bti_pac_info bp_info; + bp_info.plt_type = plt_type; + bp_info.bti_type = bti_type; + bfd_elf${ELFSIZE}_aarch64_set_options (link_info.output_bfd, &link_info, no_enum_size_warning, no_wchar_size_warning, pic_veneer, fix_erratum_835769, fix_erratum_843419, - no_apply_dynamic_relocs); + no_apply_dynamic_relocs, + bp_info); stub_file = lang_add_input_file ("linker stubs", lang_input_file_is_fake_enum, @@ -365,6 +372,7 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_FIX_ERRATUM_835769 313 #define OPTION_FIX_ERRATUM_843419 314 #define OPTION_NO_APPLY_DYNAMIC_RELOCS 315 +#define OPTION_FORCE_BTI 316 ' PARSE_AND_LIST_SHORTOPTS=p @@ -378,6 +386,7 @@ PARSE_AND_LIST_LONGOPTS=' { "fix-cortex-a53-835769", no_argument, NULL, OPTION_FIX_ERRATUM_835769}, { "fix-cortex-a53-843419", no_argument, NULL, OPTION_FIX_ERRATUM_843419}, { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS}, + { "force-bti", no_argument, NULL, OPTION_FORCE_BTI}, ' PARSE_AND_LIST_OPTIONS=' @@ -398,6 +407,7 @@ PARSE_AND_LIST_OPTIONS=' fprintf (file, _(" --fix-cortex-a53-835769 Fix erratum 835769\n")); fprintf (file, _(" --fix-cortex-a53-843419 Fix erratum 843419\n")); fprintf (file, _(" --no-apply-dynamic-relocs Do not apply link-time values for dynamic relocations\n")); + fprintf (file, _(" --force-bti Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n")); ' PARSE_AND_LIST_ARGS_CASES=' @@ -429,6 +439,11 @@ PARSE_AND_LIST_ARGS_CASES=' no_apply_dynamic_relocs = 1; break; + case OPTION_FORCE_BTI: + plt_type |= PLT_BTI; + bti_type = BTI_WARN; + break; + case OPTION_STUBGROUP_SIZE: { const char *end; diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index c6fefbb..906534b 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -374,6 +374,8 @@ run_dump_test_lp64 "pie-bind-locally" run_dump_test "property-bti-pac1" run_dump_test "property-bti-pac2" run_dump_test "property-bti-pac3" +run_dump_test "bti-plt-1" +run_dump_test "bti-plt-2" set aarch64elflinktests { {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s} @@ -389,6 +391,14 @@ set aarch64elflinktests { {"ld-aarch64/func sym hash opt for exe" "-e0 --hash-style=gnu tmpdir/func-in-so.so" "" "" {func-sym-hash-opt.s} {{readelf --dyn-sym func-sym-hash-opt.d}} "hash-opt"} + {"Build bti-plt-so for PLT tests" "-shared" "" "" {bti-plt-so.s} + {} "libbti-plt-so.so"} } run_ld_link_tests $aarch64elflinktests + +run_dump_test "bti-plt-3" +run_dump_test "bti-plt-4" +run_dump_test "bti-plt-5" +run_dump_test "bti-plt-6" +run_dump_test "bti-plt-7" diff --git a/ld/testsuite/ld-aarch64/bti-plt-1.d b/ld/testsuite/ld-aarch64/bti-plt-1.d new file mode 100644 index 0000000..b7b58a8 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-1.d @@ -0,0 +1,32 @@ +#name: Check --force-bti emits BTI PLT (shared) +#source: bti-plt-1.s +#as: -mabi=lp64 +#ld: -shared --force-bti -T bti-plt.ld +#objdump: -dr -j .plt + +[^:]*: *file format elf64-.*aarch64 + +Disassembly of section \.plt: + +[0-9]+ <.*>: +.*: d503245f bti c +.*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! +.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: f9400e11 ldr x17, \[x16, #24\] +.*: 91006210 add x16, x16, #0x18 +.*: d61f0220 br x17 +.*: d503201f nop +.*: d503201f nop +.*: d503201f nop + +[0-9]+ <.*>: +.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: f9401211 ldr x17, \[x16, #32\] +.*: 91008210 add x16, x16, #0x20 +.*: d61f0220 br x17 + +[0-9]+ <.*>: +.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: f9401611 ldr x17, \[x16, #40\] +.*: 9100a210 add x16, x16, #0x28 +.*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/bti-plt-1.s b/ld/testsuite/ld-aarch64/bti-plt-1.s new file mode 100644 index 0000000..78e1aaa --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-1.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +_start: + bl foo + bl bar + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* BTI. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-aarch64/bti-plt-2.d b/ld/testsuite/ld-aarch64/bti-plt-2.d new file mode 100644 index 0000000..c26e47a --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-2.d @@ -0,0 +1,11 @@ +#name: Check --force-bti emits BTI feature (shared) +#source: bti-plt-1.s +#source: bti-plt-2.s +#as: -mabi=lp64 +#ld: -shared --force-bti -T bti-plt.ld +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: AArch64 feature: BTI diff --git a/ld/testsuite/ld-aarch64/bti-plt-2.s b/ld/testsuite/ld-aarch64/bti-plt-2.s new file mode 100644 index 0000000..fff945c --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-2.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +func2: + bl foo2 + bl bar2 + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* BTI. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-aarch64/bti-plt-3.d b/ld/testsuite/ld-aarch64/bti-plt-3.d new file mode 100644 index 0000000..0d4c467 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-3.d @@ -0,0 +1,34 @@ +#name: Check --force-bti emits BTI PLT (exec) +#source: bti-plt-1.s +#as: -mabi=lp64 +#ld: --force-bti -e _start -T bti-plt.ld -L./tmpdir -lbti-plt-so +#objdump: -dr -j .plt + +[^:]*: *file format elf64-.*aarch64 + +Disassembly of section \.plt: + +[0-9]+ <.*>: +.*: d503245f bti c +.*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! +.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: f9400e11 ldr x17, \[x16, #24\] +.*: 91006210 add x16, x16, #0x18 +.*: d61f0220 br x17 +.*: d503201f nop +.*: d503201f nop +.*: d503201f nop + +[0-9]+ <.*>: +.*: d503245f bti c +.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: f9401211 ldr x17, \[x16, #32\] +.*: 91008210 add x16, x16, #0x20 +.*: d61f0220 br x17 + +[0-9]+ <.*>: +.*: d503245f bti c +.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: f9401611 ldr x17, \[x16, #40\] +.*: 9100a210 add x16, x16, #0x28 +.*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/bti-plt-4.d b/ld/testsuite/ld-aarch64/bti-plt-4.d new file mode 100644 index 0000000..90aeed2 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-4.d @@ -0,0 +1,10 @@ +#name: Check --force-bti emits BTI feature (exec) +#source: bti-plt-1.s +#as: -mabi=lp64 +#ld: --force-bti -e _start -T bti-plt.ld -L./tmpdir -lbti-plt-so +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: AArch64 feature: BTI diff --git a/ld/testsuite/ld-aarch64/bti-plt-5.d b/ld/testsuite/ld-aarch64/bti-plt-5.d new file mode 100644 index 0000000..01231b6 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-5.d @@ -0,0 +1,28 @@ +#name: BTI PLT with only GNU PROP +#source: property-bti-pac1.s +#as: -mabi=lp64 -defsym __property_bti__=1 +#ld: -e _start -L./tmpdir -lbti-plt-so +#objdump: -dr -j .plt +#target: *linux* + +[^:]*: *file format elf64-.*aarch64 + +Disassembly of section \.plt: + +[0-9a-f]+ <.*>: +.*: d503245f bti c +.*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! +.*: 90000090 adrp x16, 410000 <_start\+0xfd28> +.*: f9421611 ldr x17, \[x16, #1064\] +.*: 9110a210 add x16, x16, #0x428 +.*: d61f0220 br x17 +.*: d503201f nop +.*: d503201f nop +.*: d503201f nop + +[0-9a-f]+ <.*>: +.*: d503245f bti c +.*: 90000090 adrp x16, 410000 <_start\+0xfd28> +.*: f9421a11 ldr x17, \[x16, #1072\] +.*: 9110c210 add x16, x16, #0x430 +.*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/bti-plt-6.d b/ld/testsuite/ld-aarch64/bti-plt-6.d new file mode 100644 index 0000000..c7d5169 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-6.d @@ -0,0 +1,15 @@ +#name: Warn with one missing GNU NOTE BTI input +#source: property-bti-pac1.s +#source: property-bti-pac2.s +#as: -mabi=lp64 -defsym __property_pac__=1 +#ld: -shared --force-bti +#warning: .*: warning: BTI turned on by --force-bti.*$ +#readelf: -n + +# Should warn about the missing input BTI NOTE but should +# still mark output as BTI + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: AArch64 feature: BTI, PAC diff --git a/ld/testsuite/ld-aarch64/bti-plt-7.d b/ld/testsuite/ld-aarch64/bti-plt-7.d new file mode 100644 index 0000000..625f284 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-7.d @@ -0,0 +1,15 @@ +#name: Warn when neither inputs has GNU NOTE BTI +#source: property-bti-pac1.s +#source: plt_mapping_symbol.s +#as: -mabi=lp64 +#ld: -shared --force-bti +#warning: .*: warning: BTI turned on by --force-bti.*$ +#readelf: -n + +# Should warn about the missing input BTI NOTE but should +# still mark output as BTI + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: AArch64 feature: BTI diff --git a/ld/testsuite/ld-aarch64/bti-plt-so.s b/ld/testsuite/ld-aarch64/bti-plt-so.s new file mode 100644 index 0000000..2c11356 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt-so.s @@ -0,0 +1,41 @@ + .global foo + .type foo, %function +foo: + sub sp, sp, #16 + mov w0, 9 + str w0, [sp, 12] + ldr w0, [sp, 12] + add w0, w0, 4 + str w0, [sp, 12] + nop + add sp, sp, 16 + ret + .size foo, .-foo + .global bar + .type bar, %function +bar: + sub sp, sp, #16 + mov w0, 9 + str w0, [sp, 12] + ldr w0, [sp, 12] + add w0, w0, 4 + str w0, [sp, 12] + nop + add sp, sp, 16 + ret + .size bar, .-bar + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* BTI. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-aarch64/bti-plt.ld b/ld/testsuite/ld-aarch64/bti-plt.ld new file mode 100644 index 0000000..8682623 --- /dev/null +++ b/ld/testsuite/ld-aarch64/bti-plt.ld @@ -0,0 +1,14 @@ +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + . = 0x10000; + .rela.plt : { *(.rela.plt) *(.rela.iplt) } + . = 0x18000; + .plt : { *(.plt) *(.iplt) } + . = 0x20000; + .text : { *(.text) } + . = 0x28000; + .got : { *(.got) *(.got.plt) } + .ARM.attributes 0 : { *(.ARM.atttributes) } +} |