Commit 9ae222ad by Igor Tsimbalist Committed by Igor Tsimbalist

Add x86 tests for Intel CET implementation.

gcc/testsuite/

	* c-c++-common/attr-nocf-check-1.c: Shorten a cheking message.
	* c-c++-common/attr-nocf-check-3.c: Likewise.
	* c-c++-common/fcf-protection-1.c: Add x86 specific message.
	* c-c++-common/fcf-protection-2.c: Likewise.
	* c-c++-common/fcf-protection-3.c: Likewise.
	* c-c++-common/fcf-protection-5.c: Likewise.
	* c-c++-common/attr-nocf-check-1a.c: New test.
	* c-c++-common/attr-nocf-check-3a.c: Likewise.
	* g++.dg/cet-notrack-1.C: Likewise.
	* gcc.target/i386/cet-intrin-1.c: Likewise.
	* gcc.target/i386/cet-intrin-10.c: Likewise.
	* gcc.target/i386/cet-intrin-2.c: Likewise.
	* gcc.target/i386/cet-intrin-3.c: Likewise.
	* gcc.target/i386/cet-intrin-4.c: Likewise.
	* gcc.target/i386/cet-intrin-5.c: Likewise.
	* gcc.target/i386/cet-intrin-6.c: Likewise.
	* gcc.target/i386/cet-intrin-7.c: Likewise.
	* gcc.target/i386/cet-intrin-8.c: Likewise.
	* gcc.target/i386/cet-intrin-9.c: Likewise.
	* gcc.target/i386/cet-label.c: Likewise.
	* gcc.target/i386/cet-notrack-1a.c: Likewise.
	* gcc.target/i386/cet-notrack-1b.c: Likewise.
	* gcc.target/i386/cet-notrack-2a.c: Likewise.
	* gcc.target/i386/cet-notrack-2b.c: Likewise.
	* gcc.target/i386/cet-notrack-3.c: Likewise.
	* gcc.target/i386/cet-notrack-4a.c: Likewise.
	* gcc.target/i386/cet-notrack-4b.c: Likewise.
	* gcc.target/i386/cet-notrack-5a.c: Likewise.
	* gcc.target/i386/cet-notrack-5b.c: Likewise.
	* gcc.target/i386/cet-notrack-6a.c: Likewise.
	* gcc.target/i386/cet-notrack-6b.c: Likewise.
	* gcc.target/i386/cet-notrack-7.c: Likewise.
	* gcc.target/i386/cet-property-1.c: Likewise.
	* gcc.target/i386/cet-property-2.c: Likewise.
	* gcc.target/i386/cet-rdssp-1.c: Likewise.
	* gcc.target/i386/cet-sjlj-1.c: Likewise.
	* gcc.target/i386/cet-sjlj-2.c: Likewise.
	* gcc.target/i386/cet-sjlj-3.c: Likewise.
	* gcc.target/i386/cet-switch-1.c: Likewise.
	* gcc.target/i386/cet-switch-2.c: Likewise.
	* lib/target-supports.exp (check_effective_target_cet): New
	proc.

