From: Sudakshina Das <Sudi.Das@arm.com>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Cc: nd <nd@arm.com>, James Greenhalgh <James.Greenhalgh@arm.com>,
Richard Earnshaw <Richard.Earnshaw@arm.com>,
Marcus Shawcroft <Marcus.Shawcroft@arm.com>
Subject: Re: [PATCH, GCC, AARCH64, 5/6] Enable BTI : Add new pass for BTI.
Date: Fri, 14 Dec 2018 16:09:00 -0000 [thread overview]
Message-ID: <ba3e4346-2bae-c23f-ec53-a3669754c49a@arm.com> (raw)
In-Reply-To: <4a091322-c031-ced1-a78b-dd45316d8c7c@arm.com>
[-- Attachment #1: Type: text/plain, Size: 4915 bytes --]
Hi James
On 29/11/18 16:47, Sudakshina Das wrote:
> Hi
>
> On 13/11/18 14:47, Sudakshina Das wrote:
>> Hi
>>
>> On 02/11/18 18:38, Sudakshina Das wrote:
>>> Hi
>>>
>>> This patch is part of a series that enables ARMv8.5-A in GCC and
>>> adds Branch Target Identification Mechanism.
>>> (https://developer.arm.com/products/architecture/cpu-architecture/a-profile/exploration-tools)
>>>
>>> This patch adds a new pass called "bti" which is triggered by the
>>> command line argument -mbranch-protection whenever "bti" is turned on.
>>>
>>> The pass iterates through the instructions and adds appropriated BTI
>>> instructions based on the following:
>>> * Add a new "BTI C" at the beginning of a function, unless its already
>>> protected by a "PACIASP/PACIBSP". We exempt the functions that are
>>> only called directly.
>>> * Add a new "BTI J" for every target of an indirect jump, jump table
>>> targets, non-local goto targets or labels that might be referenced
>>> by variables, constant pools, etc (NOTE_INSN_DELETED_LABEL)
>>>
>>> Since we have already changed the use of indirect tail calls to only x16
>>> and x17, we do not have to use "BTI JC".
>>> (check patch 3/6).
>>>
>>
>> I missed out on the explanation for the changes to the trampoline code.
>> The patch also updates the trampoline code in case BTI is enabled. Since
>> the trampoline code is a target of an indirect branch, we need to add an
>> appropriate BTI instruction at the beginning of it to avoid a branch
>> target exception.
>>
>>> Bootstrapped and regression tested with aarch64-none-linux-gnu. Added
>>> new tests.
>>> Is this ok for trunk?
>>>
>>> Thanks
>>> Sudi
>>>
>>> *** gcc/ChangeLog ***
>>>
>>> 2018-xx-xx Sudakshina Das <sudi.das@arm.com>
>>> Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
>>>
>>> * config.gcc (aarch64*-*-*): Add aarch64-bti-insert.o.
>>> * gcc/config/aarch64/aarch64.h: Update comment for
>>> TRAMPOLINE_SIZE.
>>> * config/aarch64/aarch64.c (aarch64_asm_trampoline_template):
>>> Update if bti is enabled.
>>> * config/aarch64/aarch64-bti-insert.c: New file.
>>> * config/aarch64/aarch64-passes.def (INSERT_PASS_BEFORE): Insert
>>> bti pass.
>>> * config/aarch64/aarch64-protos.h (make_pass_insert_bti):
>>> Declare the new bti pass.
>>> * config/aarch64/aarch64.md (bti_nop): Define.
>>> * config/aarch64/t-aarch64: Add rule for aarch64-bti-insert.o.
>>>
>>> *** gcc/testsuite/ChangeLog ***
>>>
>>> 2018-xx-xx Sudakshina Das <sudi.das@arm.com>
>>>
>>> * gcc.target/aarch64/bti-1.c: New test.
>>> * gcc.target/aarch64/bti-2.c: New test.
>>> * lib/target-supports.exp
>>> (check_effective_target_aarch64_bti_hw): Add new check for
>>> BTI hw.
>>>
>>
>> Updated patch attached with more comments and a bit of simplification
>> in aarch64-bti-insert.c. ChangeLog still applies.
>>
>> Thanks
>> Sudi
>>
>
> I found a missed case in the bti pass and edited the patch to include
> it. This made me realize that the only 2 regressions I saw with the
> BTI enabled model can now be avoided. (as quoted below from my 6/6
> patch)
> "Bootstrapped and regression tested with aarch64-none-linux-gnu with
> and without the configure option turned on.
> Also tested on aarch64-none-elf with and without configure option with a
> BTI enabled aem. Only 2 regressions and these were because newlib
> requires patches to protect hand coded libraries with BTI."
>
> The ChangeLog still applies.
>
> Sudi
>
I have updated the patch according to our discussions offline.
The md pattern is now split into 4 patterns and i have added a new
test for the setjmp case along with some comments where missing.
*** gcc/ChangeLog ***
2018-xx-xx Sudakshina Das <sudi.das@arm.com>
Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config.gcc (aarch64*-*-*): Add aarch64-bti-insert.o.
* gcc/config/aarch64/aarch64.h: Update comment for
TRAMPOLINE_SIZE.
* config/aarch64/aarch64.c (aarch64_asm_trampoline_template):
Update if bti is enabled.
* config/aarch64/aarch64-bti-insert.c: New file.
* config/aarch64/aarch64-passes.def (INSERT_PASS_BEFORE): Insert
bti pass.
* config/aarch64/aarch64-protos.h (make_pass_insert_bti):
Declare the new bti pass.
* config/aarch64/aarch64.md (unspecv): Add UNSPECV_BTI_NOARG,
UNSPECV_BTI_C, UNSPECV_BTI_J and UNSPECV_BTI_JC.
(bti_noarg, bti_j, bti_c, bti_jc): New define_insns.
* config/aarch64/t-aarch64: Add rule for aarch64-bti-insert.o.
*** gcc/testsuite/ChangeLog ***
2018-xx-xx Sudakshina Das <sudi.das@arm.com>
* gcc.target/aarch64/bti-1.c: New test.
* gcc.target/aarch64/bti-2.c: New test.
* gcc.target/aarch64/bti-3.c: New test.
* lib/target-supports.exp
(check_effective_target_aarch64_bti_hw): Add new check for
BTI hw.
Thanks
Sudi
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rb10090.patch --]
[-- Type: text/x-patch; name="rb10090.patch", Size: 19407 bytes --]
diff --git a/gcc/config.gcc b/gcc/config.gcc
index cbabd21b33723a65790e2eafe8aa4979051cae48..f3dd3feceb3375374a29ca58e4ad87f949cea44d 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -318,7 +318,7 @@ aarch64*-*-*)
c_target_objs="aarch64-c.o"
cxx_target_objs="aarch64-c.o"
d_target_objs="aarch64-d.o"
- extra_objs="aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o aarch64-speculation.o falkor-tag-collision-avoidance.o"
+ extra_objs="aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o aarch64-speculation.o falkor-tag-collision-avoidance.o aarch64-bti-insert.o"
target_gtfiles="\$(srcdir)/config/aarch64/aarch64-builtins.c"
target_has_targetm_common=yes
;;
diff --git a/gcc/config/aarch64/aarch64-bti-insert.c b/gcc/config/aarch64/aarch64-bti-insert.c
new file mode 100644
index 0000000000000000000000000000000000000000..b8ab3f7bf64aa8f0071a911c9019eb0a78d45ead
--- /dev/null
+++ b/gcc/config/aarch64/aarch64-bti-insert.c
@@ -0,0 +1,236 @@
+/* Branch Target Identification for AArch64 architecture.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ Contributed by Arm Ltd.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#define INCLUDE_STRING
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "rtl.h"
+#include "tree.h"
+#include "memmodel.h"
+#include "gimple.h"
+#include "tm_p.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "emit-rtl.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "dumpfile.h"
+#include "rtl-iter.h"
+#include "cfgrtl.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+
+/* This pass enables the support for Branch Target Identification Mechanism
+ for AArch64. This is a new security feature introduced in ARMv8.5-A
+ archtitecture. A BTI instruction is used to guard against the execution
+ of instructions which are not the intended target of an indirect branch.
+
+ Outside of a guarded memory region, a BTI instruction executes as a NOP.
+ Within a guarded memory region any target of an indirect branch must be
+ a compatible BTI or BRK, HLT, PACIASP, PACIBASP instruction (even if the
+ branch is triggered in a non-guarded memory region). An incompatibility
+ generates a Branch Target Exception.
+
+ The compatibility of the BTI instruction is as follows:
+ BTI j : Can be a target of any indirect jump (BR Xn).
+ BTI c : Can be a target of any indirect call (BLR Xn and BR X16/X17).
+ BTI jc: Can be a target of any indirect call or indirect jump.
+ BTI : Can not be a target of any indirect call or indirect jump.
+
+ In order to enable this mechanism, this pass iterates through the
+ control flow of the code and adds appropriate BTI instructions :
+ * Add a new "BTI C" at the beginning of a function, unless its already
+ protected by a "PACIASP/PACIBSP". We exempt the functions that are only
+ called directly.
+ * Add a new "BTI J" for every target of an indirect jump, jump table targets,
+ non-local goto targets or labels that might be referenced by variables,
+ constant pools, etc (NOTE_INSN_DELETED_LABEL)
+
+ Since we have already changed the use of indirect tail calls to only x16
+ and x17, we do not have to use "BTI JC".
+
+ This pass is triggered by the command line option -mbranch-protection=bti or
+ -mbranch-protection=standard. Since all the BTI instructions are in the HINT
+ space, this pass does not require any minimum architecture version. */
+
+namespace {
+
+const pass_data pass_data_insert_bti =
+{
+ RTL_PASS, /* type. */
+ "bti", /* name. */
+ OPTGROUP_NONE, /* optinfo_flags. */
+ TV_MACH_DEP, /* tv_id. */
+ 0, /* properties_required. */
+ 0, /* properties_provided. */
+ 0, /* properties_destroyed. */
+ 0, /* todo_flags_start. */
+ 0, /* todo_flags_finish. */
+};
+
+/* Check if X (or any sub-rtx of X) is a PACIASP/PACIBSP instruction. */
+static bool
+aarch64_pac_insn_p (rtx x)
+{
+ if (!INSN_P (x))
+ return x;
+
+ subrtx_var_iterator::array_type array;
+ FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (x), ALL)
+ {
+ rtx sub = *iter;
+ if (sub && GET_CODE (sub) == UNSPEC)
+ {
+ int unspec_val = XINT (sub, 1);
+ switch (unspec_val)
+ {
+ case UNSPEC_PACIASP:
+ case UNSPEC_PACIBSP:
+ return true;
+
+ default:
+ return false;
+ }
+ iter.skip_subrtxes ();
+ }
+ }
+ return false;
+}
+
+/* Insert the BTI instruction. */
+/* This is implemented as a late RTL pass that runs before branch
+ shortening and does the following. */
+static unsigned int
+rest_of_insert_bti (void)
+{
+ timevar_push (TV_MACH_DEP);
+
+ rtx bti_insn;
+ rtx_insn *insn;
+ basic_block bb;
+
+ /* Since a Branch Target Exception can only be triggered by an indirect call,
+ we exempt function that are only called directly. We also exempt
+ functions that are already protected by Return Address Signing (PACIASP/
+ PACIBSP). For all other cases insert a BTI C at the beginning of the
+ function. */
+ if (!cgraph_node::get (cfun->decl)->only_called_directly_p ())
+ {
+ bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+ insn = BB_HEAD (bb);
+ if (!aarch64_pac_insn_p (get_first_nonnote_insn ()))
+ {
+ bti_insn = gen_bti_c ();
+ emit_insn_before (bti_insn, insn);
+ }
+ }
+
+ bb = 0;
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ /* If a label is marked to be preserved or can be a non-local goto
+ target, it must be protected with a BTI J. The same applies to
+ NOTE_INSN_DELETED_LABEL since they are basically labels that might
+ be referenced via variables or constant pool. */
+ if ((LABEL_P (insn)
+ && (LABEL_PRESERVE_P (insn)
+ || bb->flags & BB_NON_LOCAL_GOTO_TARGET))
+ || (NOTE_P (insn)
+ && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
+ {
+ bti_insn = gen_bti_j ();
+ emit_insn_after (bti_insn, insn);
+ continue;
+ }
+
+ /* There could still be more labels that are valid targets of a
+ BTI J instuction. To find them we start looking through the
+ JUMP_INSN. If it jumps to a jump table, then we find all labels
+ of the jump table to protect with a BTI J. */
+ if (JUMP_P (insn))
+ {
+ rtx_jump_table_data *table;
+ if (tablejump_p (insn, NULL, &table))
+ {
+ rtvec vec = table->get_labels ();
+ int j;
+ rtx_insn *label;
+
+ for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
+ {
+ label = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, j), 0));
+ bti_insn = gen_bti_j ();
+ emit_insn_after (bti_insn, label);
+ }
+ }
+ }
+
+ /* Also look for calls to setjmp () which would be marked with
+ REG_SETJMP note and put a BTI J after. This is where longjump ()
+ will return. */
+ if (CALL_P (insn) && (find_reg_note (insn, REG_SETJMP, NULL)))
+ {
+ bti_insn = gen_bti_j ();
+ emit_insn_after (bti_insn, insn);
+ continue;
+ }
+ }
+ }
+
+ timevar_pop (TV_MACH_DEP);
+ return 0;
+}
+
+
+class pass_insert_bti : public rtl_opt_pass
+{
+public:
+ pass_insert_bti (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_insert_bti, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *)
+ {
+ return aarch64_bti_enabled ();
+ }
+
+ virtual unsigned int execute (function *)
+ {
+ return rest_of_insert_bti ();
+ }
+
+}; // class pass_insert_bti
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_insert_bti (gcc::context *ctxt)
+{
+ return new pass_insert_bti (ctxt);
+}
diff --git a/gcc/config/aarch64/aarch64-passes.def b/gcc/config/aarch64/aarch64-passes.def
index 3982b6ea6290379e6ecac8046ebb27a14d2342f0..d3e316f406ecb0119787a67ad1c62fafaaf99a88 100644
--- a/gcc/config/aarch64/aarch64-passes.def
+++ b/gcc/config/aarch64/aarch64-passes.def
@@ -21,3 +21,4 @@
INSERT_PASS_AFTER (pass_regrename, 1, pass_fma_steering);
INSERT_PASS_BEFORE (pass_reorder_blocks, 1, pass_track_speculation);
INSERT_PASS_AFTER (pass_machine_reorg, 1, pass_tag_collision_avoidance);
+INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_insert_bti);
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index fa1128ce9b7208d732059feee48ebf3a0039850c..210c5d88c53ab34bae343237788dfe0d0cd80a4a 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -635,6 +635,7 @@ extern void aarch64_d_target_versions (void);
rtl_opt_pass *make_pass_fma_steering (gcc::context *);
rtl_opt_pass *make_pass_track_speculation (gcc::context *);
rtl_opt_pass *make_pass_tag_collision_avoidance (gcc::context *);
+rtl_opt_pass *make_pass_insert_bti (gcc::context *ctxt);
poly_uint64 aarch64_regmode_natural_size (machine_mode);
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index cc95be32d40268d3647c8280188f17ff8212a156..bd82ae3ddea4979e64608e0dc8b9d969fb691cd4 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -925,7 +925,7 @@ typedef struct
#define RETURN_ADDR_RTX aarch64_return_addr
-/* 3 insns + padding + 2 pointer-sized entries. */
+/* BTI c + 3 insns + 2 pointer-sized entries. */
#define TRAMPOLINE_SIZE (TARGET_ILP32 ? 24 : 32)
/* Trampolines contain dwords, so must be dword aligned. */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 8262e9da03683793995408fd8caf90dc069e1c8d..f66c963dcd5b00138c6a96cb013b675d639698e4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8137,18 +8137,36 @@ aarch64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
static void
aarch64_asm_trampoline_template (FILE *f)
{
+ int offset1 = 16;
+ int offset2 = 20;
+
+ if (aarch64_bti_enabled ())
+ {
+ asm_fprintf (f, "\thint\t34 // bti c\n");
+ offset1 -= 4;
+ offset2 -= 4;
+ }
+
if (TARGET_ILP32)
{
- asm_fprintf (f, "\tldr\tw%d, .+16\n", IP1_REGNUM - R0_REGNUM);
- asm_fprintf (f, "\tldr\tw%d, .+16\n", STATIC_CHAIN_REGNUM - R0_REGNUM);
+ asm_fprintf (f, "\tldr\tw%d, .+%d\n", IP1_REGNUM - R0_REGNUM, offset1);
+ asm_fprintf (f, "\tldr\tw%d, .+%d\n", STATIC_CHAIN_REGNUM - R0_REGNUM,
+ offset1);
}
else
{
- asm_fprintf (f, "\tldr\t%s, .+16\n", reg_names [IP1_REGNUM]);
- asm_fprintf (f, "\tldr\t%s, .+20\n", reg_names [STATIC_CHAIN_REGNUM]);
+ asm_fprintf (f, "\tldr\t%s, .+%d\n", reg_names [IP1_REGNUM], offset1);
+ asm_fprintf (f, "\tldr\t%s, .+%d\n", reg_names [STATIC_CHAIN_REGNUM],
+ offset2);
}
asm_fprintf (f, "\tbr\t%s\n", reg_names [IP1_REGNUM]);
- assemble_aligned_integer (4, const0_rtx);
+
+ /* The trampoline needs an extra padding instruction. In case if BTI is
+ enabled the padding instruction is replaced by the BTI instruction at
+ the beginning. */
+ if (!aarch64_bti_enabled ())
+ assemble_aligned_integer (4, const0_rtx);
+
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
}
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 1f21cbdd8e7e74c7f1183a85976d160b09d3049a..86f246b53c53908f555e5b844ad8b90b794a6fee 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -240,6 +240,10 @@
UNSPECV_BLOCKAGE ; Represent a blockage
UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing.
UNSPECV_SPECULATION_BARRIER ; Represent speculation barrier.
+ UNSPECV_BTI_NOARG ; Represent BTI.
+ UNSPECV_BTI_C ; Represent BTI c.
+ UNSPECV_BTI_J ; Represent BTI j.
+ UNSPECV_BTI_JC ; Represent BTI jc.
]
)
@@ -6721,6 +6725,35 @@
[(set_attr "type" "csel")]
)
+;; BTI <target> instructions
+(define_insn "bti_noarg"
+ [(unspec_volatile [(const_int 0)] UNSPECV_BTI_NOARG)]
+ ""
+ "hint\t32 // bti"
+ [(set_attr "type" "no_insn")]
+)
+
+(define_insn "bti_c"
+ [(unspec_volatile [(const_int 0)] UNSPECV_BTI_C)]
+ ""
+ "hint\t34 // bti c"
+ [(set_attr "type" "no_insn")]
+)
+
+(define_insn "bti_j"
+ [(unspec_volatile [(const_int 0)] UNSPECV_BTI_J)]
+ ""
+ "hint\t36 // bti j"
+ [(set_attr "type" "no_insn")]
+)
+
+(define_insn "bti_jc"
+ [(unspec_volatile [(const_int 0)] UNSPECV_BTI_JC)]
+ ""
+ "hint\t38 // bti jc"
+ [(set_attr "type" "no_insn")]
+)
+
;; Helper for aarch64.c code.
(define_expand "set_clobber_cc"
[(parallel [(set (match_operand 0)
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index e91dccea9954c2c387fb111d1b357dd2c220ff0a..a2048547be56eba8a47c22c9d2b94e787364828f 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -91,6 +91,15 @@ falkor-tag-collision-avoidance.o: \
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/aarch64/falkor-tag-collision-avoidance.c
+aarch64-bti-insert.o: $(srcdir)/config/aarch64/aarch64-bti-insert.c \
+ $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(REGS_H) insn-config.h $(RTL_BASE_H) \
+ dominance.h cfg.h cfganal.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(RECOG_H) \
+ output.h hash-map.h $(DF_H) $(OBSTACK_H) $(TARGET_H) $(RTL_H) \
+ $(CONTEXT_H) $(TREE_PASS_H) regrename.h \
+ $(srcdir)/config/aarch64/aarch64-protos.h
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/aarch64/aarch64-bti-insert.c
+
comma=,
MULTILIB_OPTIONS = $(subst $(comma),/, $(patsubst %, mabi=%, $(subst $(comma),$(comma)mabi=,$(TM_MULTILIB_CONFIG))))
MULTILIB_DIRNAMES = $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
diff --git a/gcc/testsuite/gcc.target/aarch64/bti-1.c b/gcc/testsuite/gcc.target/aarch64/bti-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..575d01a5411a19dabcdb56b777e5d87d9703a848
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bti-1.c
@@ -0,0 +1,59 @@
+/* { dg-do compile } */
+/* -Os to create jump table. */
+/* { dg-options "-Os -mbranch-protection=standard" } */
+
+extern int f1 (void);
+extern int f2 (void);
+extern int f3 (void);
+extern int f4 (void);
+extern int f5 (void);
+extern int f6 (void);
+extern int f7 (void);
+extern int f8 (void);
+extern int f9 (void);
+extern int f10 (void);
+
+int (*ptr) (void);
+
+int
+f_jump_table (int y, int n)
+{
+ int i;
+ for (i = 0; i < n ;i ++)
+ {
+ switch (y)
+ {
+ case 0 : ptr = f1; break;
+ case 1 : ptr = f2; break;
+ case 2 : ptr = f3; break;
+ case 3 : ptr = f4; break;
+ case 4 : ptr = f5; break;
+ case 5 : ptr = f6; break;
+ case 6 : ptr = f7; break;
+ case 7 : ptr = f8; break;
+ case 8 : ptr = f9; break;
+ case 9 : ptr = f10; break;
+ default: break;
+ }
+ y += ptr ();
+ }
+ return (y == 0)? y+1:4;
+}
+/* f_jump_table should have PACIASP and AUTIASP. */
+/* { dg-final { scan-assembler-times "hint\t25" 1 } } */
+/* { dg-final { scan-assembler-times "hint\t29" 1 } } */
+
+int
+f_label_address ()
+{
+ static void * addr = &&lab1;
+ goto *addr;
+lab1:
+ addr = &&lab2;
+ return 1;
+lab2:
+ addr = &&lab1;
+ return 2;
+}
+/* { dg-final { scan-assembler-times "hint\t34" 1 } } */
+/* { dg-final { scan-assembler-times "hint\t36" 12 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/bti-2.c b/gcc/testsuite/gcc.target/aarch64/bti-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..e50eef15c8936d00716c582e90b235add5da9136
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bti-2.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-effective-target aarch64_bti_hw } */
+/* { dg-options "-mbranch-protection=standard" } */
+
+#include<stdio.h>
+
+typedef int FP (int);
+
+int
+f1 (FP fp, int n)
+{
+ return (fp) (n);
+}
+
+int
+f2 (int n, FP fp)
+{
+ return (fp) (n);
+}
+
+int __attribute__ ((noinline))
+func (int x)
+{
+ return x+1;
+}
+
+int main ()
+{
+ int s = 0;
+ s += f1 (func, 10);
+ s += f2 (s, func);
+ printf ("S: %d\n", s);
+ return !(s == 23);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/bti-3.c b/gcc/testsuite/gcc.target/aarch64/bti-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..97cf5d37f42b9313da75481c2ceac884735ac995
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bti-3.c
@@ -0,0 +1,52 @@
+/* This is a copy of gcc/testsuite/gcc.c-torture/execute/pr56982.c to test the
+ setjmp case of the bti pass. */
+/* { dg-do run } */
+/* { dg-require-effective-target aarch64_bti_hw } */
+/* { dg-options "--save-temps -mbranch-protection=standard" } */
+
+#include <setjmp.h>
+
+extern void abort (void);
+extern void exit (int);
+
+static jmp_buf env;
+
+void baz (void)
+{
+ __asm__ volatile ("" : : : "memory");
+}
+
+static inline int g(int x)
+{
+ if (x)
+ {
+ baz();
+ return 0;
+ }
+ else
+ {
+ baz();
+ return 1;
+ }
+}
+
+int f(int *e)
+{
+ if (*e)
+ return 1;
+
+ int x = setjmp(env);
+ int n = g(x);
+ if (n == 0)
+ exit(0);
+ if (x)
+ abort();
+ longjmp(env, 42);
+}
+/* { dg-final { scan-assembler "hint\t36" } } */
+
+int main(int argc, char** argv)
+{
+ int v = 0;
+ return f(&v);
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 5026c5906cda3f2f1b21afbc9cd270aee1a81129..85b3b83776e2f8966a0ba3c6d1903bbd4995de52 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -4313,6 +4313,22 @@ proc check_effective_target_arm_neonv2_hw { } {
} [add_options_for_arm_neonv2 ""]]
}
+# ID_AA64PFR1_EL1.BT using bits[3:0] == 1 implies BTI implimented.
+proc check_effective_target_aarch64_bti_hw { } {
+ if { ![istarget aarch64*-*-*] } {
+ return 0
+ }
+ return [check_runtime aarch64_bti_hw_available {
+ int
+ main (void)
+ {
+ int a;
+ asm volatile ("mrs %0, id_aa64pfr1_el1" : "=r" (a));
+ return !((a & 0xf) == 1);
+ }
+ } "-O2" ]
+}
+
# Return 1 if the target supports the ARMv8.1 Adv.SIMD extension, 0
# otherwise. The test is valid for AArch64 and ARM. Record the command
# line options needed.
next prev parent reply other threads:[~2018-12-14 16:09 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-02 18:38 Sudakshina Das
2018-11-13 14:47 ` Sudakshina Das
2018-11-29 16:50 ` Sudakshina Das
2018-12-14 16:09 ` Sudakshina Das [this message]
2018-12-19 15:41 ` James Greenhalgh
2018-12-20 16:44 ` Sudakshina Das
2019-01-09 14:42 ` Sudakshina Das
2019-01-10 15:46 ` Christophe Lyon
2019-01-10 16:55 ` Sudakshina Das
2022-08-18 0:00 ` Andrew Pinski
2022-08-18 10:10 ` Richard Earnshaw
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ba3e4346-2bae-c23f-ec53-a3669754c49a@arm.com \
--to=sudi.das@arm.com \
--cc=James.Greenhalgh@arm.com \
--cc=Marcus.Shawcroft@arm.com \
--cc=Richard.Earnshaw@arm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=nd@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).