diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 3f27fe9aca903fbdc1d9b42f50fce9b771b12af3..246c0059fb7f21261902581128a9956107e72b9d 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 ad51e2e054da16bf723f65dbeb9d7981868b15e8..8019c09f80e0383a98850d0110758cf525ae98bc 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
similarity index 60%
rename from gcc/ada/sigtramp-armdroid.c
rename to gcc/ada/sigtramp-android-asm.h
index c8b2a0aca8acd7dffb7ebc2c9ca4b7c96abca384..72cebae1b54692b7ac3effea796cb6956d84660d 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 0000000000000000000000000000000000000000..2fd42ba6f620151126656d875a52e81c1c240ec7
--- /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 f99bc201b0d72c8ba470b14ee009471091362dce..3c28c8aa56c924a702a36bd07f511a1d03c8513d 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