From-SVN: r253979
parent ccdf009d
2017-10-21 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
* c-c++-common/attr-nocf-check-1.c: Shorten a cheking message.
* c-c++-common/attr-nocf-check-3.c: Likewise.
* c-c++-common/fcf-protection-1.c: Add x86 specific message.
* c-c++-common/fcf-protection-2.c: Likewise.
* c-c++-common/fcf-protection-3.c: Likewise.
* c-c++-common/fcf-protection-5.c: Likewise.
* c-c++-common/attr-nocf-check-1a.c: New test.
* c-c++-common/attr-nocf-check-3a.c: Likewise.
* g++.dg/cet-notrack-1.C: Likewise.
* gcc.target/i386/cet-intrin-1.c: Likewise.
* gcc.target/i386/cet-intrin-10.c: Likewise.
* gcc.target/i386/cet-intrin-2.c: Likewise.
* gcc.target/i386/cet-intrin-3.c: Likewise.
* gcc.target/i386/cet-intrin-4.c: Likewise.
* gcc.target/i386/cet-intrin-5.c: Likewise.
* gcc.target/i386/cet-intrin-6.c: Likewise.
* gcc.target/i386/cet-intrin-7.c: Likewise.
* gcc.target/i386/cet-intrin-8.c: Likewise.
* gcc.target/i386/cet-intrin-9.c: Likewise.
* gcc.target/i386/cet-label.c: Likewise.
* gcc.target/i386/cet-notrack-1a.c: Likewise.
* gcc.target/i386/cet-notrack-1b.c: Likewise.
* gcc.target/i386/cet-notrack-2a.c: Likewise.
* gcc.target/i386/cet-notrack-2b.c: Likewise.
* gcc.target/i386/cet-notrack-3.c: Likewise.
* gcc.target/i386/cet-notrack-4a.c: Likewise.
* gcc.target/i386/cet-notrack-4b.c: Likewise.
* gcc.target/i386/cet-notrack-5a.c: Likewise.
* gcc.target/i386/cet-notrack-5b.c: Likewise.
* gcc.target/i386/cet-notrack-6a.c: Likewise.
* gcc.target/i386/cet-notrack-6b.c: Likewise.
* gcc.target/i386/cet-notrack-7.c: Likewise.
* gcc.target/i386/cet-property-1.c: Likewise.
* gcc.target/i386/cet-property-2.c: Likewise.
* gcc.target/i386/cet-rdssp-1.c: Likewise.
* gcc.target/i386/cet-sjlj-1.c: Likewise.
* gcc.target/i386/cet-sjlj-2.c: Likewise.
* gcc.target/i386/cet-sjlj-3.c: Likewise.
* gcc.target/i386/cet-switch-1.c: Likewise.
* gcc.target/i386/cet-switch-2.c: Likewise.
* lib/target-supports.exp (check_effective_target_cet): New
proc.
2017-10-20 Jan Hubicka <hubicka@ucw.cz>
* gcc.target/i386/pr79683.c: Disable costmodel.
......
/* { dg-do compile } */
int func (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
int (*fptr) (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
typedef void (*nocf_check_t) (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
int func (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
int (*fptr) (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
typedef void (*nocf_check_t) (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
int
foo1 (int arg)
......@@ -13,7 +13,7 @@ foo1 (int arg)
void
foo2 (void (*foo) (void))
{
void (*func) (void) __attribute__((nocf_check)) = foo; /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
void (*func) (void) __attribute__((nocf_check)) = foo; /* { dg-warning "'nocf_check' attribute ignored" } */
func ();
}
......@@ -24,7 +24,7 @@ foo3 (nocf_check_t foo)
}
void
foo4 (void (*foo) (void) __attribute__((nocf_check))) /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
foo4 (void (*foo) (void) __attribute__((nocf_check))) /* { dg-warning "'nocf_check' attribute ignored" } */
{
foo ();
}
/* { dg-do compile } */
/* { dg-options "-fcf-protection -mcet" } */
int func (int) __attribute__ ((nocf_check));
int (*fptr) (int) __attribute__ ((nocf_check));
typedef void (*nocf_check_t) (void) __attribute__ ((nocf_check));
int
foo1 (int arg)
{
return func (arg) + fptr (arg);
}
void
foo2 (void (*foo) (void))
{
void (*func) (void) __attribute__((nocf_check)) = foo; /* { dg-warning "incompatible pointer type" "" { target c } } */
/* { dg-error "invalid conversion" "" { target c++ } .-1 } */
func ();
}
void
foo3 (nocf_check_t foo)
{
foo ();
}
void
foo4 (void (*foo) (void) __attribute__((nocf_check)))
{
foo ();
}
/* { dg-do compile } */
int foo (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
void (*foo1) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
int foo (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
void (*foo1) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
void (*foo2) (void);
int
......
/* { dg-do compile } */
/* { dg-options "-fcf-protection -mcet" } */
int foo (void) __attribute__ ((nocf_check));
void (*foo1) (void) __attribute__((nocf_check));
void (*foo2) (void);
int __attribute__ ((nocf_check))
foo (void) /* The function's address is not tracked. */
{
/* This call site is not tracked for
control-flow instrumentation. */
(*foo1)();
foo1 = foo2; /* { dg-warning "incompatible pointer type" "" { target c } } */
/* { dg-error "invalid conversion" "" { target c++ } .-1 } */
/* This call site is still not tracked for
control-flow instrumentation. */
(*foo1)();
/* This call site is tracked for
control-flow instrumentation. */
(*foo2)();
foo2 = foo1; /* { dg-warning "incompatible pointer type" "" { target c } } */
/* { dg-error "invalid conversion" "" { target c++ } .-1 } */
/* This call site is still tracked for
control-flow instrumentation. */
(*foo2)();
return 0;
}
/* { dg-do compile } */
/* { dg-options "-fcf-protection=full" } */
/* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=full' requires CET support on this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-do compile } */
/* { dg-options "-fcf-protection=branch" } */
/* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=branch' requires CET support on this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-do compile } */
/* { dg-options "-fcf-protection=return" } */
/* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=return' requires CET support on this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-do compile } */
/* { dg-options "-fcf-protection" } */
/* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=full' requires CET support on this target" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-fcf-protection -mcet" } */
/* { dg-final { scan-assembler "endbr32|endbr64" } } */
/* { dg-final { scan-assembler-times "\tcall\[ \t]+puts" 2 } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+" 1 } } */
#include <stdio.h>
struct A {
virtual int foo() __attribute__((nocf_check)) { return 42; }
};
struct B : A {
int foo() __attribute__((nocf_check)) { return 73; }
};
int main() {
B b;
A& a = b;
int (A::*amem) () __attribute__((nocf_check)) = &A::foo; // take address
if ((a.*amem)() == 73) // use the address
printf("pass\n");
else
printf("fail\n");
return 0;
}
/* { dg-do compile } */
/* { dg-options "-O2 -mcet" } */
/* { dg-final { scan-assembler-times "clrssbsy" 1 } } */
#include <immintrin.h>
void f2 (void *__B)
{
_clrssbsy (__B);
}
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 4 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler "rdsspd|incsspd\[ \t]+(%|)eax" { target ia32 } } } */
/* { dg-final { scan-assembler "rdssp\[dq]\[ \t]+(%|)\[re]ax" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler "incssp\[dq]\[ \t]+(%|)\[re]di" { target { ! ia32 } } } } */
#include <immintrin.h>
unsigned int f1 ()
{
unsigned int x = 0;
return _rdsspd (x);
}
void f3 (unsigned int _a)
{
_incsspd (_a);
}
#ifdef __x86_64__
unsigned long long f2 ()
{
unsigned long long x = 0;
return _rdsspq (x);
}
void f4 (unsigned int _a)
{
_incsspq (_a);
}
#endif
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mshstk" } */
/* { dg-final { scan-assembler "rdsspd|incsspd\[ \t]+(%|)eax" { target ia32 } } } */
/* { dg-final { scan-assembler "rdssp\[dq]\[ \t]+(%|)\[re]ax" { target { ! ia32 } } } } */
/* { dg-final { scan-assembler "incssp\[dq]\[ \t]+(%|)\[re]di" { target { ! ia32 } } } } */
#include <immintrin.h>
unsigned int f1 ()
{
unsigned int x = 0;
return _rdsspd (x);
}
void f3 (unsigned int _a)
{
_incsspd (_a);
}
#ifdef __x86_64__
unsigned long long f2 ()
{
unsigned long long x = 0;
return _rdsspq (x);
}
void f4 (unsigned int _a)
{
_incsspq (_a);
}
#endif
/* { dg-do compile } */
/* { dg-options "-O2 -mcet" } */
/* { dg-final { scan-assembler-times "saveprevssp" 1 } } */
#include <immintrin.h>
void f2 (void)
{
_saveprevssp ();
}
/* { dg-do compile } */
/* { dg-options "-O2 -mcet" } */
/* { dg-final { scan-assembler-times "rstorssp" 1 } } */
#include <immintrin.h>
void f2 (void *__B)
{
_rstorssp (__B);
}
/* { dg-do compile } */
/* { dg-options "-O2 -mcet" } */
/* { dg-final { scan-assembler-times "wrssd" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "wrss\[d|q]" 2 { target lp64 } } } */
#include <immintrin.h>
void f1 (unsigned int __A, void *__B)
{
_wrssd (__A, __B);
}
#ifdef __x86_64__
void f2 (unsigned long long __A, void *__B)
{
_wrssq (__A, __B);
}
#endif
/* { dg-do compile } */
/* { dg-options "-O2 -mcet" } */
/* { dg-final { scan-assembler-times "wrussd" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "wruss\[d|q]" 2 { target lp64 } } } */
#include <immintrin.h>
void f1 (unsigned int __A, void *__B)
{
_wrussd (__A, __B);
}
#ifdef __x86_64__
void f2 (unsigned long long __A, void *__B)
{
_wrussq (__A, __B);
}
#endif
/* { dg-do compile } */
/* { dg-options "-O2 -mcet" } */
/* { dg-final { scan-assembler-times "setssbsy" 1 } } */
#include <immintrin.h>
void f2 (void)
{
_setssbsy ();
}
/* Verify that CET works. */
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 3 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 3 { target { ! ia32 } } } } */
int func (int arg)
{
static void *array[] = { &&foo, &&bar };
goto *array[arg];
foo:
return arg*111;
bar:
return arg*777;
}
/* { dg-do compile } */
/* { dg-options "-O0 -fcf-protection=none -mno-cet" } */
/* { dg-final { scan-assembler-not "endbr" } } */
/* { dg-final { scan-assembler-not "notrack call\[ \t]+" } } */
int func (int a) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
int (*fptr) (int a) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
int foo (int arg)
{
int a, b;
a = func (arg);
b = (*fptr) (arg);
return a+b;
}
int __attribute__ ((nocf_check))
func (int arg)
{ /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
int (*fptrl) (int a) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
return arg*(*fptrl)(arg);
}
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+" 2 } } */
int func (int a) __attribute__ ((nocf_check));
int (*fptr) (int a) __attribute__ ((nocf_check));
int foo (int arg)
{
int a, b;
a = func (arg);
b = (*fptr) (arg);
return a+b;
}
int __attribute__ ((nocf_check))
func (int arg)
{
int (*fptrl) (int a) __attribute__ ((nocf_check));
return arg*(*fptrl)(arg);
}
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+" 1 } } */
void
bar (void (*foo) (void))
{
void (*func) (void) __attribute__((nocf_check)) = foo; /* { dg-warning "incompatible pointer type" } */
func ();
}
/* { dg-do compile } */
/* { dg-options "-O2 -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "notrack jmp\[ \t]+" 1 } } */
void
bar (void (*foo) (void))
{
void (*func) (void) __attribute__((nocf_check)) = foo; /* { dg-warning "incompatible pointer type" } */
func ();
}
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+" 1 } } */
typedef void (*func_t) (void) __attribute__((nocf_check));
extern func_t func;
void
bar (void)
{
func ();
}
/* { dg-do compile } */
/* { dg-options "-fcf-protection=none -mno-cet" } */
int var1 __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute only applies to function types" } */
int *var2 __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute only applies to function types" } */
void (**var3) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute only applies to function types" } */
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
int var1 __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute only applies to function types" } */
int *var2 __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute only applies to function types" } */
void (**var3) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute only applies to function types" } */
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-not "\tcall\[ \t]+" } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+" 1 } } */
int (*fptr) (int) __attribute__ ((nocf_check));
int
foo (int arg)
{
int a;
a = (*fptr) (arg); /* notrack call. */
return arg+a;
}
/* Check the attribute do not proparate through assignment. */
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "\tcall\[ \t]+" 1 } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+" 1 } } */
int (*fptr) (int) __attribute__ ((nocf_check));
int (*fptr1) (int);
int
foo (int arg)
{
int a;
a = (*fptr) (arg); /* non-checked call. */
arg += a;
fptr1 = fptr; /* { dg-warning "incompatible pointer type" } */
a = (*fptr1) (arg); /* checked call. */
return arg+a;
}
/* { dg-do compile } */
/* { dg-options "-O2 -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "\t(?:call|jmp)\[ \t]+.*foo" 1 } } */
/* { dg-final { scan-assembler-not "notrack call\[ \t]+" } } */
int foo (int arg);
int func (int arg)
{
int (*fptrl) (int a) __attribute__ ((nocf_check)) = foo; /* { dg-warning "incompatible pointer type" } */
return (*fptrl)(arg);
}
/* { dg-do compile } */
/* { dg-options "-O0 -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-not "\tcall\[ \t]+" } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+" 1 } } */
int foo (int arg);
int func (int arg)
{
int (*fptrl) (int a) __attribute__ ((nocf_check)) = foo; /* { dg-warning "incompatible pointer type" } */
return (*fptrl)(arg); /* notrack call. */
}
/* Check the notrack prefix is not generated for direct call. */
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "notrack call\[ \t]+.*foo" 0 } } */
/* { dg-final { scan-assembler-times "\tcall\[ \t]+.*foo" 1 } } */
extern void foo (void) __attribute__((nocf_check));
void
bar (void)
{
foo ();
}
/* Verify nocf_check functions are not ICF optimized. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "endbr" } } */
/* { dg-final { scan-assembler-not "fn3:" } } */
/* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
/* { dg-final { scan-assembler "set\[ \t]+fn3,fn1" } } */
static __attribute__((noinline)) int
fn1 (int x)
{
return x + 12;
}
static __attribute__((noinline)) int
fn2 (int x)
{
return x + 12;
}
static __attribute__((noinline, nocf_check)) int
fn3 (int x)
{ /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
return x + 12;
}
int
fn4 (int x)
{
return fn1 (x) + fn2 (x) + fn3 (x);
}
/* Verify nocf_check functions are not ICF optimized. */
/* { dg-do compile } */
/* { dg-options "-O2 -fcf-protection -mcet" } */
/* { dg-final { scan-assembler "endbr" } } */
/* { dg-final { scan-assembler "fn3:" } } */
/* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
static __attribute__((noinline)) int
fn1 (int x)
{
return x + 12;
}
static __attribute__((noinline)) int
fn2 (int x)
{
return x + 12;
}
static __attribute__((noinline, nocf_check)) int
fn3 (int x)
{
return x + 12;
}
int
fn4 (int x)
{
return fn1 (x) + fn2 (x) + fn3 (x);
}
/* Verify nocf_check function calls are not ICF optimized. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "endbr" } } */
/* { dg-final { scan-assembler-not "fn2:" } } */
/* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
/* { dg-final { scan-assembler "set\[ \t]+fn3,fn1" } } */
int (*foo)(int);
typedef int (*type1_t) (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored. Use -fcf-protection option to enable it" } */
typedef int (*type2_t) (int);
static __attribute__((noinline)) int
fn1 (int x)
{
return ((type2_t)foo)(x + 12);
}
static __attribute__((noinline)) int
fn2 (int x)
{
return ((type1_t)foo)(x + 12);
}
static __attribute__((noinline)) int
fn3 (int x)
{
return ((type2_t)foo)(x + 12);
}
int
fn4 (int x)
{
return fn1 (x) + fn2 (x) + fn3 (x);
}
/* Verify nocf_check function calls are not ICF optimized. */
/* { dg-do compile } */
/* { dg-options "-O2 -fcf-protection -mcet" } */
/* { dg-final { scan-assembler "endbr" } } */
/* { dg-final { scan-assembler "fn2:" } } */
/* { dg-final { scan-assembler "set\[ \t]+fn3,fn1" } } */
int (*foo)(int);
typedef int (*type1_t) (int) __attribute__ ((nocf_check));
typedef int (*type2_t) (int);
static __attribute__((noinline)) int
fn1 (int x)
{
return ((type2_t)foo)(x + 12);
}
static __attribute__((noinline)) int
fn2 (int x)
{
return ((type1_t)foo)(x + 12);
}
static __attribute__((noinline)) int
fn3 (int x)
{
return ((type2_t)foo)(x + 12);
}
int
fn4 (int x)
{
return fn1 (x) + fn2 (x) + fn3 (x);
}
/* { dg-do compile { target *-*-linux* } } */
/* { dg-options "-fcf-protection -mcet" } */
/* { dg-final { scan-assembler ".note.gnu.property" } } */
extern void foo (void);
void
bar (void)
{
foo ();
}
/* { dg-do compile } */
/* { dg-options "-mcet" } */
/* { dg-final { scan-assembler-not ".note.gnu.property" } } */
extern void foo (void);
void
bar (void)
{
foo ();
}
/* { dg-do run { target cet } } */
/* { dg-options "-O2 -fcf-protection -mcet" } */
void _exit(int status) __attribute__ ((__noreturn__));
#ifdef __x86_64__
# define incssp(x) __builtin_ia32_incsspq (x)
# define rdssp(x) __builtin_ia32_rdsspq (x)
#else
# define incssp(x) __builtin_ia32_incsspd (x)
# define rdssp(x) __builtin_ia32_rdsspd (x)
#endif
static void
__attribute__ ((noinline, noclone))
test (unsigned long frames)
{
unsigned long ssp = 0;
ssp = rdssp (ssp);
if (ssp != 0)
{
unsigned long tmp = frames;
while (tmp > 255)
{
incssp (tmp);
tmp -= 255;
}
incssp (tmp);
}
/* We must call _exit since shadow stack is incorrect now. */
_exit (0);
}
int
main ()
{
test (1);
return 0;
}
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 4 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 4 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "rdssp\[dq]" 2 } } */
/* { dg-final { scan-assembler-times "incssp\[dq]" 1 } } */
/* Based on gcc.dg/setjmp-3.c. */
void *buf[5];
extern void abort (void);
void raise0(void)
{
__builtin_longjmp (buf, 1);
}
int execute(int cmd)
{
int last = 0;
if (__builtin_setjmp (buf) == 0)
while (1)
{
last = 1;
raise0 ();
}
if (last == 0)
return 0;
else
return cmd;
}
int main(void)
{
if (execute (1) == 0)
abort ();
return 0;
}
/* { dg-do run { target cet } } */
/* { dg-options "-O -fcf-protection -mcet" } */
#include "cet-sjlj-1.c"
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 4 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 4 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "call _setjmp" 1 } } */
/* { dg-final { scan-assembler-times "call longjmp" 1 } } */
#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
int bar (int);
int
foo (int i)
{
int j = i * 11;
if (!setjmp (buf))
{
j += 33;
printf ("After setjmp: j = %d\n", j);
bar (j);
}
return j + i;
}
int
bar (int i)
{
int j = i;
j -= 111;
printf ("In longjmp: j = %d\n", j);
longjmp (buf, 1);
return j;
}
int
main ()
{
foo (10);
return 0;
}
/* Verify that CET works. */
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "notrack jmp\[ \t]+\[*]" 1 } } */
void func2 (int);
int func1 (int arg)
{
switch (arg)
{
case 1: func2 (arg*100);
case 2: func2 (arg*300);
case 5: func2 (arg*500);
case 8: func2 (arg*700);
case 7: func2 (arg*900);
case -1: func2 (arg*-100);
case -2: func2 (arg*-300);
case -5: func2 (arg*-500);
case -7: func2 (arg*-700);
case -9: func2 (arg*-900);
}
return 0;
}
/* Verify that CET works. */
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet -mcet-switch" } */
/* { dg-final { scan-assembler-times "endbr32" 12 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 12 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "\[ \t]+jmp\[ \t]+\[*]" 1 } } */
void func2 (int);
int func1 (int arg)
{
switch (arg)
{
case 1: func2 (arg*100);
case 2: func2 (arg*300);
case 5: func2 (arg*500);
case 8: func2 (arg*700);
case 7: func2 (arg*900);
case -1: func2 (arg*-100);
case -2: func2 (arg*-300);
case -5: func2 (arg*-500);
case -7: func2 (arg*-700);
case -9: func2 (arg*-900);
}
return 0;
}
......@@ -8923,3 +8923,16 @@ proc check_effective_target_callee_realigns_stack { } {
}
return 0
}
# Return 1 if CET instructions can be compiled.
proc check_effective_target_cet { } {
if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } {
return 0
}
return [check_no_compiler_messages cet object {
void foo (void)
{
asm ("setssbsy");
}
} "-O2" ]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment