diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/Makefile.rtl | 12 | ||||
-rw-r--r-- | gcc/ada/init.c | 7 | ||||
-rw-r--r-- | gcc/ada/sigtramp-android-asm.h (renamed from gcc/ada/sigtramp-armdroid.c) | 83 | ||||
-rw-r--r-- | gcc/ada/sigtramp-android.c | 79 | ||||
-rw-r--r-- | gcc/ada/sigtramp.h | 21 |
5 files changed, 115 insertions, 87 deletions
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl index 3f27fe9..246c0059 100644 --- a/gcc/ada/Makefile.rtl +++ b/gcc/ada/Makefile.rtl @@ -1430,22 +1430,20 @@ ifeq ($(strip $(filter-out arm% aarch64 linux-android%,$(target_cpu) $(target_os EXTRA_GNATRTL_TASKING_OBJS=s-linux.o - # 32bit arm relies on a sigtramp for signal->exception propagation - # while aarch64 relies on kernel dwarf CFI. And as a 64bit target, - # aarch64 can also incorporate support for 128bit arithmetic. + # ARM and aarch64 rely on different unwinding mechanisms, and as + # a 64bit target, aarch64 can also incorporate support for 128bit + # arithmetic. ifeq ($(strip $(filter-out arm%, $(target_cpu))),) SELECTED_PAIRS=arm-android EH_MECHANISM=-arm - SIGTRAMP_OBJ=sigtramp-armdroid.o LIBGNAT_TARGET_PAIRS += \ s-linux.ads<libgnarl/s-linux__android-arm.ads else SELECTED_PAIRS=aarch64-android EH_MECHANISM=-gcc - SIGTRAMP_OBJ= LIBGNAT_TARGET_PAIRS += \ s-linux.ads<libgnarl/s-linux__android-aarch64.ads @@ -1453,8 +1451,8 @@ ifeq ($(strip $(filter-out arm% aarch64 linux-android%,$(target_cpu) $(target_os EXTRA_GNATRTL_NONTASKING_OBJS = $(GNATRTL_128BIT_OBJS) endif - EXTRA_LIBGNAT_OBJS+=$(SIGTRAMP_OBJ) - EXTRA_LIBGNAT_SRCS+=sigtramp.h + EXTRA_LIBGNAT_OBJS+=sigtramp-android.o + EXTRA_LIBGNAT_SRCS+=sigtramp.h sigtramp-android-asm.h THREADSLIB = GNATLIB_SHARED = gnatlib-shared-dual LIBRARY_VERSION := $(LIB_VERSION) diff --git a/gcc/ada/init.c b/gcc/ada/init.c index ad51e2e..8019c09 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -2831,15 +2831,8 @@ static void __gnat_error_handler (int sig, siginfo_t *si, void *ucontext) { __gnat_adjust_context_for_raise (sig, ucontext); - - /* The ARM port relies on a sigtramp. Others such as aarch64, - dwarf info based, rely on kernel CFI. */ -#if defined(__arm__) __gnat_sigtramp (sig, (void *) si, (void *) ucontext, (__sigtramphandler_t *)&__gnat_map_signal); -#else - __gnat_map_signal (sig, si, ucontext); -#endif } /* This must be in keeping with System.OS_Interface.Alternate_Stack_Size. */ diff --git a/gcc/ada/sigtramp-armdroid.c b/gcc/ada/sigtramp-android-asm.h index c8b2a0a..72cebae 100644 --- a/gcc/ada/sigtramp-armdroid.c +++ b/gcc/ada/sigtramp-android-asm.h @@ -2,11 +2,11 @@ * * * GNAT COMPILER COMPONENTS * * * - * S I G T R A M P * + * S I G T R A M P - T A R G E T * * * - * Asm Implementation File * + * Asm Implementation Include File * * * - * Copyright (C) 2015-2024, Free Software Foundation, Inc. * + * Copyright (C) 2024, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -29,62 +29,19 @@ * * ****************************************************************************/ -/****************************************************** - * ARM-Android version of the __gnat_sigtramp service * - ******************************************************/ +/***************************************************************** + * CPU specific parts of the __gnat_sigtramp service for Android * + *****************************************************************/ -#include <sys/ucontext.h> +/* The intended use mode of this header is to provide macros + and a prologue to the generation of an asm function, as in -#include "sigtramp.h" -/* See sigtramp.h for a general explanation of functionality. */ + #include <this-header> + asm (SIGTRAMP_START(<symbol-name>)); + asm (SIGTRAMP_BODY); + asm (SIGTRAMP_END(<symbol-name>)); -/* ---------------------- - -- General comments -- - ---------------------- - - Stubs are generated from toplevel asms, - The general idea is to establish CFA as the sigcontext - and state where to find the registers as offsets from there. - - We support stubs for VxWorks and Android, providing unwind info for - common registers. We might need variants with support for floating - point or altivec registers as well at some point. - - For Android it would be simpler to write this in Asm since there's only - one variant, but to keep it looking like the VxWorks stubs, - C is the choice for our toplevel interface. - - Note that the registers we "restore" here are those to which we have - direct access through the system sigcontext structure, which includes - only a partial set of the non-volatiles ABI-wise. */ - -/* ----------------------------------------- - -- Protypes for our internal asm stubs -- - ----------------------------------------- - - The registers are expected to be at SIGCONTEXT + 12 (reference the - sicontext structure in asm/sigcontext.h which describes the first - 3 * 4byte fields.) Even though our symbols will remain local, the - prototype claims "extern" and not "static" to prevent compiler complaints - about a symbol used but never defined. */ - -/* sigtramp stub providing unwind info for common registers. */ - -extern void __gnat_sigtramp_common - (int signo, void *siginfo, void *sigcontext, - __sigtramphandler_t * handler); - -void __gnat_sigtramp (int signo, void *si, void *sc, - __sigtramphandler_t * handler) - __attribute__((optimize(2))); - -void __gnat_sigtramp (int signo, void *si, void *ucontext, - __sigtramphandler_t * handler) -{ - struct sigcontext *mcontext = &((ucontext_t *) ucontext)->uc_mcontext; - - __gnat_sigtramp_common (signo, si, mcontext, handler); -} + and nothing else after. */ /* asm string construction helpers. */ @@ -103,6 +60,8 @@ void __gnat_sigtramp (int signo, void *si, void *ucontext, #undef TCR #define TCR(S) TAB(CR(S)) +#if defined(__arm__) + /* Trampoline body block --------------------- */ @@ -145,19 +104,9 @@ TCR(".fnstart") CR(".fnend") \ TCR(".size " S(SYM) ", .-" S(SYM)) -/*---------------------------- - -- And now, the real code -- - ---------------------------- */ +#endif /* Text section start. The compiler isn't aware of that switch. */ asm (".text\n" TCR(".align 2")); - -/* sigtramp stub for common registers. */ - -#define TRAMP_COMMON __gnat_sigtramp_common - -asm (SIGTRAMP_START(TRAMP_COMMON)); -asm (SIGTRAMP_BODY); -asm (SIGTRAMP_END(TRAMP_COMMON)); diff --git a/gcc/ada/sigtramp-android.c b/gcc/ada/sigtramp-android.c new file mode 100644 index 0000000..2fd42ba --- /dev/null +++ b/gcc/ada/sigtramp-android.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * * + * GNAT COMPILER COMPONENTS * + * * + * S I G T R A M P * + * * + * C/Asm Implementation File * + * * + * Copyright (C) 2015-2024, Free Software Foundation, Inc. * + * * + * GNAT is free software; you can redistribute it and/or modify it under * + * terms of the GNU General Public License as published by the Free Soft- * + * ware Foundation; either version 3, or (at your option) any later ver- * + * sion. GNAT is distributed in the hope that it will be useful, but WITH- * + * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. * + * * + * As a special exception under Section 7 of GPL version 3, you are granted * + * additional permissions described in the GCC Runtime Library Exception, * + * version 3.1, as published by the Free Software Foundation. * + * * + * In particular, you can freely distribute your programs built with the * + * GNAT Pro compiler, including any required library run-time units, using * + * any licensing terms of your choosing. See the AdaCore Software License * + * for full details. * + * * + * GNAT was originally developed by the GNAT team at New York University. * + * Extensive contributions were provided by Ada Core Technologies Inc. * + * * + ****************************************************************************/ + +/************************************************** + * Android version of the __gnat_sigtramp service * + **************************************************/ + +#include "sigtramp.h" + +/* The ARM port relies on CFI info setup here. Others such as aarch64 + rely on kernel CFI and may relay to the handler directly. */ + +#if defined(__arm__) +#define __SETUP_CFI 1 +#else +#define __SETUP_CFI 0 +#endif + +#if __SETUP_CFI + +/* Craft a sigtramp stub providing unwind info for common registers. */ + +#define TRAMP_COMMON __gnat_sigtramp_common +extern void TRAMP_COMMON + (int signo, void *siginfo, void *sigcontext, + __sigtramphandler_t * handler); + +#include <sys/ucontext.h> + +void __gnat_sigtramp (int signo, void *si, void *ucontext, + __sigtramphandler_t * handler) +{ + struct sigcontext *mcontext = &((ucontext_t *) ucontext)->uc_mcontext; + TRAMP_COMMON (signo, si, mcontext, handler); +} + +#include <sigtramp-android-asm.h> + +asm (SIGTRAMP_START(TRAMP_COMMON)); +asm (SIGTRAMP_BODY); +asm (SIGTRAMP_END(TRAMP_COMMON)); + +#else /* !__SETUP_CFI */ + +void __gnat_sigtramp (int signo, void *si, void *ucontext, + __sigtramphandler_t * handler) +{ + handler (signo, si, ucontext); +} + +#endif diff --git a/gcc/ada/sigtramp.h b/gcc/ada/sigtramp.h index f99bc20..3c28c8a 100644 --- a/gcc/ada/sigtramp.h +++ b/gcc/ada/sigtramp.h @@ -29,11 +29,19 @@ * * ****************************************************************************/ -/* On targets where this is implemented, we resort to a signal trampoline to - set up the DWARF Call Frame Information that lets unwinders walk through - the signal frame up into the interrupted user code. This file introduces - the relevant declarations. It should only be #included on targets that do - implement the signal trampoline. */ +/* On targets where this is useful, a signal handler trampoline is setup to + allow interposing handcrafted DWARF Call Frame Information that lets + unwinders walk through a signal frame up into the interrupted user code. + This file introduces the relevant declarations. + + For an OS family, in specific CPU configurations where kernel signal CFI + is known to be available, the trampoline may directly call the intended + handler without any intermediate CFI magic. + + sigtramp*.c offers a convenient spot for picking such alternatives, as + it allows testing for precise target predicates and is easily shared + by the tasking and non-tasking runtimes for a given OS (e.g. s-intman.adb + and init.c:__gnat_error_handler). */ #ifdef __cplusplus extern "C" { @@ -54,7 +62,8 @@ extern void __gnat_sigtramp (int signo, void *siginfo, void *sigcontext, __sigtramphandler_t * handler); /* The signal trampoline is to be called from an established signal handler. - It sets up the DWARF CFI and calls HANDLER (SIGNO, SIGINFO, SIGCONTEXT). + It calls HANDLER (SIGNO, SIGINFO, SIGCONTEXT) after setting up the DWARF + CFI if needed. The trampoline construct makes it so that the unwinder jumps over it + the signal handler + the kernel frame. For a typical backtrace from the raise |