mirror of git://gcc.gnu.org/git/gcc.git
[AArch64, 5/6] Enable BTI : Add new pass for BTI.
This patch is part of a series that enables ARMv8.5-A in GCC and
adds Branch Target Identification Mechanism.
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". 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).
*** gcc/ChangeLog ***
2018-01-09 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-01-09 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.
Co-Authored-By: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
From-SVN: r267769
This commit is contained in:
parent
30afdf34a6
commit
b5f794b47b
|
|
@ -1,3 +1,20 @@
|
||||||
|
2018-01-09 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.
|
||||||
|
|
||||||
2018-01-09 Sudakshina Das <sudi.das@arm.com>
|
2018-01-09 Sudakshina Das <sudi.das@arm.com>
|
||||||
|
|
||||||
* config/aarch64/aarch64-protos.h (aarch64_bti_enabled): Declare.
|
* config/aarch64/aarch64-protos.h (aarch64_bti_enabled): Declare.
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ aarch64*-*-*)
|
||||||
c_target_objs="aarch64-c.o"
|
c_target_objs="aarch64-c.o"
|
||||||
cxx_target_objs="aarch64-c.o"
|
cxx_target_objs="aarch64-c.o"
|
||||||
d_target_objs="aarch64-d.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_gtfiles="\$(srcdir)/config/aarch64/aarch64-builtins.c"
|
||||||
target_has_targetm_common=yes
|
target_has_targetm_common=yes
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,235 @@
|
||||||
|
/* Branch Target Identification for AArch64 architecture.
|
||||||
|
Copyright (C) 2019 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_PACISP:
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -21,3 +21,4 @@
|
||||||
INSERT_PASS_AFTER (pass_regrename, 1, pass_fma_steering);
|
INSERT_PASS_AFTER (pass_regrename, 1, pass_fma_steering);
|
||||||
INSERT_PASS_BEFORE (pass_reorder_blocks, 1, pass_track_speculation);
|
INSERT_PASS_BEFORE (pass_reorder_blocks, 1, pass_track_speculation);
|
||||||
INSERT_PASS_AFTER (pass_machine_reorg, 1, pass_tag_collision_avoidance);
|
INSERT_PASS_AFTER (pass_machine_reorg, 1, pass_tag_collision_avoidance);
|
||||||
|
INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_insert_bti);
|
||||||
|
|
|
||||||
|
|
@ -633,6 +633,7 @@ extern void aarch64_d_target_versions (void);
|
||||||
rtl_opt_pass *make_pass_fma_steering (gcc::context *);
|
rtl_opt_pass *make_pass_fma_steering (gcc::context *);
|
||||||
rtl_opt_pass *make_pass_track_speculation (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_tag_collision_avoidance (gcc::context *);
|
||||||
|
rtl_opt_pass *make_pass_insert_bti (gcc::context *ctxt);
|
||||||
|
|
||||||
poly_uint64 aarch64_regmode_natural_size (machine_mode);
|
poly_uint64 aarch64_regmode_natural_size (machine_mode);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8250,18 +8250,36 @@ aarch64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
|
||||||
static void
|
static void
|
||||||
aarch64_asm_trampoline_template (FILE *f)
|
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)
|
if (TARGET_ILP32)
|
||||||
{
|
{
|
||||||
asm_fprintf (f, "\tldr\tw%d, .+16\n", IP1_REGNUM - R0_REGNUM);
|
asm_fprintf (f, "\tldr\tw%d, .+%d\n", IP1_REGNUM - R0_REGNUM, offset1);
|
||||||
asm_fprintf (f, "\tldr\tw%d, .+16\n", STATIC_CHAIN_REGNUM - R0_REGNUM);
|
asm_fprintf (f, "\tldr\tw%d, .+%d\n", STATIC_CHAIN_REGNUM - R0_REGNUM,
|
||||||
|
offset1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
asm_fprintf (f, "\tldr\t%s, .+16\n", reg_names [IP1_REGNUM]);
|
asm_fprintf (f, "\tldr\t%s, .+%d\n", reg_names [IP1_REGNUM], offset1);
|
||||||
asm_fprintf (f, "\tldr\t%s, .+20\n", reg_names [STATIC_CHAIN_REGNUM]);
|
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]);
|
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);
|
||||||
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
|
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -918,7 +918,7 @@ typedef struct
|
||||||
|
|
||||||
#define RETURN_ADDR_RTX aarch64_return_addr
|
#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)
|
#define TRAMPOLINE_SIZE (TARGET_ILP32 ? 24 : 32)
|
||||||
|
|
||||||
/* Trampolines contain dwords, so must be dword aligned. */
|
/* Trampolines contain dwords, so must be dword aligned. */
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,10 @@
|
||||||
UNSPECV_BLOCKAGE ; Represent a blockage
|
UNSPECV_BLOCKAGE ; Represent a blockage
|
||||||
UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing.
|
UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing.
|
||||||
UNSPECV_SPECULATION_BARRIER ; Represent speculation barrier.
|
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.
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -6939,6 +6943,35 @@
|
||||||
[(set_attr "type" "csel")]
|
[(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.
|
;; Helper for aarch64.c code.
|
||||||
(define_expand "set_clobber_cc"
|
(define_expand "set_clobber_cc"
|
||||||
[(parallel [(set (match_operand 0)
|
[(parallel [(set (match_operand 0)
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,15 @@ falkor-tag-collision-avoidance.o: \
|
||||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
|
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
|
||||||
$(srcdir)/config/aarch64/falkor-tag-collision-avoidance.c
|
$(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=,
|
comma=,
|
||||||
MULTILIB_OPTIONS = $(subst $(comma),/, $(patsubst %, mabi=%, $(subst $(comma),$(comma)mabi=,$(TM_MULTILIB_CONFIG))))
|
MULTILIB_OPTIONS = $(subst $(comma),/, $(patsubst %, mabi=%, $(subst $(comma),$(comma)mabi=,$(TM_MULTILIB_CONFIG))))
|
||||||
MULTILIB_DIRNAMES = $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
|
MULTILIB_DIRNAMES = $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
2018-01-09 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.
|
||||||
|
|
||||||
2018-01-09 Sudakshina Das <sudi.das@arm.com>
|
2018-01-09 Sudakshina Das <sudi.das@arm.com>
|
||||||
|
|
||||||
* gcc.target/aarch64/test_frame_17.c: Update to check for EP0_REGNUM
|
* gcc.target/aarch64/test_frame_17.c: Update to check for EP0_REGNUM
|
||||||
|
|
|
||||||
|
|
@ -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 } } */
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -4313,6 +4313,22 @@ proc check_effective_target_arm_neonv2_hw { } {
|
||||||
} [add_options_for_arm_neonv2 ""]]
|
} [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
|
# 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
|
# otherwise. The test is valid for AArch64 and ARM. Record the command
|
||||||
# line options needed.
|
# line options needed.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue