[gcc/devel/ranger] Ability to build the GNAT runtime with project files

Aldy Hernandez aldyh@gcc.gnu.org
Wed Jun 17 21:58:57 GMT 2020


https://gcc.gnu.org/g:9f2e635defba9d697a6c291013b37bd2c7ed91aa

commit 9f2e635defba9d697a6c291013b37bd2c7ed91aa
Author: Arnaud Charlet <charlet@adacore.com>
Date:   Sat May 30 14:40:02 2020 -0400

    Ability to build the GNAT runtime with project files
    
    This change add project files to provide the ability to rebuild the
    runtime with gprbuild after setup-rts is called.
    
    gcc/ada/
    
            * Makefile.rtl (ADA_INCLUDE_SRCS): Replace Makefile.adalib by
            libada.gpr and associated project files.
            (g-debpoo.o): Add missing rule to ensure subprograms are not reordered.
            (setup-rts): Add generation of libgnat/libgnarl.lst.
            (LIBGNAT_SRCS): Remove thread.c which is part of libgnarl.
            * tracebak.c, tb-gcc.c: Merged the two files to simplify dependencies.
            * libgnarl/libgnarl.gpr, libgnat/libada.gpr,
            libgnat/libgnat.gpr, libgnat/libgnat_common.gpr: New files.
            * doc/gnat_ugn/the_gnat_compilation_model.rst: Makefile.adalib
            replaced by libada.gpr.
            * libgnat/system-mingw.ads: Remove obsolete comment.
            * gcc-interface/Makefile.in: Remove dependency on tb-gcc.c.

Diff:
---
 gcc/ada/Makefile.rtl                               |  33 +++++-
 .../doc/gnat_ugn/the_gnat_compilation_model.rst    |  18 +--
 gcc/ada/gcc-interface/Makefile.in                  |   2 +-
 gcc/ada/libgnarl/libgnarl.gpr                      |  28 +++++
 gcc/ada/libgnat/libada.gpr                         |  77 +++++++++++++
 gcc/ada/libgnat/libgnat.gpr                        |  69 ++++++++++++
 gcc/ada/libgnat/libgnat_common.gpr                 |  19 ++++
 gcc/ada/libgnat/system-mingw.ads                   |   5 -
 gcc/ada/tb-gcc.c                                   | 125 ---------------------
 gcc/ada/tracebak.c                                 |  96 +++++++++++++++-
 10 files changed, 329 insertions(+), 143 deletions(-)

diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 55ff9b0f3d5..0c62df23628 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2621,7 +2621,7 @@ LIBGNAT_OBJS = adadecode.o adaint.o argv.o aux-io.o 			\
 
 LIBGNAT_SRCS = $(patsubst %.o,%.c,$(LIBGNAT_OBJS))			\
   adadecode.h adaint.h env.h gsocket.h raise.h standard.ads.h		\
-  tb-gcc.c runtime.h libgnarl/thread.c $(EXTRA_LIBGNAT_SRCS)
+  runtime.h $(EXTRA_LIBGNAT_SRCS)
 
 # memtrack.o is special as not put into libgnat.
 GNATRTL_OBJS = $(GNATRTL_NONTASKING_OBJS) $(GNATRTL_TASKING_OBJS) \
@@ -2634,7 +2634,8 @@ GNATRTL_OBJS = $(GNATRTL_NONTASKING_OBJS) $(GNATRTL_TASKING_OBJS) \
 ADA_INCLUDE_SRCS =\
  libgnat/ada.ads libgnat/calendar.ads libgnat/directio.ads libgnat/gnat.ads libgnat/interfac.ads libgnat/ioexcept.ads \
  libgnat/machcode.ads libgnat/text_io.ads libgnat/unchconv.ads libgnat/unchdeal.ads \
