aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/Makefile.rtl12
-rw-r--r--gcc/ada/init.c7
-rw-r--r--gcc/ada/sigtramp-android-asm.h (renamed from gcc/ada/sigtramp-armdroid.c)83
-rw-r--r--gcc/ada/sigtramp-android.c79
-rw-r--r--gcc/ada/sigtramp.h21
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