Re: [PATCH 1/4] Generate off-stack nested function trampolines

2021-12-02 Thread Jeff Law via Gcc-patches




On 11/13/2021 2:45 AM, Maxim Blinov wrote:

Add support for allocating nested function trampolines on an
executable heap rather than on the stack. This is motivated by targets
such as AArch64 Darwin, which globally prohibit executing code on the
stack.

The target-specific routines for allocating and writing trampolines is
to be provided in libgcc, and is by-default _not_ compiled in unless
the target specifically requires it, or you manually provide
--enable-off-stack-trampolines when configuring gcc/libgcc.

The gcc flag -foff-stack-trampolines controls whether to generate code
that instantiates trampolines on the stack, or to emit calls to
__builtin_nested_func_ptr_created and
__builtin_nested_func_ptr_deleted. Note that this flag is completely
independent of libgcc: If libgcc is for any reason missing those
symbols, you will get a link failure.

This implementation imposes some implicit restrictions as compared to
stack trampolines. longjmp'ing back to a state before a trampoline was
created will cause us to skip over the corresponding
__builtin_nested_func_ptr_deleted, which will leak trampolines
starting from the beginning of the linked list of allocated
trampolines. There may be scope for instrumenting longjmp/setjmp to
trigger cleanups of trampolines.

Co-authored-by: Andrew Burgess 

gcc/ChangeLog:

 * builtins.def (BUILT_IN_NESTED_PTR_CREATED): Define.
 (BUILT_IN_NESTED_PTR_DELETED): Ditto.
 * common.opt (foff-stack-trampolines): Add flag to control
 generation of heap-based trampoline instantiation.
 * tree-nested.c (convert_tramp_reference_op): Don't bother calling
 __builtin_adjust_trampoline for the off-stack case.
 (finalize_nesting_tree_1): Emit calls to
 __builtin_nested_...{created,deleted} if we're generating with
 -foff-stack-trampolines.
 * tree.c (build_common_builtin_nodes): Build
 __builtin_nested_...{created,deleted}.
* dov/invoke.texi (-foff-stack-trampolines): Document.

libgcc/ChangeLog:

* configure.ac: Add configure parameter
 --enable-off-stack-trampolines, and do error checking if we've
 trying to enable off-stack trampolines for a platform that doesn't
 provide any such implementation.
* configure: Regenerate.
* libgcc-std.ver.in: Ditto.
* libgcc2.h (__builtin_nested_func_ptr_created): Declare.
 (__builtin_nested_func_ptr_deleted): Ditto.
I'd tend to lean away from having this be a compile-time flag.  For 
aarch64-darwin, we'd just enable it and not allow it to be selectable.  
Similarly for other target where implementations. Ultimately this is an 
ABI decision, so a target needs to make a selection then stick with it IMHO.


Aside from that, I don't see anything in here too terrible.

jeff


Re: [PATCH 1/4] Generate off-stack nested function trampolines

2021-11-15 Thread Joseph Myers
On Sat, 13 Nov 2021, Maxim Blinov wrote:

> the target specifically requires it, or you manually provide
> --enable-off-stack-trampolines when configuring gcc/libgcc.

If you're adding a new configure option, it needs documenting in 
install.texi.

-- 
Joseph S. Myers
jos...@codesourcery.com


[PATCH 1/4] Generate off-stack nested function trampolines

2021-11-13 Thread Maxim Blinov
Add support for allocating nested function trampolines on an
executable heap rather than on the stack. This is motivated by targets
such as AArch64 Darwin, which globally prohibit executing code on the
stack.

The target-specific routines for allocating and writing trampolines is
to be provided in libgcc, and is by-default _not_ compiled in unless
the target specifically requires it, or you manually provide
--enable-off-stack-trampolines when configuring gcc/libgcc.

The gcc flag -foff-stack-trampolines controls whether to generate code
that instantiates trampolines on the stack, or to emit calls to
__builtin_nested_func_ptr_created and
__builtin_nested_func_ptr_deleted. Note that this flag is completely
independent of libgcc: If libgcc is for any reason missing those
symbols, you will get a link failure.

