From 9ae222ad79c83b3928ea8643140da6fc6bfd5e16 Mon Sep 17 00:00:00 2001 From: Igor Tsimbalist Date: Sat, 21 Oct 2017 23:33:41 +0200 Subject: [PATCH] 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 --- gcc/testsuite/ChangeLog | 45 ++++++++++++++++++ .../c-c++-common/attr-nocf-check-1.c | 10 ++-- .../c-c++-common/attr-nocf-check-1a.c | 32 +++++++++++++ .../c-c++-common/attr-nocf-check-3.c | 4 +- .../c-c++-common/attr-nocf-check-3a.c | 32 +++++++++++++ gcc/testsuite/c-c++-common/fcf-protection-1.c | 2 +- gcc/testsuite/c-c++-common/fcf-protection-2.c | 2 +- gcc/testsuite/c-c++-common/fcf-protection-3.c | 2 +- gcc/testsuite/c-c++-common/fcf-protection-5.c | 2 +- gcc/testsuite/g++.dg/cet-notrack-1.C | 25 ++++++++++ gcc/testsuite/gcc.target/i386/cet-intrin-10.c | 10 ++++ gcc/testsuite/gcc.target/i386/cet-intrin-3.c | 33 +++++++++++++ gcc/testsuite/gcc.target/i386/cet-intrin-4.c | 31 +++++++++++++ gcc/testsuite/gcc.target/i386/cet-intrin-5.c | 10 ++++ gcc/testsuite/gcc.target/i386/cet-intrin-6.c | 10 ++++ gcc/testsuite/gcc.target/i386/cet-intrin-7.c | 18 ++++++++ gcc/testsuite/gcc.target/i386/cet-intrin-8.c | 18 ++++++++ gcc/testsuite/gcc.target/i386/cet-intrin-9.c | 10 ++++ gcc/testsuite/gcc.target/i386/cet-label.c | 16 +++++++ .../gcc.target/i386/cet-notrack-1a.c | 22 +++++++++ .../gcc.target/i386/cet-notrack-1b.c | 23 ++++++++++ .../gcc.target/i386/cet-notrack-2a.c | 12 +++++ .../gcc.target/i386/cet-notrack-2b.c | 12 +++++ gcc/testsuite/gcc.target/i386/cet-notrack-3.c | 14 ++++++ .../gcc.target/i386/cet-notrack-4a.c | 6 +++ .../gcc.target/i386/cet-notrack-4b.c | 6 +++ .../gcc.target/i386/cet-notrack-5a.c | 16 +++++++ .../gcc.target/i386/cet-notrack-5b.c | 21 +++++++++ .../gcc.target/i386/cet-notrack-6a.c | 15 ++++++ .../gcc.target/i386/cet-notrack-6b.c | 15 ++++++ gcc/testsuite/gcc.target/i386/cet-notrack-7.c | 15 ++++++ .../gcc.target/i386/cet-notrack-icf-1.c | 31 +++++++++++++ .../gcc.target/i386/cet-notrack-icf-2.c | 30 ++++++++++++ .../gcc.target/i386/cet-notrack-icf-3.c | 36 +++++++++++++++ .../gcc.target/i386/cet-notrack-icf-4.c | 35 ++++++++++++++ .../gcc.target/i386/cet-property-1.c | 11 +++++ .../gcc.target/i386/cet-property-2.c | 11 +++++ gcc/testsuite/gcc.target/i386/cet-rdssp-1.c | 39 ++++++++++++++++ gcc/testsuite/gcc.target/i386/cet-sjlj-1.c | 42 +++++++++++++++++ gcc/testsuite/gcc.target/i386/cet-sjlj-2.c | 4 ++ gcc/testsuite/gcc.target/i386/cet-sjlj-3.c | 46 +++++++++++++++++++ gcc/testsuite/gcc.target/i386/cet-switch-1.c | 26 +++++++++++ gcc/testsuite/gcc.target/i386/cet-switch-2.c | 26 +++++++++++ gcc/testsuite/lib/target-supports.exp | 13 ++++++ 44 files changed, 828 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/attr-nocf-check-1a.c create mode 100644 gcc/testsuite/c-c++-common/attr-nocf-check-3a.c create mode 100644 gcc/testsuite/g++.dg/cet-notrack-1.C create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-10.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-3.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-4.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-5.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-6.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-7.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-8.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-intrin-9.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-label.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-1a.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-1b.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-2a.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-2b.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-3.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-4a.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-4b.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-5a.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-5b.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-6a.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-6b.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-7.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-icf-2.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-notrack-icf-4.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-property-1.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-property-2.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-rdssp-1.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-1.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-2.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-3.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-switch-1.c create mode 100644 gcc/testsuite/gcc.target/i386/cet-switch-2.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 22405be6a87..e14725979c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,48 @@ +2017-10-21 Igor Tsimbalist + + * 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 * gcc.target/i386/pr79683.c: Disable costmodel. diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c index 62fa370b22e..15f69731b91 100644 --- a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c +++ b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c @@ -1,8 +1,8 @@ /* { 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 (); } diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-1a.c b/gcc/testsuite/c-c++-common/attr-nocf-check-1a.c new file mode 100644 index 00000000000..9549e697658 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-nocf-check-1a.c @@ -0,0 +1,32 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c index c7d9c8f401f..ad1ca7eec9b 100644 --- a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c +++ b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c @@ -1,7 +1,7 @@ /* { 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 diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-3a.c b/gcc/testsuite/c-c++-common/attr-nocf-check-3a.c new file mode 100644 index 00000000000..1a833012409 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-nocf-check-3a.c @@ -0,0 +1,32 @@ +/* { 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; +} diff --git a/gcc/testsuite/c-c++-common/fcf-protection-1.c b/gcc/testsuite/c-c++-common/fcf-protection-1.c index 6a27e1973d8..2e9337c3051 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-1.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-1.c @@ -1,4 +1,4 @@ /* { 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 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-2.c b/gcc/testsuite/c-c++-common/fcf-protection-2.c index 558f4c0a580..aa0d2a04645 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-2.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-2.c @@ -1,4 +1,4 @@ /* { 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 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-3.c b/gcc/testsuite/c-c++-common/fcf-protection-3.c index ffc73469ad9..028775adc35 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-3.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-3.c @@ -1,4 +1,4 @@ /* { 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 } */ diff --git a/gcc/testsuite/c-c++-common/fcf-protection-5.c b/gcc/testsuite/c-c++-common/fcf-protection-5.c index 2ea2ce0d825..a5f8e116992 100644 --- a/gcc/testsuite/c-c++-common/fcf-protection-5.c +++ b/gcc/testsuite/c-c++-common/fcf-protection-5.c @@ -1,4 +1,4 @@ /* { 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 } */ diff --git a/gcc/testsuite/g++.dg/cet-notrack-1.C b/gcc/testsuite/g++.dg/cet-notrack-1.C new file mode 100644 index 00000000000..43dbbd6a7f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cet-notrack-1.C @@ -0,0 +1,25 @@ +/* { 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 + +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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-10.c b/gcc/testsuite/gcc.target/i386/cet-intrin-10.c new file mode 100644 index 00000000000..695dc5edc34 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-10.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcet" } */ +/* { dg-final { scan-assembler-times "clrssbsy" 1 } } */ + +#include + +void f2 (void *__B) +{ + _clrssbsy (__B); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-3.c b/gcc/testsuite/gcc.target/i386/cet-intrin-3.c new file mode 100644 index 00000000000..bcd7203fdb4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-3.c @@ -0,0 +1,33 @@ +/* { 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 + +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 diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-4.c b/gcc/testsuite/gcc.target/i386/cet-intrin-4.c new file mode 100644 index 00000000000..76ec160543f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-4.c @@ -0,0 +1,31 @@ +/* { 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 + +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 diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-5.c b/gcc/testsuite/gcc.target/i386/cet-intrin-5.c new file mode 100644 index 00000000000..8a1b637905c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-5.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcet" } */ +/* { dg-final { scan-assembler-times "saveprevssp" 1 } } */ + +#include + +void f2 (void) +{ + _saveprevssp (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-6.c b/gcc/testsuite/gcc.target/i386/cet-intrin-6.c new file mode 100644 index 00000000000..dfa6d20ca26 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-6.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcet" } */ +/* { dg-final { scan-assembler-times "rstorssp" 1 } } */ + +#include + +void f2 (void *__B) +{ + _rstorssp (__B); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-7.c b/gcc/testsuite/gcc.target/i386/cet-intrin-7.c new file mode 100644 index 00000000000..ecd1825a303 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-7.c @@ -0,0 +1,18 @@ +/* { 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 + +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 diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-8.c b/gcc/testsuite/gcc.target/i386/cet-intrin-8.c new file mode 100644 index 00000000000..2188876cca5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-8.c @@ -0,0 +1,18 @@ +/* { 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 + +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 diff --git a/gcc/testsuite/gcc.target/i386/cet-intrin-9.c b/gcc/testsuite/gcc.target/i386/cet-intrin-9.c new file mode 100644 index 00000000000..569931a9492 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-intrin-9.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcet" } */ +/* { dg-final { scan-assembler-times "setssbsy" 1 } } */ + +#include + +void f2 (void) +{ + _setssbsy (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-label.c b/gcc/testsuite/gcc.target/i386/cet-label.c new file mode 100644 index 00000000000..8fb8d420349 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-label.c @@ -0,0 +1,16 @@ +/* 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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-1a.c b/gcc/testsuite/gcc.target/i386/cet-notrack-1a.c new file mode 100644 index 00000000000..ab0bd3ba9b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-1a.c @@ -0,0 +1,22 @@ +/* { 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); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-1b.c b/gcc/testsuite/gcc.target/i386/cet-notrack-1b.c new file mode 100644 index 00000000000..6faf88fdf04 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-1b.c @@ -0,0 +1,23 @@ +/* { 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); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-2a.c b/gcc/testsuite/gcc.target/i386/cet-notrack-2a.c new file mode 100644 index 00000000000..6f441e49edf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-2a.c @@ -0,0 +1,12 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-2b.c b/gcc/testsuite/gcc.target/i386/cet-notrack-2b.c new file mode 100644 index 00000000000..0df46450e88 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-2b.c @@ -0,0 +1,12 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-3.c b/gcc/testsuite/gcc.target/i386/cet-notrack-3.c new file mode 100644 index 00000000000..5e124c7f95c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-3.c @@ -0,0 +1,14 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-4a.c b/gcc/testsuite/gcc.target/i386/cet-notrack-4a.c new file mode 100644 index 00000000000..34cfd9098c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-4a.c @@ -0,0 +1,6 @@ +/* { 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" } */ diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-4b.c b/gcc/testsuite/gcc.target/i386/cet-notrack-4b.c new file mode 100644 index 00000000000..6065ef69c25 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-4b.c @@ -0,0 +1,6 @@ +/* { 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" } */ diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-5a.c b/gcc/testsuite/gcc.target/i386/cet-notrack-5a.c new file mode 100644 index 00000000000..d23968e58d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-5a.c @@ -0,0 +1,16 @@ +/* { 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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-5b.c b/gcc/testsuite/gcc.target/i386/cet-notrack-5b.c new file mode 100644 index 00000000000..42d9d07b19d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-5b.c @@ -0,0 +1,21 @@ +/* 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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-6a.c b/gcc/testsuite/gcc.target/i386/cet-notrack-6a.c new file mode 100644 index 00000000000..e0fb4f90aaf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-6a.c @@ -0,0 +1,15 @@ +/* { 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); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-6b.c b/gcc/testsuite/gcc.target/i386/cet-notrack-6b.c new file mode 100644 index 00000000000..1c47c9f7d20 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-6b.c @@ -0,0 +1,15 @@ +/* { 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. */ +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-7.c b/gcc/testsuite/gcc.target/i386/cet-notrack-7.c new file mode 100644 index 00000000000..f2e31d0258a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-7.c @@ -0,0 +1,15 @@ +/* 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c new file mode 100644 index 00000000000..7987d53d305 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c @@ -0,0 +1,31 @@ +/* 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); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-2.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-2.c new file mode 100644 index 00000000000..db0b0a44237 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-2.c @@ -0,0 +1,30 @@ +/* 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); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c new file mode 100644 index 00000000000..07c4a6b61ef --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c @@ -0,0 +1,36 @@ +/* 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); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-4.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-4.c new file mode 100644 index 00000000000..e4e96aaf0dc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-4.c @@ -0,0 +1,35 @@ +/* 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); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-property-1.c b/gcc/testsuite/gcc.target/i386/cet-property-1.c new file mode 100644 index 00000000000..df243efc574 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-property-1.c @@ -0,0 +1,11 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-property-2.c b/gcc/testsuite/gcc.target/i386/cet-property-2.c new file mode 100644 index 00000000000..5a87dab92f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-property-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-mcet" } */ +/* { dg-final { scan-assembler-not ".note.gnu.property" } } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/i386/cet-rdssp-1.c b/gcc/testsuite/gcc.target/i386/cet-rdssp-1.c new file mode 100644 index 00000000000..fb50ff43504 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-rdssp-1.c @@ -0,0 +1,39 @@ +/* { 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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-1.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-1.c new file mode 100644 index 00000000000..374d12aa745 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-1.c @@ -0,0 +1,42 @@ +/* { 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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-2.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-2.c new file mode 100644 index 00000000000..c97094a19c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-2.c @@ -0,0 +1,4 @@ +/* { dg-do run { target cet } } */ +/* { dg-options "-O -fcf-protection -mcet" } */ + +#include "cet-sjlj-1.c" diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-3.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-3.c new file mode 100644 index 00000000000..c1efbbeab17 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-3.c @@ -0,0 +1,46 @@ +/* { 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 +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-switch-1.c b/gcc/testsuite/gcc.target/i386/cet-switch-1.c new file mode 100644 index 00000000000..7a75857fcb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-switch-1.c @@ -0,0 +1,26 @@ +/* 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; +} diff --git a/gcc/testsuite/gcc.target/i386/cet-switch-2.c b/gcc/testsuite/gcc.target/i386/cet-switch-2.c new file mode 100644 index 00000000000..e620b837a3c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cet-switch-2.c @@ -0,0 +1,26 @@ +/* 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; +} diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 63694ea51e2..56ac2211e47 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -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" ] +} -- 2.30.2