'Retpoline' mitigation technique for Spectre (branch target injection) [CVE-2017-5715]: https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html https://support.google.com/faqs/answer/7625886 https://spectreattack.com/ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715 Patch copied from the 'retpoline-20180107' branch of upstream source repository (please add new / update existing patches when new 'retpoline-xxxxxxxx' branch appears): http://git.infradead.org/users/dwmw2/gcc-retpoline.git From 4032162fb6d36e20091885d0558f91daaa0080d3 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 27 Nov 2017 08:38:41 -0800 Subject: [PATCH 07/17] Add -mindirect-branch=thunk-extern Add -mindirect-branch=thunk-extern tests --- gcc/config/i386/i386-opts.h | 3 +- gcc/config/i386/i386.opt | 3 ++ .../gcc.target/i386/indirect-thunk-extern-1.c | 19 ++++++++++ .../gcc.target/i386/indirect-thunk-extern-2.c | 19 ++++++++++ .../gcc.target/i386/indirect-thunk-extern-3.c | 20 ++++++++++ .../gcc.target/i386/indirect-thunk-extern-4.c | 20 ++++++++++ .../gcc.target/i386/indirect-thunk-extern-5.c | 16 ++++++++ .../gcc.target/i386/indirect-thunk-extern-6.c | 17 +++++++++ .../gcc.target/i386/indirect-thunk-extern-7.c | 43 ++++++++++++++++++++++ 9 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h index f301890575a..f8d80ba7ec6 100644 --- a/gcc/config/i386/i386-opts.h +++ b/gcc/config/i386/i386-opts.h @@ -102,7 +102,8 @@ enum stack_protector_guard { enum indirect_branch { indirect_branch_keep, indirect_branch_thunk, - indirect_branch_thunk_inline + indirect_branch_thunk_inline, + indirect_branch_thunk_extern }; #endif diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 68484a75022..4a932e11bf6 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -944,3 +944,6 @@ Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) EnumValue Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) + +EnumValue +Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c new file mode 100644 index 00000000000..0a1f91be988 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +void +male_indirect_jump (long offset) +{ + dispatch(offset); +} + +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c new file mode 100644 index 00000000000..182520ab3dc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +void +male_indirect_jump (long offset) +{ + dispatch[offset](offset); +} + +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c new file mode 100644 index 00000000000..5c31ddc34fd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +int +male_indirect_jump (long offset) +{ + dispatch(offset); + return 0; +} + +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c new file mode 100644 index 00000000000..f24d0c060f2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +int +male_indirect_jump (long offset) +{ + dispatch[offset](offset); + return 0; +} + +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c new file mode 100644 index 00000000000..ad54aaeac4c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c new file mode 100644 index 00000000000..a8e75254cfe --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c new file mode 100644 index 00000000000..8d39fb6f939 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ + +void func0 (void); +void func1 (void); +void func2 (void); +void func3 (void); +void func4 (void); +void func4 (void); +void func5 (void); + +void +bar (int i) +{ + switch (i) + { + default: + func0 (); + break; + case 1: + func1 (); + break; + case 2: + func2 (); + break; + case 3: + func3 (); + break; + case 4: + func4 (); + break; + case 5: + func5 (); + break; + } +} + +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */ +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ -- 2.15.1