This implementation imposes some implicit restrictions as compared to
stack trampolines. longjmp'ing back to a state before a trampoline was
created will cause us to skip over the corresponding
__builtin_nested_func_ptr_deleted, which will leak trampolines
starting from the beginning of the linked list of allocated
trampolines. There may be scope for instrumenting longjmp/setjmp to
trigger cleanups of trampolines.

Co-authored-by: Andrew Burgess 

gcc/ChangeLog:

* builtins.def (BUILT_IN_NESTED_PTR_CREATED): Define.
(BUILT_IN_NESTED_PTR_DELETED): Ditto.
* common.opt (foff-stack-trampolines): Add flag to control
generation of heap-based trampoline instantiation.
* tree-nested.c (convert_tramp_reference_op): Don't bother calling
__builtin_adjust_trampoline for the off-stack case.
(finalize_nesting_tree_1): Emit calls to
__builtin_nested_...{created,deleted} if we're generating with
-foff-stack-trampolines.
* tree.c (build_common_builtin_nodes): Build
__builtin_nested_...{created,deleted}.
* dov/invoke.texi (-foff-stack-trampolines): Document.

libgcc/ChangeLog:

* configure.ac: Add configure parameter
--enable-off-stack-trampolines, and do error checking if we've
trying to enable off-stack trampolines for a platform that doesn't
provide any such implementation.
* configure: Regenerate.
* libgcc-std.ver.in: Ditto.
* libgcc2.h (__builtin_nested_func_ptr_created): Declare.
(__builtin_nested_func_ptr_deleted): Ditto.
---
 gcc/builtins.def |   2 +
 gcc/common.opt   |   4 ++
 gcc/config.gcc   |   7 +++
 gcc/doc/invoke.texi  |  14 +
 gcc/tree-nested.c| 121 +--
 gcc/tree.c   |  17 ++
 libgcc/configure |  26 +
 libgcc/configure.ac  |  17 ++
 libgcc/libgcc-std.ver.in |   3 +
 libgcc/libgcc2.h |   3 +
 10 files changed, 197 insertions(+), 17 deletions(-)

diff --git a/gcc/builtins.def b/gcc/builtins.def
index 45a09b4d42d..90a94a6dd0f 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -950,6 +950,8 @@ DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, 
"__builtin_adjust_trampoline")
 DEF_BUILTIN_STUB (BUILT_IN_INIT_DESCRIPTOR, "__builtin_init_descriptor")
 DEF_BUILTIN_STUB (BUILT_IN_ADJUST_DESCRIPTOR, "__builtin_adjust_descriptor")
 DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto")
+DEF_BUILTIN_STUB (BUILT_IN_NESTED_PTR_CREATED, 
"__builtin_nested_func_ptr_created")
+DEF_BUILTIN_STUB (BUILT_IN_NESTED_PTR_DELETED, 
"__builtin_nested_func_ptr_deleted")
 
 /* Implementing __builtin_setjmp.  */
 DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup")
diff --git a/gcc/common.opt b/gcc/common.opt
index de9b848eda5..a97aeeb2165 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2149,6 +2149,10 @@ foffload-abi=
 Common Joined RejectNegative Enum(offload_abi)
 -foffload-abi=[lp64|ilp32] Set the ABI to use in an offload compiler.
 
+foff-stack-trampolines
+Common RejectNegative Var(flag_off_stack_trampolines) 
Init(OFF_STACK_TRAMPOLINES_INIT)
+Generate trampolines in executable memory rather than executable stack.
+
 Enum
 Name(offload_abi) Type(enum offload_abi) UnknownError(unknown offload ABI %qs)
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index edd12655c4a..c479aa4cc44 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1070,6 +1070,13 @@ case ${target} in
   ;;
 esac
 
+# Figure out if we need to enable -foff-stack-trampolines by default.
+case ${target} in
+*)
+  tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=0"
+  ;;
+esac
+
 case ${target} in
 aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*)
tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2aba4c70b44..a5db65f8721 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -660,6 +660,7 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-fcall-saved-@var{reg}  -fcall-used-@var{reg} @gol
 -ffixed-@var{reg}  -fexceptions @gol
 -fnon-call-exceptions  -fdelete-d