Hi This patch adds the GNU NOTE section to the BTI and/or PAC enabled objects for linux targets. The ABI document that we published mentioning GNU NOTE section is below: https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4
The patches needed for these in binutils are already approved and committed. https://sourceware.org/ml/binutils/2019-03/msg00072.html Bootstrapped and regression tested with aarch64-none-linux-gnu. Is this ok for trunk? Thanks Sudi *** gcc/ChangeLog *** 2018-xx-xx Sudakshina Das <sudi....@arm.com> * config/aarch64/aarch64-linux.h (TARGET_ASM_FILE_END): Define for AArch64. (aarch64_file_end_indicate_exec_stack): Add gnu note section. gcc/testsuite/ChangeLog: 2018-xx-xx Sudakshina Das <sudi....@arm.com> * gcc.target/aarch64/bti-1.c: Add scan directive for gnu note section for linux targets. * gcc.target/aarch64/va_arg_1.c: Don't run for aarch64 linux targets with --enable-standard-branch-protection.
diff --git a/gcc/config/aarch64/aarch64-linux.h b/gcc/config/aarch64/aarch64-linux.h index 9d0292d64f20939ccedd7ab56027aa1282826b23..5e8b34ded03c78493f868e38647bf57c2da5187c 100644 --- a/gcc/config/aarch64/aarch64-linux.h +++ b/gcc/config/aarch64/aarch64-linux.h @@ -83,7 +83,7 @@ #define GNU_USER_TARGET_D_CRITSEC_SIZE 48 -#define TARGET_ASM_FILE_END file_end_indicate_exec_stack +#define TARGET_ASM_FILE_END aarch64_file_end_indicate_exec_stack /* Uninitialized common symbols in non-PIE executables, even with strong definitions in dependent shared libraries, will resolve diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b38505b0872688634b2d3f625ab8d313e89cfca0..d616c8360b396ebe3ab2ac0fb799b30830df2b3e 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -18744,6 +18744,67 @@ aarch64_stack_protect_guard (void) return NULL_TREE; } +/* Implement TARGET_ASM_FILE_END for AArch64. This adds the AArch64 GNU NOTE + section at the end if needed. */ +#define ASM_LONG "\t.long\t" +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) +void +aarch64_file_end_indicate_exec_stack () +{ + file_end_indicate_exec_stack (); + + if (!aarch64_bti_enabled () + && aarch64_ra_sign_scope == AARCH64_FUNCTION_NONE) + { + return; + } + + unsigned feature_1_and = 0; + if (aarch64_bti_enabled ()) + feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; + + if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE) + feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC; + + if (feature_1_and) + { + int p2align = ptr_mode == SImode ? 2 : 3; + + /* Generate GNU_PROPERTY_AARCH64_FEATURE_1_XXX. */ + switch_to_section (get_section (".note.gnu.property", + SECTION_NOTYPE, NULL)); + + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + /* name length. */ + fprintf (asm_out_file, ASM_LONG " 1f - 0f\n"); + /* data length. */ + fprintf (asm_out_file, ASM_LONG " 4f - 1f\n"); + /* note type: NT_GNU_PROPERTY_TYPE_0. */ + fprintf (asm_out_file, ASM_LONG " 5\n"); + fprintf (asm_out_file, "0:\n"); + /* vendor name: "GNU". */ + fprintf (asm_out_file, STRING_ASM_OP " \"GNU\"\n"); + fprintf (asm_out_file, "1:\n"); + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + /* pr_type: GNU_PROPERTY_AARCH64_FEATURE_1_AND. */ + fprintf (asm_out_file, ASM_LONG " 0x%x\n", + GNU_PROPERTY_AARCH64_FEATURE_1_AND); + /* pr_datasz. */\ + fprintf (asm_out_file, ASM_LONG " 3f - 2f\n"); + fprintf (asm_out_file, "2:\n"); + /* GNU_PROPERTY_AARCH64_FEATURE_1_XXX. */ + fprintf (asm_out_file, ASM_LONG " 0x%x\n", feature_1_and); + fprintf (asm_out_file, "3:\n"); + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + fprintf (asm_out_file, "4:\n"); + } +} +#undef GNU_PROPERTY_AARCH64_FEATURE_1_PAC +#undef GNU_PROPERTY_AARCH64_FEATURE_1_BTI +#undef GNU_PROPERTY_AARCH64_FEATURE_1_AND +#undef ASM_LONG /* Target-specific selftests. */ diff --git a/gcc/testsuite/gcc.target/aarch64/bti-1.c b/gcc/testsuite/gcc.target/aarch64/bti-1.c index a8c60412e310a4f322372f334ae5314f426d310e..5a556b08ed15679b25676a11fe9c7a64641ee671 100644 --- a/gcc/testsuite/gcc.target/aarch64/bti-1.c +++ b/gcc/testsuite/gcc.target/aarch64/bti-1.c @@ -61,3 +61,4 @@ lab2: } /* { dg-final { scan-assembler-times "hint\t34" 1 } } */ /* { dg-final { scan-assembler-times "hint\t36" 12 } } */ +/* { dg-final { scan-assembler ".note.gnu.property" { target *-*-linux* } } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/va_arg_1.c b/gcc/testsuite/gcc.target/aarch64/va_arg_1.c index e8e3cdac51350b545e5c2a644a3e1f4d1c37f88d..1fe92ff08935d4c6f08affcbd77ea91537030640 100644 --- a/gcc/testsuite/gcc.target/aarch64/va_arg_1.c +++ b/gcc/testsuite/gcc.target/aarch64/va_arg_1.c @@ -4,7 +4,9 @@ int f (int a, ...) { - /* { dg-final { scan-assembler-not "str" } } */ + /* Fails on aarch64*-*-linux* if configured with + --enable-standard-branch-protection because of the GNU NOTE section. */ + /* { dg-final { scan-assembler-not "str" { target { ! aarch64*-*-linux* } || { ! default_branch_protection } } } } */ return a; }