i386: Add __x86_indirect_thunk_nt_reg for -fcf-protection -mcet
nocf_check attribute can be used with -fcf-protection -mcet to disable control-flow check by adding NOTRACK prefix before indirect branch. When -mindirect-branch=thunk-extern -mindirect-branch-register is added, indirect branch via register, "notrack call/jmp reg", is converted to call/jmp __x86_indirect_thunk_nt_reg When running on machines with CET enabled, __x86_indirect_thunk_nt_reg can be updated to notrack jmp reg at run-time to restore NOTRACK prefix in the original indirect branch. Since we don't support -mindirect-branch=thunk-extern, CET and MPX at the same time, -mindirect-branch=thunk-extern is disallowed with -fcf-protection=branch and -fcheck-pointer-bounds. Tested on i686 and x86-64. gcc/ PR target/84176 * config/i386/i386.c (ix86_set_indirect_branch_type): Issue an error when -mindirect-branch=thunk-extern, -fcf-protection=branch and -fcheck-pointer-bounds are used together. (indirect_thunk_prefix): New enum. (indirect_thunk_need_prefix): New function. (indirect_thunk_name): Replace need_bnd_p with need_prefix. Use "_nt" instead of "_bnd" for NOTRACK prefix. (output_indirect_thunk): Replace need_bnd_p with need_prefix. (output_indirect_thunk_function): Likewise. (): Likewise. (ix86_code_end): Update output_indirect_thunk_function calls. (ix86_output_indirect_branch_via_reg): Replace ix86_bnd_prefixed_insn_p with indirect_thunk_need_prefix. (ix86_output_indirect_branch_via_push): Likewise. (ix86_output_function_return): Likewise. * doc/invoke.texi: Document -mindirect-branch=thunk-extern is incompatible with -fcf-protection=branch and -fcheck-pointer-bounds. gcc/testsuite/ PR target/84176 * gcc.target/i386/indirect-thunk-11.c: New test. * gcc.target/i386/indirect-thunk-12.c: Likewise. * gcc.target/i386/indirect-thunk-attr-12.c: Likewise. * gcc.target/i386/indirect-thunk-attr-13.c: Likewise. * gcc.target/i386/indirect-thunk-attr-14.c: Likewise. * gcc.target/i386/indirect-thunk-attr-15.c: Likewise. * gcc.target/i386/indirect-thunk-attr-16.c: Likewise. * gcc.target/i386/indirect-thunk-extern-10.c: Likewise. * gcc.target/i386/indirect-thunk-extern-8.c: Likewise. * gcc.target/i386/indirect-thunk-extern-9.c: Likewise. From-SVN: r257909
This commit is contained in:
parent
eae52f300e
commit
73b8b82295
14 changed files with 258 additions and 43 deletions
|
@ -1,3 +1,25 @@
|
|||
2018-02-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/84176
|
||||
* config/i386/i386.c (ix86_set_indirect_branch_type): Issue an
|
||||
error when -mindirect-branch=thunk-extern, -fcf-protection=branch
|
||||
and -fcheck-pointer-bounds are used together.
|
||||
(indirect_thunk_prefix): New enum.
|
||||
(indirect_thunk_need_prefix): New function.
|
||||
(indirect_thunk_name): Replace need_bnd_p with need_prefix. Use
|
||||
"_nt" instead of "_bnd" for NOTRACK prefix.
|
||||
(output_indirect_thunk): Replace need_bnd_p with need_prefix.
|
||||
(output_indirect_thunk_function): Likewise.
|
||||
(): Likewise.
|
||||
(ix86_code_end): Update output_indirect_thunk_function calls.
|
||||
(ix86_output_indirect_branch_via_reg): Replace
|
||||
ix86_bnd_prefixed_insn_p with indirect_thunk_need_prefix.
|
||||
(ix86_output_indirect_branch_via_push): Likewise.
|
||||
(ix86_output_function_return): Likewise.
|
||||
* doc/invoke.texi: Document -mindirect-branch=thunk-extern is
|
||||
incompatible with -fcf-protection=branch and
|
||||
-fcheck-pointer-bounds.
|
||||
|
||||
2018-02-22 Steve Ellcey <sellcey@cavium.com>
|
||||
|
||||
PR target/83335
|
||||
|
|
|
@ -5898,6 +5898,16 @@ ix86_set_indirect_branch_type (tree fndecl)
|
|||
((cfun->machine->indirect_branch_type
|
||||
== indirect_branch_thunk_extern)
|
||||
? "thunk-extern" : "thunk"));
|
||||
|
||||
/* -mindirect-branch=thunk-extern, -fcf-protection=branch and
|
||||
-fcheck-pointer-bounds are not compatible. */
|
||||
if ((cfun->machine->indirect_branch_type
|
||||
== indirect_branch_thunk_extern)
|
||||
&& flag_check_pointer_bounds
|
||||
&& (flag_cf_protection & CF_BRANCH) != 0)
|
||||
error ("%<-mindirect-branch=thunk-extern%>, "
|
||||
"%<-fcf-protection=branch%> and "
|
||||
"%<-fcheck-pointer-bounds%> are not compatible");
|
||||
}
|
||||
|
||||
if (cfun->machine->function_return_type == indirect_branch_unset)
|
||||
|
@ -10806,18 +10816,62 @@ static int indirect_thunks_bnd_used;
|
|||
# define INDIRECT_LABEL "LIND"
|
||||
#endif
|
||||
|
||||
/* Indicate what prefix is needed for an indirect branch. */
|
||||
enum indirect_thunk_prefix
|
||||
{
|
||||
indirect_thunk_prefix_none,
|
||||
indirect_thunk_prefix_bnd,
|
||||
indirect_thunk_prefix_nt
|
||||
};
|
||||
|
||||
/* Return the prefix needed for an indirect branch INSN. */
|
||||
|
||||
enum indirect_thunk_prefix
|
||||
indirect_thunk_need_prefix (rtx_insn *insn)
|
||||
{
|
||||
enum indirect_thunk_prefix need_prefix;
|
||||
if (ix86_bnd_prefixed_insn_p (insn))
|
||||
need_prefix = indirect_thunk_prefix_bnd;
|
||||
else if ((cfun->machine->indirect_branch_type
|
||||
== indirect_branch_thunk_extern)
|
||||
&& ix86_notrack_prefixed_insn_p (insn))
|
||||
{
|
||||
/* NOTRACK prefix is only used with external thunk so that it
|
||||
can be properly updated to support CET at run-time. */
|
||||
need_prefix = indirect_thunk_prefix_nt;
|
||||
}
|
||||
else
|
||||
need_prefix = indirect_thunk_prefix_none;
|
||||
return need_prefix;
|
||||
}
|
||||
|
||||
/* Fills in the label name that should be used for the indirect thunk. */
|
||||
|
||||
static void
|
||||
indirect_thunk_name (char name[32], unsigned int regno,
|
||||
bool need_bnd_p, bool ret_p)
|
||||
enum indirect_thunk_prefix need_prefix,
|
||||
bool ret_p)
|
||||
{
|
||||
if (regno != INVALID_REGNUM && ret_p)
|
||||
gcc_unreachable ();
|
||||
|
||||
if (USE_HIDDEN_LINKONCE)
|
||||
{
|
||||
const char *bnd = need_bnd_p ? "_bnd" : "";
|
||||
const char *prefix;
|
||||
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
prefix = "_bnd";
|
||||
else if (need_prefix == indirect_thunk_prefix_nt
|
||||
&& regno != INVALID_REGNUM)
|
||||
{
|
||||
/* NOTRACK prefix is only used with external thunk via
|
||||
register so that NOTRACK prefix can be added to indirect
|
||||
branch via register to support CET at run-time. */
|
||||
prefix = "_nt";
|
||||
}
|
||||
else
|
||||
prefix = "";
|
||||
|
||||
if (regno != INVALID_REGNUM)
|
||||
{
|
||||
const char *reg_prefix;
|
||||
|
@ -10826,19 +10880,19 @@ indirect_thunk_name (char name[32], unsigned int regno,
|
|||
else
|
||||
reg_prefix = "";
|
||||
sprintf (name, "__x86_indirect_thunk%s_%s%s",
|
||||
bnd, reg_prefix, reg_names[regno]);
|
||||
prefix, reg_prefix, reg_names[regno]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *ret = ret_p ? "return" : "indirect";
|
||||
sprintf (name, "__x86_%s_thunk%s", ret, bnd);
|
||||
sprintf (name, "__x86_%s_thunk%s", ret, prefix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (regno != INVALID_REGNUM)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno);
|
||||
else
|
||||
ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
|
||||
|
@ -10847,14 +10901,14 @@ indirect_thunk_name (char name[32], unsigned int regno,
|
|||
{
|
||||
if (ret_p)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0);
|
||||
else
|
||||
ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0);
|
||||
else
|
||||
ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
|
||||
|
@ -10890,7 +10944,8 @@ indirect_thunk_name (char name[32], unsigned int regno,
|
|||
*/
|
||||
|
||||
static void
|
||||
output_indirect_thunk (bool need_bnd_p, unsigned int regno)
|
||||
output_indirect_thunk (enum indirect_thunk_prefix need_prefix,
|
||||
unsigned int regno)
|
||||
{
|
||||
char indirectlabel1[32];
|
||||
char indirectlabel2[32];
|
||||
|
@ -10901,7 +10956,7 @@ output_indirect_thunk (bool need_bnd_p, unsigned int regno)
|
|||
indirectlabelno++);
|
||||
|
||||
/* Call */
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fputs ("\tbnd call\t", asm_out_file);
|
||||
else
|
||||
fputs ("\tcall\t", asm_out_file);
|
||||
|
@ -10938,7 +10993,7 @@ output_indirect_thunk (bool need_bnd_p, unsigned int regno)
|
|||
output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
|
||||
}
|
||||
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fputs ("\tbnd ret\n", asm_out_file);
|
||||
else
|
||||
fputs ("\tret\n", asm_out_file);
|
||||
|
@ -10950,13 +11005,14 @@ output_indirect_thunk (bool need_bnd_p, unsigned int regno)
|
|||
on the top of stack. */
|
||||
|
||||
static void
|
||||
output_indirect_thunk_function (bool need_bnd_p, unsigned int regno)
|
||||
output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
|
||||
unsigned int regno)
|
||||
{
|
||||
char name[32];
|
||||
tree decl;
|
||||
|
||||
/* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */
|
||||
indirect_thunk_name (name, regno, need_bnd_p, false);
|
||||
indirect_thunk_name (name, regno, need_prefix, false);
|
||||
decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
|
||||
get_identifier (name),
|
||||
build_function_type_list (void_type_node, NULL_TREE));
|
||||
|
@ -11004,7 +11060,7 @@ output_indirect_thunk_function (bool need_bnd_p, unsigned int regno)
|
|||
/* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */
|
||||
char alias[32];
|
||||
|
||||
indirect_thunk_name (alias, regno, need_bnd_p, true);
|
||||
indirect_thunk_name (alias, regno, need_prefix, true);
|
||||
#if TARGET_MACHO
|
||||
if (TARGET_MACHO)
|
||||
{
|
||||
|
@ -11040,7 +11096,7 @@ output_indirect_thunk_function (bool need_bnd_p, unsigned int regno)
|
|||
/* Make sure unwind info is emitted for the thunk if needed. */
|
||||
final_start_function (emit_barrier (), asm_out_file, 1);
|
||||
|
||||
output_indirect_thunk (need_bnd_p, regno);
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
|
||||
final_end_function ();
|
||||
init_insn_lengths ();
|
||||
|
@ -11076,18 +11132,22 @@ ix86_code_end (void)
|
|||
unsigned int regno;
|
||||
|
||||
if (indirect_thunk_needed)
|
||||
output_indirect_thunk_function (false, INVALID_REGNUM);
|
||||
output_indirect_thunk_function (indirect_thunk_prefix_none,
|
||||
INVALID_REGNUM);
|
||||
if (indirect_thunk_bnd_needed)
|
||||
output_indirect_thunk_function (true, INVALID_REGNUM);
|
||||
output_indirect_thunk_function (indirect_thunk_prefix_bnd,
|
||||
INVALID_REGNUM);
|
||||
|
||||
for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
|
||||
{
|
||||
unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1;
|
||||
if ((indirect_thunks_used & (1 << i)))
|
||||
output_indirect_thunk_function (false, regno);
|
||||
output_indirect_thunk_function (indirect_thunk_prefix_none,
|
||||
regno);
|
||||
|
||||
if ((indirect_thunks_bnd_used & (1 << i)))
|
||||
output_indirect_thunk_function (true, regno);
|
||||
output_indirect_thunk_function (indirect_thunk_prefix_bnd,
|
||||
regno);
|
||||
}
|
||||
|
||||
for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
|
||||
|
@ -11096,10 +11156,12 @@ ix86_code_end (void)
|
|||
tree decl;
|
||||
|
||||
if ((indirect_thunks_used & (1 << regno)))
|
||||
output_indirect_thunk_function (false, regno);
|
||||
output_indirect_thunk_function (indirect_thunk_prefix_none,
|
||||
regno);
|
||||
|
||||
if ((indirect_thunks_bnd_used & (1 << regno)))
|
||||
output_indirect_thunk_function (true, regno);
|
||||
output_indirect_thunk_function (indirect_thunk_prefix_bnd,
|
||||
regno);
|
||||
|
||||
if (!(pic_labels_used & (1 << regno)))
|
||||
continue;
|
||||
|
@ -28676,7 +28738,8 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
|
|||
{
|
||||
char thunk_name_buf[32];
|
||||
char *thunk_name;
|
||||
bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
|
||||
enum indirect_thunk_prefix need_prefix
|
||||
= indirect_thunk_need_prefix (current_output_insn);
|
||||
int regno = REGNO (call_op);
|
||||
|
||||
if (cfun->machine->indirect_branch_type
|
||||
|
@ -28687,12 +28750,12 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
|
|||
int i = regno;
|
||||
if (i >= FIRST_REX_INT_REG)
|
||||
i -= (FIRST_REX_INT_REG - LAST_INT_REG - 1);
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
indirect_thunks_bnd_used |= 1 << i;
|
||||
else
|
||||
indirect_thunks_used |= 1 << i;
|
||||
}
|
||||
indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);
|
||||
indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
|
||||
thunk_name = thunk_name_buf;
|
||||
}
|
||||
else
|
||||
|
@ -28702,19 +28765,19 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
|
|||
{
|
||||
if (thunk_name != NULL)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
|
||||
else
|
||||
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_bnd_p, regno);
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thunk_name != NULL)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name);
|
||||
else
|
||||
fprintf (asm_out_file, "\tcall\t%s\n", thunk_name);
|
||||
|
@ -28732,7 +28795,7 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
|
|||
indirectlabelno++);
|
||||
|
||||
/* Jump. */
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fputs ("\tbnd jmp\t", asm_out_file);
|
||||
else
|
||||
fputs ("\tjmp\t", asm_out_file);
|
||||
|
@ -28743,18 +28806,18 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
|
|||
|
||||
if (thunk_name != NULL)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
|
||||
else
|
||||
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_bnd_p, regno);
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
|
||||
|
||||
/* Call. */
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fputs ("\tbnd call\t", asm_out_file);
|
||||
else
|
||||
fputs ("\tcall\t", asm_out_file);
|
||||
|
@ -28788,7 +28851,8 @@ ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
|
|||
char thunk_name_buf[32];
|
||||
char *thunk_name;
|
||||
char push_buf[64];
|
||||
bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
|
||||
enum indirect_thunk_prefix need_prefix
|
||||
= indirect_thunk_need_prefix (current_output_insn);
|
||||
int regno = -1;
|
||||
|
||||
if (cfun->machine->indirect_branch_type
|
||||
|
@ -28796,12 +28860,12 @@ ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
|
|||
{
|
||||
if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
indirect_thunk_bnd_needed = true;
|
||||
else
|
||||
indirect_thunk_needed = true;
|
||||
}
|
||||
indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false);
|
||||
indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
|
||||
thunk_name = thunk_name_buf;
|
||||
}
|
||||
else
|
||||
|
@ -28815,13 +28879,13 @@ ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
|
|||
output_asm_insn (push_buf, &call_op);
|
||||
if (thunk_name != NULL)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
|
||||
else
|
||||
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_bnd_p, regno);
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -28836,7 +28900,7 @@ ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
|
|||
indirectlabelno++);
|
||||
|
||||
/* Jump. */
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fputs ("\tbnd jmp\t", asm_out_file);
|
||||
else
|
||||
fputs ("\tjmp\t", asm_out_file);
|
||||
|
@ -28882,18 +28946,18 @@ ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
|
|||
|
||||
if (thunk_name != NULL)
|
||||
{
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
|
||||
else
|
||||
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_bnd_p, regno);
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
|
||||
|
||||
/* Call. */
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fputs ("\tbnd call\t", asm_out_file);
|
||||
else
|
||||
fputs ("\tcall\t", asm_out_file);
|
||||
|
@ -28945,16 +29009,17 @@ ix86_output_function_return (bool long_p)
|
|||
if (cfun->machine->function_return_type != indirect_branch_keep)
|
||||
{
|
||||
char thunk_name[32];
|
||||
bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn);
|
||||
enum indirect_thunk_prefix need_prefix
|
||||
= indirect_thunk_need_prefix (current_output_insn);
|
||||
|
||||
if (cfun->machine->function_return_type
|
||||
!= indirect_branch_thunk_inline)
|
||||
{
|
||||
bool need_thunk = (cfun->machine->function_return_type
|
||||
== indirect_branch_thunk);
|
||||
indirect_thunk_name (thunk_name, INVALID_REGNUM, need_bnd_p,
|
||||
indirect_thunk_name (thunk_name, INVALID_REGNUM, need_prefix,
|
||||
true);
|
||||
if (need_bnd_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
{
|
||||
indirect_thunk_bnd_needed |= need_thunk;
|
||||
fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
|
||||
|
@ -28966,7 +29031,7 @@ ix86_output_function_return (bool long_p)
|
|||
}
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_bnd_p, INVALID_REGNUM);
|
||||
output_indirect_thunk (need_prefix, INVALID_REGNUM);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -27837,6 +27837,11 @@ Note that @option{-mcmodel=large} is incompatible with
|
|||
@option{-mindirect-branch=thunk-extern} since the thunk function may
|
||||
not be reachable in large code model.
|
||||
|
||||
Note that @option{-mindirect-branch=thunk-extern} is incompatible with
|
||||
@option{-fcf-protection=branch} and @option{-fcheck-pointer-bounds}
|
||||
since the external thunk can not be modified to disable control-flow
|
||||
check.
|
||||
|
||||
@item -mfunction-return=@var{choice}
|
||||
@opindex -mfunction-return
|
||||
Convert function return with @var{choice}. The default is @samp{keep},
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
2018-02-22 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/84176
|
||||
* gcc.target/i386/indirect-thunk-11.c: New test.
|
||||
* gcc.target/i386/indirect-thunk-12.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-attr-12.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-attr-13.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-attr-14.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-attr-15.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-attr-16.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-extern-10.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-extern-8.c: Likewise.
|
||||
* gcc.target/i386/indirect-thunk-extern-9.c: Likewise.
|
||||
|
||||
2018-02-22 Steve Ellcey <sellcey@cavium.com>
|
||||
|
||||
PR target/83335
|
||||
|
|
7
gcc/testsuite/gcc.target/i386/indirect-thunk-11.c
Normal file
7
gcc/testsuite/gcc.target/i386/indirect-thunk-11.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* { dg-do compile { target { ! x32 } } } */
|
||||
/* { dg-options "-O2 -mindirect-branch=thunk-extern -fcf-protection -mcet -fcheck-pointer-bounds -mmpx" } */
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{ /* { dg-error "'-mindirect-branch=thunk-extern', '-fcf-protection=branch' and '-fcheck-pointer-bounds' are not compatible" } */
|
||||
}
|
7
gcc/testsuite/gcc.target/i386/indirect-thunk-12.c
Normal file
7
gcc/testsuite/gcc.target/i386/indirect-thunk-12.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* { dg-do compile { target { ! x32 } } } */
|
||||
/* { dg-options "-O2 -mindirect-branch=thunk -fcf-protection -mcet -fcheck-pointer-bounds -mmpx" } */
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
}
|
8
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-12.c
Normal file
8
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-12.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* { dg-do compile { target { ! x32 } } } */
|
||||
/* { dg-options "-O2 -mindirect-branch=keep -fcf-protection -mcet -fcheck-pointer-bounds -mmpx" } */
|
||||
|
||||
__attribute__ ((indirect_branch("thunk-extern")))
|
||||
void
|
||||
bar (void)
|
||||
{ /* { dg-error "'-mindirect-branch=thunk-extern', '-fcf-protection=branch' and '-fcheck-pointer-bounds' are not compatible" } */
|
||||
}
|
8
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-13.c
Normal file
8
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-13.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* { dg-do compile { target { ! x32 } } } */
|
||||
/* { dg-options "-O2 -mindirect-branch=keep -fcf-protection -mcet -fcheck-pointer-bounds -mmpx" } */
|
||||
|
||||
__attribute__ ((indirect_branch("thunk-inline")))
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
}
|
14
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-14.c
Normal file
14
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-14.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile { target *-*-linux* } } */
|
||||
/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic -fplt -mindirect-branch=keep -fcf-protection -mcet" } */
|
||||
|
||||
extern void (*bar) (void);
|
||||
|
||||
__attribute__ ((indirect_branch("thunk-extern")))
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
|
||||
/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk_nt" } } */
|
14
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-15.c
Normal file
14
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-15.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile { target *-*-linux* } } */
|
||||
/* { dg-options "-O2 -mindirect-branch-register -mfunction-return=keep -fno-pic -fplt -mindirect-branch=keep -fcf-protection -mcet" } */
|
||||
|
||||
extern void (*bar) (void);
|
||||
|
||||
__attribute__ ((indirect_branch("thunk-extern")))
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
|
||||
/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk_nt" } } */
|
13
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-16.c
Normal file
13
gcc/testsuite/gcc.target/i386/indirect-thunk-attr-16.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile { target *-*-linux* } } */
|
||||
/* { dg-options "-O2 -mindirect-branch-register -mfunction-return=keep -fno-pic -fplt -mindirect-branch=keep -fcf-protection -mcet" } */
|
||||
|
||||
extern void (*bar) (void) __attribute__((nocf_check));
|
||||
|
||||
__attribute__ ((indirect_branch("thunk-extern")))
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_nt_(r|e)" } } */
|
12
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-10.c
Normal file
12
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-10.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile { target *-*-linux* } } */
|
||||
/* { dg-options "-O2 -mindirect-branch-register -mfunction-return=keep -fno-pic -fplt -mindirect-branch=thunk-extern -fcf-protection -mcet" } */
|
||||
|
||||
extern void (*bar) (void) __attribute__((nocf_check));
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_nt_(r|e)" } } */
|
13
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-8.c
Normal file
13
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-8.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile { target *-*-linux* } } */
|
||||
/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic -fplt -mindirect-branch=thunk-extern -fcf-protection -mcet" } */
|
||||
|
||||
extern void (*bar) (void);
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
|
||||
/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk_nt" } } */
|
13
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-9.c
Normal file
13
gcc/testsuite/gcc.target/i386/indirect-thunk-extern-9.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile { target *-*-linux* } } */
|
||||
/* { dg-options "-O2 -mindirect-branch-register -mfunction-return=keep -fno-pic -fplt -mindirect-branch=thunk-extern -fcf-protection -mcet" } */
|
||||
|
||||
extern void (*bar) (void);
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
|
||||
/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk_nt" } } */
|
Loading…
Add table
Reference in a new issue