aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2018-04-19 17:05:39 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2018-04-19 10:05:39 -0700
commit5707be3c7da6196efcef2d86e623771153eb6c7f (patch)
treea43f6ec251c9c1de4fb01850c3b58f0720cb6b46 /gcc
parentf22723f93dd662c419e810e04390cf2319d4b29f (diff)
downloadgcc-5707be3c7da6196efcef2d86e623771153eb6c7f.zip
gcc-5707be3c7da6196efcef2d86e623771153eb6c7f.tar.gz
gcc-5707be3c7da6196efcef2d86e623771153eb6c7f.tar.bz2
libgcc/CET: Skip signal frames when unwinding shadow stack
When -fcf-protection -mcet is used, I got FAIL: g++.dg/eh/sighandle.C (gdb) bt #0 _Unwind_RaiseException (exc=exc@entry=0x416ed0) at /export/gnu/import/git/sources/gcc/libgcc/unwind.inc:140 #1 0x00007ffff7d9936b in __cxxabiv1::__cxa_throw (obj=<optimized out>, tinfo=0x403dd0 <typeinfo for int@@CXXABI_1.3>, dest=0x0) at /export/gnu/import/git/sources/gcc/libstdc++-v3/libsupc++/eh_throw.cc:90 #2 0x0000000000401255 in sighandler (signo=11, si=0x7fffffffd6f8, uc=0x7fffffffd5c0) at /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/eh/sighandle.C:9 #3 <signal handler called> <<<< Signal frame which isn't on shadow stack #4 dosegv () at /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/eh/sighandle.C:14 #5 0x00000000004012e3 in main () at /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/eh/sighandle.C:30 (gdb) p frames $6 = 5 (gdb) frame count should be 4, not 5. This patch skips signal frames when unwinding shadow stack. gcc/testsuite/ PR libgcc/85334 * g++.dg/torture/pr85334.C: New test. libgcc/ PR libgcc/85334 * unwind-generic.h (_Unwind_Frames_Increment): New. * config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment): Likewise. * unwind.inc (_Unwind_RaiseException_Phase2): Increment frame count with _Unwind_Frames_Increment. (_Unwind_ForcedUnwind_Phase2): Likewise. From-SVN: r259502
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr85334.C38
2 files changed, 43 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 62dec37..e7b9547 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-04-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR libgcc/85334
+ * g++.dg/torture/pr85334.C: New test.
+
2018-04-19 Jonathan Wakely <jwakely@redhat.com>
PR c++/85464 - missing location for -Wignored-qualifiers diagnostic
diff --git a/gcc/testsuite/g++.dg/torture/pr85334.C b/gcc/testsuite/g++.dg/torture/pr85334.C
new file mode 100644
index 0000000..0809781
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr85334.C
@@ -0,0 +1,38 @@
+// { dg-do run { target { i?86-*-linux* i?86-*-gnu* x86_64-*-linux* } } }
+// { dg-require-effective-target cet }
+// { dg-additional-options "-fexceptions -fnon-call-exceptions -fcf-protection -mcet" }
+
+#include <signal.h>
+#include <stdlib.h>
+
+void sighandler (int signo, siginfo_t * si, void * uc)
+{
+ throw (5);
+}
+
+char * dosegv ()
+{
+ * ((volatile int *)0) = 12;
+ return 0;
+}
+
+int main ()
+{
+ struct sigaction sa;
+ int status;
+
+ sa.sa_sigaction = sighandler;
+ sa.sa_flags = SA_SIGINFO;
+
+ status = sigaction (SIGSEGV, & sa, NULL);
+ status = sigaction (SIGBUS, & sa, NULL);
+
+ try {
+ dosegv ();
+ }
+ catch (int x) {
+ return (x != 5);
+ }
+
+ return 1;
+}