- libgnat/sequenio.ads libgnat/system.ads Makefile.adalib libgnat/memtrack.adb \
+ libgnat/sequenio.ads libgnat/system.ads libgnat/memtrack.adb \
+ libgna*/*.gpr \
  libgnat/a-[a-o]*.adb libgnat/a-[a-o]*.ads \
  libgnat/a-[p-z]*.adb libgnat/a-[p-z]*.ads \
  libgnat/g-[a-o]*.adb libgnat/g-[a-o]*.ads \
@@ -2680,7 +2681,7 @@ setup-rts: force
 	$(MKDIR) $(RTSDIR)
 	$(CHMOD) u+w $(RTSDIR)
 # Copy target independent sources
-	$(foreach f,$(ADA_INCLUDE_SRCS) $(LIBGNAT_SRCS), \
+	$(foreach f,$(ADA_INCLUDE_SRCS) $(LIBGNAT_SRCS) libgnarl/thread.c, \
 	  $(LN_S) $(GNAT_SRC)/$(f) $(RTSDIR) ;) true
 # Remove files not used
 	$(RM) $(patsubst %,$(RTSDIR)/%,$(ADA_EXCLUDE_FILES))
@@ -2697,6 +2698,25 @@ setup-rts: force
 	$(foreach PAIR,$(LIBGNAT_TARGET_PAIRS), \
 	          $(LN_S) $(GNAT_SRC)/$(word 2,$(subst <, ,$(PAIR))) \
 	                $(RTSDIR)/$(word 1,$(subst <, ,$(PAIR)));)
+# And finally generate libgnat.lst and libgnarl.lst
+	@for f in \
+	  $(foreach F,$(GNATRTL_TASKING_OBJS),$(subst $(objext),.ads,$(F))) \
+	  $(foreach F,$(GNATRTL_TASKING_OBJS),$(subst $(objext),.adb,$(F))); \
+	do \
+	  if [ -f $(RTSDIR)/$$f ]; then echo $$f >> $(RTSDIR)/libgnarl.lst; fi \
+	done
+	@echo thread.c >> $(RTSDIR)/libgnarl.lst
+	@for f in \
+	  $(foreach F,$(GNATRTL_NONTASKING_OBJS),$(subst $(objext),.ads,$(F))) \
+	  $(foreach F,$(GNATRTL_NONTASKING_OBJS),$(subst $(objext),.adb,$(F))); \
+	do \
+	  if [ -f $(RTSDIR)/$$f ]; then echo $$f >> $(RTSDIR)/libgnat.lst; fi \
+	done
+# s-oscons.ads is generated later, so hardcode it here
+	@echo s-oscons.ads >> $(RTSDIR)/libgnat.lst
+	@for f in $(LIBGNAT_SRCS); do \
+	  echo $$f >> $(RTSDIR)/libgnat.lst; \
+	done
 
 # Special flags. It is recommended not to change the compilation flags
 # without a careful analysis of the consequences because (part of) the
@@ -2773,3 +2793,10 @@ a-tags.o  : a-tags.adb a-tags.ads
 s-memory.o  : s-memory.adb s-memory.ads
 	$(ADAC) -c $(ALL_ADAFLAGS) $(NO_SIBLING_ADAFLAGS) $(ADA_INCLUDES) \
 	  $< $(OUTPUT_OPTION)
+
+# Need to keep functions ordered on g-debpoo.o since labels are used to
+# exclude subprograms from traceback computation.
+
+g-debpoo.o: g-debpoo.adb g-debpoo.ads
+	$(ADAC) -c $(ALL_ADAFLAGS) $(NO_REORDER_ADAFLAGS) $(ADA_INCLUDES) \
+	  $< $(OUTPUT_OPTION)
diff --git a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
index d7388bb5ffe..0b587efac12 100644
--- a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
+++ b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
@@ -2393,10 +2393,9 @@ Rebuilding the GNAT Run-Time Library
 .. index:: Rebuilding the GNAT Run-Time Library
 .. index:: Run-Time Library, rebuilding
 
-It may be useful to recompile the GNAT library in various contexts, the
-most important one being the use of partition-wide configuration pragmas
-such as ``Normalize_Scalars``. A special Makefile called
-:file:`Makefile.adalib` is provided to that effect and can be found in
+It may be useful to recompile the GNAT library in various debugging or
+experimentation contexts. A project file called
+:file:`libada.gpr` is provided to that effect and can be found in
 the directory containing the GNAT library. The location of this
 directory depends on the way the GNAT environment has been installed and can
 be determined by means of the command:
@@ -2405,10 +2404,13 @@ be determined by means of the command:
 
       $ gnatls -v
 
-The last entry in the object search path usually contains the
-gnat library. This Makefile contains its own documentation and in
-particular the set of instructions needed to rebuild a new library and
-to use it.
+The last entry in the source search path usually contains the
+gnat library (the :file:`adainclude` directory). This project file contains its
+own documentation and in particular the set of instructions needed to rebuild a
+new library and to use it.
+
+Note that rebuilding the GNAT Run-Time is only recommended for temporary
+experiments or debugging, and is not supported.
 
 
 .. index:: ! Conditional compilation
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 3342e33b4b1..25ebc3d21d4 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -895,7 +895,7 @@ ADA_RTL_DSO_DIR = $(toolexeclibdir)
 # need to keep the frame pointer in tracebak.o to pop the stack properly on
 # some targets.
 
-tracebak.o  : tracebak.c tb-gcc.c
+tracebak.o  : tracebak.c
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) \
 	      $(INCLUDES) $(NO_OMIT_ADAFLAGS) $< $(OUTPUT_OPTION)
 
diff --git a/gcc/ada/libgnarl/libgnarl.gpr b/gcc/ada/libgnarl/libgnarl.gpr
new file mode 100644
index 00000000000..3933f6f2f3a
--- /dev/null
+++ b/gcc/ada/libgnarl/libgnarl.gpr
@@ -0,0 +1,28 @@
+with "libgnat_common";
+
+library project Libgnarl is
+
+   for Languages use ("Ada", "C");
+   for Source_Dirs use (".");
+   for Source_List_File use "libgnarl.lst";
+   for Object_Dir use "../obj-" & Libgnat_Common.Library_Kind;
+
+   for Library_Name use "gnarl";
+   for Library_Dir use "../adalib";
+   for Library_Kind use Libgnat_Common.Library_Kind;
+
+   package Compiler is
+
+      for Switches ("C") use Libgnat_Common.C_Flags;
+      for Switches ("Ada") use Libgnat_Common.Ada_Flags;
+
+      for Switches ("s-tasdeb.adb") use
+        Libgnat_Common.Ada_Flags &
+        Libgnat_Common.Force_Debug &
+        Libgnat_Common.No_Opt;
+      --  Compile s-tasdeb.o without optimization and with debug info so that
+      --  it is always possible to set conditional breakpoints on tasks.
+
+   end Compiler;
+
+end Libgnarl;
diff --git a/gcc/ada/libgnat/libada.gpr b/gcc/ada/libgnat/libada.gpr
new file mode 100644
index 00000000000..9453cae8f53
--- /dev/null
+++ b/gcc/ada/libgnat/libada.gpr
@@ -0,0 +1,77 @@
+-- This is a project file used to rebuild the GNAT run-time for debug
+-- or instrumentation purposes.
+--
+-- Here is how to use this project file:
+--
+-- 1. Create a new directory (e.g. "rts-debug"), then copy the adainclude
+--    directory from the reference runtime that you want to rebuild.
+--    You can find the relevant adainclude directory by running the command
+--    gprls [--target=<target>] [--RTS=<runtime>] and using the adainclude
+--    directory listed. For example:
+--     $ cd <reference directory>
+--     $ mkdir rts-debug
+--     $ cd rts-debug
+--     $ cp -a `gprls -v | grep adainclude` .
+--     $ cd adainclude
+--
+--    or under Windows:
+--
+--     $ mkdir adainclude
+--     $ xcopy /s /path/to/adainclude adainclude
+--     $ cd adainclude
+--
+-- 2. If needed (e.g for pragma Normalize_Scalars), create a file called
+--    gnat.adc in the adainclude directory containing the configuration pragmas
+--    you want to use to build the library, e.g.
+--
+--     $ echo "pragma Normalize_Scalars;" > gnat.adc
+--
+--    Note that this step is usually not needed, and most pragmas are not
+--    relevant to the GNAT run time.
+--
+-- 3. Determine the values of the following variables
+--    CFLAGS (back end compilation flags such as -g -O2)
+--    ADAFLAGS (front end compilation flags such as -gnatn)
+--
+-- 4. Run gprbuild on libada.gpr, e.g:
+--    $ gprbuild -p -Plibada -j0 -XCFLAGS="-O2 -g" -XADAFLAGS="-gnatn"
+--
+--    or for a cross target:
+--
+--    $ gprbuild --target=powerpc-elf -p -Plibada -j0 [...]
+--
+--    if you created a gnat.adc file at step 2, add "-XCONFIG_FILE=gnat.adc" to
+--    the gprbuild switches.
+--
+--    The above command will build libgnat.a and libgnarl.a with the given
+--    switches.
+--
+-- 4b. In order to generate shared libraries instead, add
+--    "-XLIBRARY_KIND=dynamic" to the gprbuild switches, and if you want to
+--    build both shared and static libraries, you can run gprbuild twice in
+--    a row, e.g:
+--
+--    $ gprbuild -p -Plibada -j0 -XLIBRARY_KIND=dynamic [...]
+--    $ gprbuild -p -Plibada -j0 -XLIBRARY_KIND=static [...]
+--
+-- 5. Once the above gprbuild command is successful, you can use this new
+--    runtime directory by specifying it either via the --RTS= switch on the
+--    command line or via the attribute Runtime ("Ada") in the main project
+--    file:
+--     $ gprbuild --RTS=.../rts-debug ...
+--    or
+--       for Runtime ("Ada") use ".../rts-debug";
+
+aggregate project Libada is
+   for Project_Files use ("libgnat.gpr", "libgnarl.gpr");
+
+   Config_File := External ("CONFIG_FILE", "");
+
+   package Builder is
+      case Config_File is
+         when ""     => null;
+         when others => for Global_Configuration_Pragmas use Config_File;
+      end case;
+   end Builder;
+
+end Libada;
diff --git a/gcc/ada/libgnat/libgnat.gpr b/gcc/ada/libgnat/libgnat.gpr
new file mode 100644
index 00000000000..006ff2d8da0
--- /dev/null
+++ b/gcc/ada/libgnat/libgnat.gpr
@@ -0,0 +1,69 @@
+with "libgnat_common";
+
+library project Libgnat is
+
+   for Languages use ("Ada", "C");
+   for Source_Dirs use (".");
+   for Source_List_File use "libgnat.lst";
+   for Object_Dir use "../obj-" & Libgnat_Common.Library_Kind;
+
+   for Library_Name use "gnat";
+   for Library_Dir use "../adalib";
+   for Library_Kind use Libgnat_Common.Library_Kind;
+
+   package Compiler is
+
+      for Switches ("C") use Libgnat_Common.C_Flags;
+      for Switches ("Ada") use Libgnat_Common.Ada_Flags;
+
+      for Switches ("s-traceb.adb") use
+        Libgnat_Common.Ada_Flags & Libgnat_Common.Force_Debug &
+        Libgnat_Common.No_Inline & Libgnat_Common.No_Sibling;
+      --  Force no sibling call optimization on s-traceb.o so the number of
+      --  stack frames to be skipped when computing a call chain is not
+      --  modified by optimization. We don.t want inlining, either.
+
+      for Switches ("a-except.adb") use
+        Libgnat_Common.Ada_Flags & ("-O1") &
+        Libgnat_Common.Force_Debug & Libgnat_Common.No_Inline &
+        Libgnat_Common.No_Reorder;
+      --  Force no function reordering because of the exclusion bounds
+      --  mechanism (see the source file for more detailed information).
+      --  Force debugging information so that it is always possible to set
+      --  conditional breakpoints on exceptions.
+      --  Use -O1 otherwise gdb isn.t able to get a full backtrace on mips
+      --  targets.
+
+      for Switches ("s-excdeb.adb") use
+        Libgnat_Common.Ada_Flags & Libgnat_Common.Force_Debug &
+        Libgnat_Common.No_Opt;
+      --  Compile without optimization and with debug info to let the debugger
+      --  set breakpoints and inspect subprogram parameters on exception
+      --  related events.
+
+      for Switches ("s-assert.adb") use
+        Libgnat_Common.Ada_Flags & Libgnat_Common.Force_Debug;
+      --  Force debugging information on s-assert.o so that it is always
+      --  possible to set breakpoint on assert failures.
+
+      for Switches ("a-tags.adb") use
+        Libgnat_Common.Ada_Flags & Libgnat_Common.Force_Debug;
+      --  Force debugging information on a-tags.o so that the debugger can find
+      --  the description of Ada.Tags.Type_Specific_Data.
+
+      for Switches ("s-memory.adb") use
+        Libgnat_Common.Ada_Flags & Libgnat_Common.No_Sibling;
+      --  Force no sibling call optimization on s-memory.o to avoid turning the
+      --  tail recursion in Alloc into a loop that confuses branch prediction.
+
+      for Switches ("g-debpoo.adb") use
+        Libgnat_Common.Ada_Flags & Libgnat_Common.No_Reorder;
+      --  Need to keep functions ordered on g-debpoo.o since labels are used to
+      --  exclude subprograms from traceback computation.
+
+      for Switches ("traceback.c") use
+        Libgnat_Common.C_Flags & Libgnat_Common.No_Omit;
+
+   end Compiler;
+
+end Libgnat;
diff --git a/gcc/ada/libgnat/libgnat_common.gpr b/gcc/ada/libgnat/libgnat_common.gpr
new file mode 100644
index 00000000000..63039288764
--- /dev/null
+++ b/gcc/ada/libgnat/libgnat_common.gpr
@@ -0,0 +1,19 @@
+abstract project Libgnat_Common is
+
+   Common_Flags := Split (External ("CFLAGS", "-O2 -g"), " ");
+   C_Flags      := Common_Flags &
+                   ("-I../include", "-DIN_RTS=1", "-fexceptions",
+                    "-DSTANDALONE") &
+                   External_As_List ("EXTRALIBFLAGS", " ");
+   Ada_Flags    := Common_Flags & ("-nostdinc", "-I../adainclude")
+                   & Split (External ("ADAFLAGS", "-gnatpg"), " ");
+   Library_Kind := External ("LIBRARY_KIND", "static");
+
+   No_Opt      := ("-O0");
+   Force_Debug := ("-g");
+   No_Inline   := ("-fno-inline");
+   No_Omit     := ("-fno-omit-frame-pointer");
+   No_Sibling  := ("-fno-optimize-sibling-calls");
+   No_Reorder  := ("-fno-toplevel-reorder", "-O0");
+
+end Libgnat_Common;
diff --git a/gcc/ada/libgnat/system-mingw.ads b/gcc/ada/libgnat/system-mingw.ads
index 42719e41fe4..3df80e3bf37 100644
--- a/gcc/ada/libgnat/system-mingw.ads
+++ b/gcc/ada/libgnat/system-mingw.ads
@@ -185,11 +185,6 @@ private
    --  model, but maps them using compression onto the 7 priority levels
    --  available in NT and on the 16 priority levels available in 2000/XP.
 
-   --  To replace the default values of the Underlying_Priorities mapping,
-   --  copy this source file into your build directory, edit the file to
-   --  reflect your desired behavior, and recompile using Makefile.adalib
-   --  which can be found under the adalib directory of your gnat installation
-
    pragma Linker_Options ("-Wl,--stack=0x2000000");
    --  This is used to change the default stack (32 MB) size for non tasking
    --  programs. We change this value for GNAT on Windows here because the
diff --git a/gcc/ada/tb-gcc.c b/gcc/ada/tb-gcc.c
deleted file mode 100644
index 74d0c2167af..00000000000
--- a/gcc/ada/tb-gcc.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
- *                                                                          *
- *                         GNAT RUN-TIME COMPONENTS                         *
- *                                                                          *
- *                   T R A C E B A C K - G C C t a b l e s                  *
- *                                                                          *
- *                          C Implementation File                           *
- *                                                                          *
- *          Copyright (C) 2004-2019, 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.               *
- *                                                                          *
- * You should have received a copy of the GNU General Public License and    *
- * a copy of the GCC Runtime Library Exception along with this program;     *
- * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    *
- * <http://www.gnu.org/licenses/>.                                          *
- *                                                                          *
- * GNAT was originally developed  by the GNAT team at  New York University. *
- * Extensive contributions were provided by Ada Core Technologies Inc.      *
- *                                                                          *
- ****************************************************************************/
-
-/* 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
-}
diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c
index 9e74282e11f..abbe075979c 100644
--- a/gcc/ada/tracebak.c
+++ b/gcc/ada/tracebak.c
@@ -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 --*


More information about the Gcc-cvs mailing list