aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/tracebak.c
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
commita926878ddbd5a98b272c22171ce58663fc04c3e0 (patch)
tree86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/ada/tracebak.c
parent542730f087133690b47e036dfd43eb0db8a650ce (diff)
parent07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff)
downloadgcc-devel/autopar_devel.zip
gcc-devel/autopar_devel.tar.gz
gcc-devel/autopar_devel.tar.bz2
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/ada/tracebak.c')
-rw-r--r--gcc/ada/tracebak.c101
1 files changed, 99 insertions, 2 deletions
diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c
index 9e74282..d643cfc 100644
--- a/gcc/ada/tracebak.c
+++ b/gcc/ada/tracebak.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 2000-2019, Free Software Foundation, Inc. *
+ * Copyright (C) 2000-2020, 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- *
@@ -588,7 +588,101 @@ is_return_from(void *symbol_addr, void *ret_addr)
define it to a reasonable value to avoid a compilation error. */
#define _URC_NORMAL_STOP 0
#endif
-#include "tb-gcc.c"
+
+/* This is an implementation of the __gnat_backtrace routine using the
+ underlying GCC unwinding support associated with the exception handling
+ infrastructure. This will only work for ZCX based applications. */
+
+#include <unwind.h>
+
+/* The implementation boils down to a call to _Unwind_Backtrace with a
+ tailored callback and carried-on data structure to keep track of the
+ input parameters we got as well as of the basic processing state. */
+
+/******************
+ * trace_callback *
+ ******************/
+
+#if !defined (__USING_SJLJ_EXCEPTIONS__)
+
+typedef struct {
+ void ** traceback;
+ int max_len;
+ void * exclude_min;
+ void * exclude_max;
+ int n_frames_to_skip;
+ int n_frames_skipped;
+ int n_entries_filled;
+} uw_data_t;
+
+#if defined (__ia64__) && defined (__hpux__)
+#include <uwx.h>
+#endif
+
+static _Unwind_Reason_Code
+trace_callback (struct _Unwind_Context * uw_context, uw_data_t * uw_data)
+{
+ char * pc;
+
+#if defined (__ia64__) && defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
+ /* Work around problem with _Unwind_GetIP on ia64 HP-UX. */
+ uwx_get_reg ((struct uwx_env *) uw_context, UWX_REG_IP, (uint64_t *) &pc);
+#else
+ pc = (char *) _Unwind_GetIP (uw_context);
+#endif
+
+ if (uw_data->n_frames_skipped < uw_data->n_frames_to_skip)
+ {
+ uw_data->n_frames_skipped ++;
+ return _URC_NO_REASON;
+ }
+
+ if (uw_data->n_entries_filled >= uw_data->max_len)
+ return _URC_NORMAL_STOP;
+
+ if (pc < (char *)uw_data->exclude_min || pc > (char *)uw_data->exclude_max)
+ uw_data->traceback [uw_data->n_entries_filled ++] = pc + PC_ADJUST;
+
+ return _URC_NO_REASON;
+}
+
+#endif
+
+/********************
+ * __gnat_backtrace *
+ ********************/
+
+int
+__gnat_backtrace (void ** traceback __attribute__((unused)),
+ int max_len __attribute__((unused)),
+ void * exclude_min __attribute__((unused)),
+ void * exclude_max __attribute__((unused)),
+ int skip_frames __attribute__((unused)))
+{
+#if defined (__USING_SJLJ_EXCEPTIONS__)
+ /* We have no unwind material (tables) at hand with sjlj eh, and no
+ way to retrieve complete and accurate call chain information from
+ the context stack we maintain. */
+ return 0;
+#else
+ uw_data_t uw_data;
+ /* State carried over during the whole unwinding process. */
+
+ uw_data.traceback = traceback;
+ uw_data.max_len = max_len;
+ uw_data.exclude_min = exclude_min;
+ uw_data.exclude_max = exclude_max;
+
+ uw_data.n_frames_to_skip = skip_frames;
+
+ uw_data.n_frames_skipped = 0;
+ uw_data.n_entries_filled = 0;
+
+ _Unwind_Backtrace ((_Unwind_Trace_Fn)trace_callback, &uw_data);
+
+ return uw_data.n_entries_filled;
+#endif
+}
/*------------------------------------------------------------------*
*-- The generic implementation based on frame layout assumptions --*
@@ -596,6 +690,9 @@ is_return_from(void *symbol_addr, void *ret_addr)
#elif defined (USE_GENERIC_UNWINDER)
+/* No warning since the cases where FRAME_LEVEL > 0 are known to work. */
+#pragma GCC diagnostic ignored "-Wframe-address"
+
#ifndef CURRENT_STACK_FRAME
# define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
#endif