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 <andrew.burg...@embecosm.com>
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