aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.2.1/gcc/ada/tracebak.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.2.1/gcc/ada/tracebak.c')
-rw-r--r--gcc-4.2.1/gcc/ada/tracebak.c501
1 files changed, 0 insertions, 501 deletions
diff --git a/gcc-4.2.1/gcc/ada/tracebak.c b/gcc-4.2.1/gcc/ada/tracebak.c
deleted file mode 100644
index 9c25d1ee4..000000000
--- a/gcc-4.2.1/gcc/ada/tracebak.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/****************************************************************************
- * *
- * GNAT COMPILER COMPONENTS *
- * *
- * T R A C E B A C K *
- * *
- * C Implementation File *
- * *
- * Copyright (C) 2000-2006, AdaCore *
- * *
- * 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 2, 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. See the GNU General Public License *
- * for more details. You should have received a copy of the GNU General *
- * Public License distributed with GNAT; see file COPYING. If not, write *
- * to the Free Software Foundation, 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301, USA. *
- * *
- * As a special exception, if you link this file with other files to *
- * produce an executable, this file does not by itself cause the resulting *
- * executable to be covered by the GNU General Public License. This except- *
- * ion does not however invalidate any other reasons why the executable *
- * file might be covered by the GNU Public License. *
- * *
- * GNAT was originally developed by the GNAT team at New York University. *
- * Extensive contributions were provided by Ada Core Technologies Inc. *
- * *
- ****************************************************************************/
-
-/* This file contains low level support for stack unwinding using GCC intrinsic
- functions.
- It has been tested on the following configurations:
- PowerPC/AiX
- PowerPC/VxWorks
- SPARC/Solaris
- i386/GNU/Linux
- i386/Solaris
- i386/NT
- i386/OS2
- i386/LynxOS
- Alpha/VxWorks
- Alpha/VMS
-*/
-
-#ifdef __alpha_vxworks
-#include "vxWorks.h"
-#endif
-
-#ifdef IN_RTS
-#define POSIX
-#include "tconfig.h"
-#include "tsystem.h"
-#else
-#include "config.h"
-#include "system.h"
-#endif
-
-extern int __gnat_backtrace (void **, int, void *, void *, int);
-
-/* The point is to provide an implementation of the __gnat_backtrace function
- above, called by the default implementation of the System.Traceback package.
-
- We first have a series of target specific implementations, each included
- from a separate C file for readability purposes.
-
- Then come two flavors of a generic implementation: one relying on static
- assumptions about the frame layout, and the other one using the GCC EH
- infrastructure. The former uses a whole set of macros and structures which
- may be tailored on a per target basis, and is activated as soon as
- USE_GENERIC_UNWINDER is defined. The latter uses a small subset of the
- macro definitions and is activated when USE_GCC_UNWINDER is defined. It is
- only available post GCC 3.3.
-
- Finally, there is a default dummy implementation, necessary to make the
- linker happy on platforms where the feature is not supported, but where the
- function is still referenced by the default System.Traceback. */
-
-#define Lock_Task system__soft_links__lock_task
-extern void (*Lock_Task) (void);
-
-#define Unlock_Task system__soft_links__unlock_task
-extern void (*Unlock_Task) (void);
-
-/*-------------------------------------*
- *-- Target specific implementations --*
- *-------------------------------------*/
-
-#if defined (__alpha_vxworks)
-
-#include "tb-alvxw.c"
-
-#elif defined (__ALPHA) && defined (__VMS__)
-
-#include "tb-alvms.c"
-
-#else
-/* No target specific implementation. */
-
-/*----------------------------------------------------------------*
- *-- Target specific definitions for the generic implementation --*
- *----------------------------------------------------------------*/
-
-/* The stack layout is specified by the target ABI. The "generic" scheme is
- based on the following assumption:
-
- The stack layout from some frame pointer is such that the information
- required to compute the backtrace is available at static offsets.
-
- For a given frame, the information we are interested in is the saved return
- address (somewhere after the call instruction in the caller) and a pointer
- to the caller's frame. The former is the base of the call chain information
- we store in the tracebacks array. The latter allows us to loop over the
- successive frames in the chain.
-
- To initiate the process, we retrieve an initial frame pointer using the
- appropriate GCC builtin (__builtin_frame_address).
-
- This scheme is unfortunately not applicable on every target because the
- stack layout is not necessarily regular (static) enough. On targets where
- this scheme applies, the implementation relies on the following items:
-
- o struct layout, describing the expected stack data layout relevant to the
- information we are interested in,
-
- o FRAME_OFFSET, the offset, from a given frame pointer, at which this
- layout will be found,
-
- o FRAME_LEVEL, controls how many frames up we get at to start with,
- from the initial frame pointer we compute by way of the GCC builtin,
-
- 0 is most often the appropriate value. 1 may be necessary on targets
- where return addresses are saved by a function in it's caller's frame
- (e.g. PPC).
-
- o PC_ADJUST, to account for the difference between a call point (address
- of a call instruction), which is what we want in the output array, and
- the associated return address, which is what we retrieve from the stack.
-
- o STOP_FRAME, to decide wether we reached the top of the call chain, and
- thus if the process shall stop.
-
- :
- : stack
- | +----------------+
- | +-------->| : |
- | | | (FRAME_OFFSET) |
- | | | : | (PC_ADJUST)
- | | layout:| return_address ----------------+
- | | | .... | |
- +--------------- next_frame | |
- | | .... | |
- | | | |
- | +----------------+ | +-----+
- | | : |<- Base fp | | : |
- | | (FRAME_OFFSET) | (FRAME_LEVEL) | | : |
- | | : | +---> | [1]
- | layout:| return_address --------------------> | [0]
- | | ... | (PC_ADJUST) +-----+
- +---------- next_frame | traceback[]
- | ... |
- | |
- +----------------+
-
- o BASE_SKIP,
-
- Since we inherently deal with return addresses, there is an implicit shift
- by at least one for the initial point we are able to observe in the chain.
-
- On some targets (e.g. sparc-solaris), the first return address we can
- easily get without special code is even our caller's return address, so
- there is a initial shift of two.
-
- BASE_SKIP represents this initial shift, which is the minimal "skip_frames"
- value we support. We could add special code for the skip_frames < BASE_SKIP
- cases. This is not done currently because there is virtually no situation
- in which this would be useful.
-
- Finally, to account for some ABI specificities, a target may (but does
- not have to) define:
-
- o FORCE_CALL, to force a call to a dummy function at the very beginning
- of the computation. See the PPC AIX target for an example where this
- is useful.
-
- o FETCH_UP_FRAME, to force an invocation of __builtin_frame_address with a
- positive argument right after a possibly forced call even if FRAME_LEVEL
- is 0. See the SPARC Solaris case for an example where this is useful.
-
- */
-
-/*--------------------------- PPC AIX/Darwin ----------------------------*/
-
-#if ((defined (_POWER) && defined (_AIX)) || \
-(defined (__ppc__) && defined (__APPLE__)))
-
-#define USE_GENERIC_UNWINDER
-
-struct layout
-{
- struct layout *next;
- void *pad;
- void *return_address;
-};
-
-#define FRAME_OFFSET 0
-#define PC_ADJUST -4
-#define STOP_FRAME(CURRENT, TOP_STACK) ((void *) (CURRENT) < (TOP_STACK))
-
-/* The PPC ABI has an interesting specificity: the return address saved by a
- function is located in it's caller's frame, and the save operation only
- takes place if the function performs a call.
-
- To have __gnat_backtrace retrieve its own return address, we then
- define ... */
-
-#define FORCE_CALL 1
-#define FRAME_LEVEL 1
-
-#define BASE_SKIP 1
-
-/*---------------------------- PPC VxWorks------------------------------*/
-
-#elif defined (_ARCH_PPC) && defined (__vxworks)
-
-#define USE_GENERIC_UNWINDER
-
-struct layout
-{
- struct layout *next;
- void *return_address;
-};
-
-#define FORCE_CALL 1
-#define FRAME_LEVEL 1
-/* See the PPC AIX case for an explanation of these values. */
-
-#define FRAME_OFFSET 0
-#define PC_ADJUST -4
-#define STOP_FRAME(CURRENT, TOP_STACK) ((CURRENT)->next == 0)
-
-#define BASE_SKIP 1
-
-/*-------------------------- SPARC Solaris -----------------------------*/
-
-#elif defined (sun) && defined (sparc)
-
-#define USE_GENERIC_UNWINDER
-
-/* These definitions are inspired from the Appendix D (Software
- Considerations) of the SPARC V8 architecture manual. */
-
-struct layout
-{
- struct layout *next;
- void *return_address;
-};
-
-#ifdef __arch64__
-#define STACK_BIAS 2047 /* V9 ABI */
-#else
-#define STACK_BIAS 0 /* V8 ABI */
-#endif
-
-#define FRAME_LEVEL 0
-#define FRAME_OFFSET (14 * sizeof (void*) + STACK_BIAS)
-#define PC_ADJUST 0
-#define STOP_FRAME(CURRENT, TOP_STACK) \
- ((CURRENT)->return_address == 0|| (CURRENT)->next == 0 \
- || (void *) (CURRENT) < (TOP_STACK))
-
-/* The sparc register windows need to be flushed before we may access them
- from the stack. This is achieved by way of builtin_frame_address only
- when the "count" argument is positive, so force at least one such call. */
-#define FETCH_UP_FRAME_ADDRESS
-
-#define BASE_SKIP 2
-/* From the frame pointer of frame N, we are accessing the flushed register
- window of frame N-1 (positive offset from fp), in which we retrieve the
- saved return address. We then end up with our caller's return address. */
-
-/*------------------------------- x86 ----------------------------------*/
-
-#elif defined (i386)
-
-#ifdef __WIN32
-#include <windows.h>
-#define IS_BAD_PTR(ptr) (IsBadCodePtr((void *)ptr))
-#else
-#define IS_BAD_PTR(ptr) 0
-#endif
-
-#define USE_GENERIC_UNWINDER
-
-struct layout
-{
- struct layout *next;
- void *return_address;
-};
-
-#define LOWEST_ADDR 0
-#define FRAME_LEVEL 1
-/* builtin_frame_address (1) is expected to work on this target, and (0) might
- return the soft stack pointer, which does not designate a location where a
- backchain and a return address might be found. */
-
-#define FRAME_OFFSET 0
-#define PC_ADJUST -2
-#define STOP_FRAME(CURRENT, TOP_STACK) \
- (IS_BAD_PTR((long)(CURRENT)->return_address) \
- || (unsigned int)(CURRENT)->return_address < LOWEST_ADDR \
- || (CURRENT)->return_address == 0|| (CURRENT)->next == 0 \
- || (void *) (CURRENT) < (TOP_STACK))
-
-#define BASE_SKIP (1+FRAME_LEVEL)
-
-/* On i386 architecture we check that at the call point we really have a call
- insn. Possible call instructions are:
-
- call addr16 E8 xx xx xx xx
- call reg FF Dx
- call off(reg) FF xx xx
- lcall addr seg 9A xx xx xx xx xx xx
-
- This check will not catch all cases but it will increase the backtrace
- reliability on this architecture.
-*/
-
-#define VALID_STACK_FRAME(ptr) \
- (!IS_BAD_PTR(ptr) \
- && (((*((ptr) - 3) & 0xff) == 0xe8) \
- || ((*((ptr) - 5) & 0xff) == 0x9a) \
- || ((*((ptr) - 1) & 0xff) == 0xff) \
- || (((*(ptr) & 0xd0ff) == 0xd0ff))))
-
-/*----------------------------- x86_64 ---------------------------------*/
-
-#elif defined (__x86_64__)
-
-#define USE_GCC_UNWINDER
-/* The generic unwinder is not used for this target because it is based
- on frame layout assumptions that are not reliable on this target (the
- rbp register is very likely used for something else than storing the
- frame pointer in optimized code). Hence, we use the GCC unwinder
- based on DWARF 2 call frame information, although it has the drawback
- of not being able to unwind through frames compiled without DWARF 2
- information.
-*/
-
-#define PC_ADJUST -2
-/* The minimum size of call instructions on this architecture is 2 bytes */
-
-/*----------------------------- ia64 ---------------------------------*/
-
-#elif defined (__ia64__) && (defined (linux) || defined (__hpux__))
-
-#define USE_GCC_UNWINDER
-/* Use _Unwind_Backtrace driven exceptions on ia64 HP-UX and ia64
- GNU/Linux, where _Unwind_Backtrace is provided by the system unwind
- library. On HP-UX 11.23 this requires patch PHSS_33352, which adds
- _Unwind_Backtrace to the system unwind library. */
-
-#define PC_ADJUST -16
-/* Every call on ia64 is part of a 128 bit bundle, so an adjustment of
- minus 16 bytes from the point of return finds the address of the
- previous bundle. */
-
-#endif
-
-/*---------------------------------------------------------------------*
- *-- The post GCC 3.3 infrastructure based implementation --*
- *---------------------------------------------------------------------*/
-
-#if defined (USE_GCC_UNWINDER) && (__GNUC__ * 10 + __GNUC_MINOR__ > 33)
-
-/* Conditioning the inclusion on the GCC version is useful to avoid bootstrap
- path problems, since the included file refers to post 3.3 functions in
- libgcc, and the stage1 compiler is unlikely to be linked against a post 3.3
- library. It actually disables the support for backtraces in this compiler
- for targets defining USE_GCC_UNWINDER, which is OK since we don't use the
- traceback capability in the compiler anyway.
-
- The condition is expressed the way above because we cannot reliably rely on
- any other macro from the base compiler when compiling stage1. */
-
-#include "tb-gcc.c"
-
-/*------------------------------------------------------------------*
- *-- The generic implementation based on frame layout assumptions --*
- *------------------------------------------------------------------*/
-
-#elif defined (USE_GENERIC_UNWINDER)
-
-#ifndef CURRENT_STACK_FRAME
-# define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
-#endif
-
-#ifndef VALID_STACK_FRAME
-#define VALID_STACK_FRAME(ptr) 1
-#endif
-
-#ifndef MAX
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
-#endif
-
-#ifndef FORCE_CALL
-#define FORCE_CALL 0
-#endif
-
-/* Make sure the function is not inlined. */
-static void forced_callee (void) __attribute__ ((noinline));
-
-static void forced_callee (void)
-{
- /* Make sure the function is not pure. */
- volatile int i __attribute__ ((unused)) = 0;
-}
-
-int
-__gnat_backtrace (void **array,
- int size,
- void *exclude_min,
- void *exclude_max,
- int skip_frames)
-{
- struct layout *current;
- void *top_frame;
- void *top_stack;
- int cnt = 0;
-
- if (FORCE_CALL)
- forced_callee ();
-
- /* Force a call to builtin_frame_address with a positive argument
- if required. This is necessary e.g. on sparc to have the register
- windows flushed before we attempt to access them on the stack. */
-#if defined (FETCH_UP_FRAME_ADDRESS) && (FRAME_LEVEL == 0)
- __builtin_frame_address (1);
-#endif
-
- top_frame = __builtin_frame_address (FRAME_LEVEL);
- top_stack = CURRENT_STACK_FRAME;
- current = (struct layout *) ((size_t) top_frame + FRAME_OFFSET);
-
- /* Skip the number of calls we have been requested to skip, accounting for
- the BASE_SKIP parameter.
-
- FRAME_LEVEL is meaningless for the count adjustment. It impacts where we
- start retrieving data from, but how many frames "up" we start at is in
- BASE_SKIP by definition. */
-
- skip_frames = MAX (0, skip_frames - BASE_SKIP);
-
- while (cnt < skip_frames)
- {
- current = (struct layout *) ((size_t) current->next + FRAME_OFFSET);
- cnt++;
- }
-
- cnt = 0;
- while (cnt < size)
- {
- if (STOP_FRAME (current, top_stack) ||
- !VALID_STACK_FRAME((char *)(current->return_address + PC_ADJUST)))
- break;
-
- if (current->return_address < exclude_min
- || current->return_address > exclude_max)
- array[cnt++] = current->return_address + PC_ADJUST;
-
- current = (struct layout *) ((size_t) current->next + FRAME_OFFSET);
- }
-
- return cnt;
-}
-
-#else
-
-/* No target specific implementation and neither USE_GCC_UNWINDER not
- USE_GCC_UNWINDER defined. */
-
-/*------------------------------*
- *-- The dummy implementation --*
- *------------------------------*/
-
-int
-__gnat_backtrace (array, size, exclude_min, exclude_max, skip_frames)
- void **array ATTRIBUTE_UNUSED;
- int size ATTRIBUTE_UNUSED;
- void *exclude_min ATTRIBUTE_UNUSED;
- void *exclude_max ATTRIBUTE_UNUSED;
- int skip_frames ATTRIBUTE_UNUSED;
-{
- return 0;
-}
-
-#endif
-
-#endif