libgcc/CET: Skip signal frames when unwinding shadow stack
commit20d1a0756a0cf5072d0cdf3d2adab00063c224a7
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Apr 2018 17:05:39 +0000 (19 17:05 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Apr 2018 17:05:39 +0000 (19 17:05 +0000)
treea43f6ec251c9c1de4fb01850c3b58f0720cb6b46
parent47b6cf63fca600c911e7c0498bc740c74eb438a1
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@259502 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr85334.C [new file with mode: 0644]
libgcc/ChangeLog
libgcc/config/i386/shadow-stack-unwind.h
libgcc/unwind-generic.h
libgcc/unwind.inc