Skip to content

Commit

Permalink
Also set ECF_RETURNS_TWICE for __[sig]setjmp_cancel
Browse files Browse the repository at this point in the history
__setjmp_cancel and __sigsetjmp_cancel are added to glibc to implement
thread cancellation to avoid preserving shadow stack register for CET
since there is no space in thread cancellation buffer to save and
restore shadow stack register.  This works since thread cancellation
always leads to exit after longjmp.  This patch updates GCC to set
ECF_RETURNS_TWICE for __setjmp_cancel and __sigsetjmp_cancel, just like
setjmp.

gcc/

	* calls.c (special_function_p): Also set ECF_RETURNS_TWICE for
	__setjmp_cancel and __sigsetjmp_cancel.

gcc/testsuite/

	* gcc.target/i386/cet-sjlj-7.c: New test.
	* gcc.target/i386/cet-sjlj-8.c: Likewise.
  • Loading branch information
hjl-tools committed Mar 7, 2018
1 parent 5666d34 commit e980878
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
4 changes: 3 additions & 1 deletion gcc/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ special_function_p (const_tree fndecl, int flags)
name_decl = DECL_NAME (cgraph_node::get (fndecl)->orig_decl);

if (fndecl && name_decl
&& IDENTIFIER_LENGTH (name_decl) <= 11
&& IDENTIFIER_LENGTH (name_decl) <= 18
/* Exclude functions not at the file scope, or not `extern',
since they are not the magic functions we would otherwise
think they are.
Expand Down Expand Up @@ -639,6 +639,8 @@ special_function_p (const_tree fndecl, int flags)
/* ECF_RETURNS_TWICE is safe even for -ffreestanding. */
if (! strcmp (tname, "setjmp")
|| ! strcmp (tname, "sigsetjmp")
|| ! strcmp (tname, "setjmp_cancel")
|| ! strcmp (tname, "sigsetjmp_cancel")
|| ! strcmp (name, "savectx")
|| ! strcmp (name, "vfork")
|| ! strcmp (name, "getcontext"))
Expand Down
17 changes: 17 additions & 0 deletions gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "call _?__setjmp_cancel" 1 } } */

extern int __setjmp_cancel (char *);
extern char env[];

int
foo (void)
{
if (__setjmp_cancel (env))
return 1;
else
return 0;
}
17 changes: 17 additions & 0 deletions gcc/testsuite/gcc.target/i386/cet-sjlj-8.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-O -fcf-protection -mcet" } */
/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */
/* { dg-final { scan-assembler-times "call _?__sigsetjmp_cancel" 1 } } */

extern int __sigsetjmp_cancel (char *);
extern char env[];

int
foo (void)
{
if (__sigsetjmp_cancel (env))
return 1;
else
return 0;
}

0 comments on commit e980878

Please sign in to comment.