]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/ada/tracebak.c
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / ada / tracebak.c
diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c
deleted file mode 100644 (file)
index 3dd7519..0000000
+++ /dev/null
@@ -1,1176 +0,0 @@
-/****************************************************************************
- *                                                                          *
- *                         GNAT COMPILER COMPONENTS                         *
- *                                                                          *
- *                            T R A C E B A C K                             *
- *                                                                          *
- *                          C Implementation File                           *
- *                                                                          *
- *                            $Revision: 1.3 $
- *                                                                          *
- *           Copyright (C) 2000-2001 Ada Core Technologies, 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 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,  59 Temple Place - Suite 330,  Boston, *
- * MA 02111-1307, 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. *
- * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
- *                                                                          *
- ****************************************************************************/
-
-/* This file contains low level support for stack unwinding using GCC intrinsic
-   functions.
-   It has been tested on the following configurations:
-   HPPA/HP-UX
-   PowerPC/AiX
-   PowerPC/VxWorks
-   Sparc/Solaris
-   i386/GNU/Linux
-   i386/Solaris
-   i386/NT
-   i386/OS2
-   i386/LynxOS
-   Alpha/VxWorks
-*/
-
-#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
-
-#define Lock_Task system__soft_links__lock_task
-extern void (*Lock_Task) PARAMS ((void));
-
-#define Unlock_Task system__soft_links__unlock_task
-extern void (*Unlock_Task) PARAMS ((void));
-
-#ifndef CURRENT_STACK_FRAME
-# define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
-#endif
-
-extern int __gnat_backtrace    PARAMS ((void **, int, void *, void *));
-
-#if defined (__hppa)
-struct layout
-{
-  void *return_address;
-  void *pad[4];
-  struct layout *next;
-};
-
-#define FRAME_LEVEL 1
-#define FRAME_OFFSET -20
-#define SKIP_FRAME 1
-#define PC_ADJUST -4
-
-/* If CURRENT is unaligned, it means that CURRENT is not a valid frame
-   pointer and we should stop popping frames. */
-
-#define STOP_FRAME(CURRENT, TOP_STACK) \
-  (((int) (CURRENT) & 0x3) != 0 && (CURRENT)->return_address == 0)
-
-/* Current implementation need to be protected against invalid memory
-   accesses */
-#define PROTECT_SEGV
-
-#elif defined (_AIX)
-struct layout
-{
-  struct layout *next;
-  void *pad;
-  void *return_address;
-};
-
-#define FRAME_LEVEL 1
-#define FRAME_OFFSET 0
-#define SKIP_FRAME 2
-#define PC_ADJUST -4
-#define STOP_FRAME(CURRENT, TOP_STACK) ((void *) (CURRENT) < (TOP_STACK))
-
-#elif defined (_ARCH_PPC) && defined (__vxworks)
-struct layout
-{
-  struct layout *next;
-  void *return_address;
-};
-
-#define FRAME_LEVEL 1
-#define FRAME_OFFSET 0
-#define SKIP_FRAME 2
-#define PC_ADJUST 0
-#define STOP_FRAME(CURRENT, TOP_STACK) ((CURRENT)->return_address == 0)
-
-#elif defined (sun) && defined (sparc)
-struct layout
-{
-  struct layout *next;
-  void *return_address;
-};
-
-#define FRAME_LEVEL 1
-#define FRAME_OFFSET (14*4)
-#define SKIP_FRAME 1
-#define PC_ADJUST 0
-#define STOP_FRAME(CURRENT, TOP_STACK) \
-  ((CURRENT)->return_address == 0|| (CURRENT)->next == 0 \
-   || (void *) (CURRENT) < (TOP_STACK))
-
-#elif defined (i386)
-struct layout
-{
-  struct layout *next;
-  void *return_address;
-};
-
-#define FRAME_LEVEL 0
-#define FRAME_OFFSET 0
-#define SKIP_FRAME 1
-#define PC_ADJUST -2
-#define STOP_FRAME(CURRENT, TOP_STACK) \
-  ((CURRENT)->return_address == 0|| (CURRENT)->next == 0  \
-   || (void *) (CURRENT) < (TOP_STACK))
-
-#elif defined (__alpha_vxworks)
-
-#define SKIP_FRAME 1
-#define PC_ADJUST -4
-
-extern void kerTaskEntry();
-
-#define STOP_FRAME \
-   (current == NULL \
-    || ((CORE_ADDR) &kerTaskEntry >= PROC_LOW_ADDR (current->proc_desc) \
-        && current->pc >= (CORE_ADDR) &kerTaskEntry))
-#endif
-
-#if !defined (PC_ADJUST)
-int
-__gnat_backtrace (array, size, exclude_min, exclude_max)
-     void **array ATTRIBUTE_UNUSED;
-     int size ATTRIBUTE_UNUSED;
-     void *exclude_min ATTRIBUTE_UNUSED;
-     void *exclude_max ATTRIBUTE_UNUSED;
-{
-  return 0;
-}
-
-#elif !defined (__alpha_vxworks)
-
-#ifdef PROTECT_SEGV
-#include <setjmp.h>
-#include <signal.h>
-
-static jmp_buf sigsegv_excp;
-
-static void
-segv_handler (ignored)
-     int ignored;
-{
-  longjmp (sigsegv_excp, 1);
-}
-#endif
-
-int
-__gnat_backtrace (array, size, exclude_min, exclude_max)
-     void **array;
-     int size;
-     void *exclude_min;
-     void *exclude_max;
-{
-  struct layout *current;
-  void *top_frame;
-  void *top_stack;
-  int cnt = 0;
-
-#ifdef PROTECT_SEGV
-  struct sigaction this_act, old_act;
-
-  /* This function is not thread safe if PROTECT_SEGV is defined, so
-     protect it */
-  (*Lock_Task) ();
-#endif
-
-  top_frame = __builtin_frame_address (FRAME_LEVEL);
-  top_stack = CURRENT_STACK_FRAME;
-  current = (struct layout *) ((size_t) top_frame + FRAME_OFFSET);
-
-#ifdef PROTECT_SEGV
-  this_act.sa_handler = segv_handler;
-  sigemptyset (&this_act.sa_mask);
-  this_act.sa_flags = 0;
-  sigaction (SIGSEGV, &this_act, &old_act);
-
-  if (setjmp (sigsegv_excp))
-    goto Done;
-#endif
-
-  /* We skip the call to this function, it makes no sense to record it.  */
-  while (cnt < SKIP_FRAME)
-    {
-      current = (struct layout *) ((size_t) current->next + FRAME_OFFSET);
-      cnt++;
-    }
-
-  cnt = 0;
-  while (cnt < size)
-    {
-      if (STOP_FRAME (current, top_stack))
-        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);
-    }
-
-#ifdef PROTECT_SEGV
- Done:
-  sigaction (SIGSEGV, &old_act, NULL);
-  (*Unlock_Task) ();
-#endif
-  return cnt;
-}
-
-#else
-/* Alpha vxWorks requires a special, complex treatment that is extracted
-   from GDB */
-
-#include <string.h>
-
-/* Register numbers of various important registers.
-   Note that most of these values are "real" register numbers,
-   and correspond to the general registers of the machine,
-   and FP_REGNUM is a "phony" register number which is too large
-   to be an actual register number as far as the user is concerned
-   but serves to get the desired value when passed to read_register.  */
-
-#define T7_REGNUM 8            /* Return address register for OSF/1 __add* */
-#define GCC_FP_REGNUM 15       /* Used by gcc as frame register */
-#define T9_REGNUM 23           /* Return address register for OSF/1 __div* */
-#define SP_REGNUM 30           /* Contains address of top of stack */
-#define RA_REGNUM 26           /* Contains return address value */
-#define FP0_REGNUM 32          /* Floating point register 0 */
-#define PC_REGNUM 64           /* Contains program counter */
-#define NUM_REGS 66
-
-#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000
-
-#define SIZEOF_FRAME_SAVED_REGS (sizeof (CORE_ADDR) * (NUM_REGS))
-#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci)
-
-#define FRAME_CHAIN(thisframe) (CORE_ADDR) alpha_frame_chain (thisframe)
-
-#define FRAME_CHAIN_VALID(CHAIN, THISFRAME)    \
-  ((CHAIN) != 0                                        \
-   && !inside_entry_file (FRAME_SAVED_PC (THISFRAME)))
-
-#define FRAME_SAVED_PC(FRAME)  (alpha_frame_saved_pc (FRAME))
-
-#define        FRAME_CHAIN_COMBINE(CHAIN, THISFRAME) (CHAIN)
-
-#define        INIT_FRAME_PC(FROMLEAF, PREV)
-
-#define INIT_FRAME_PC_FIRST(FROMLEAF, PREV) \
-  (PREV)->pc = ((FROMLEAF) ? SAVED_PC_AFTER_CALL ((PREV)->next) \
-               : (PREV)->next ? FRAME_SAVED_PC ((prev)->NEXT) : read_pc ());
-
-#define SAVED_PC_AFTER_CALL(FRAME)     alpha_saved_pc_after_call (FRAME)
-
-typedef unsigned long long int bfd_vma;
-
-typedef bfd_vma CORE_ADDR;
-
-typedef struct pdr
-{
-  bfd_vma adr;         /* memory address of start of procedure */
-  long isym;           /* start of local symbol entries */
-  long iline;          /* start of line number entries*/
-  long regmask;        /* save register mask */
-  long regoffset;      /* save register offset */
-  long iopt;           /* start of optimization symbol entries*/
-  long fregmask;       /* save floating point register mask */
-  long fregoffset;     /* save floating point register offset */
-  long frameoffset;    /* frame size */
-  short        framereg;       /* frame pointer register */
-  short        pcreg;          /* offset or reg of return pc */
-  long lnLow;          /* lowest line in the procedure */
-  long lnHigh;         /* highest line in the procedure */
-  bfd_vma cbLineOffset;        /* byte offset for this procedure from the fd base */
-  /* These fields are new for 64 bit ECOFF.  */
-  unsigned gp_prologue : 8; /* byte size of GP prologue */
-  unsigned gp_used : 1;        /* true if the procedure uses GP */
-  unsigned reg_frame : 1; /* true if register frame procedure */
-  unsigned prof : 1;   /* true if compiled with -pg */
-  unsigned reserved : 13; /* reserved: must be zero */
-  unsigned localoff : 8; /* offset of local variables from vfp */
-} PDR;
-
-typedef struct alpha_extra_func_info
-{
-  long numargs;                /* number of args to procedure (was iopt) */
-  PDR pdr;                     /* Procedure descriptor record */
-}
-*alpha_extra_func_info_t;
-
-struct frame_info
-{
-  /* Nominal address of the frame described.  See comments at FRAME_FP
-     about what this means outside the *FRAME* macros; in the *FRAME*
-     macros, it can mean whatever makes most sense for this machine.  */
-  CORE_ADDR frame;
-
-  /* Address at which execution is occurring in this frame.  For the
-     innermost frame, it's the current pc.  For other frames, it is a
-     pc saved in the next frame.  */
-  CORE_ADDR pc;
-
-  /* For each register, address of where it was saved on entry to the
-     frame, or zero if it was not saved on entry to this frame.  This
-     includes special registers such as pc and fp saved in special
-     ways in the stack frame.  The SP_REGNUM is even more special, the
-     address here is the sp for the next frame, not the address where
-     the sp was saved.  Allocated by frame_saved_regs_zalloc () which
-     is called and initialized by FRAME_INIT_SAVED_REGS. */
-  CORE_ADDR *saved_regs;       /*NUM_REGS */
-
-  int localoff;
-  int pc_reg;
-  alpha_extra_func_info_t proc_desc;
-
-  /* Pointers to the next and previous frame_info's in the frame cache.  */
-  struct frame_info *next, *prev;
-};
-
-struct frame_saved_regs
-{
-  /* For each register R (except the SP), regs[R] is the address at
-     which it was saved on entry to the frame, or zero if it was not
-     saved on entry to this frame.  This includes special registers
-     such as pc and fp saved in special ways in the stack frame.
-
-     regs[SP_REGNUM] is different.  It holds the actual SP, not the
-     address at which it was saved.  */
-
-  CORE_ADDR regs[NUM_REGS];
-};
-
-static CORE_ADDR theRegisters[32];
-
-/* Prototypes for local functions. */
-
-static CORE_ADDR read_next_frame_reg PARAMS ((struct frame_info *, int));
-static CORE_ADDR heuristic_proc_start PARAMS ((CORE_ADDR));
-static int alpha_about_to_return PARAMS ((CORE_ADDR pc));
-static void init_extra_frame_info PARAMS ((struct frame_info *));
-static CORE_ADDR alpha_frame_chain PARAMS ((struct frame_info *));
-static CORE_ADDR alpha_frame_saved_pc PARAMS ((struct frame_info *frame))
-static void *trace_alloc PARAMS ((unsigned int));
-static struct frame_info *create_new_frame PARAMS ((CORE_ADDR, CORE_ADDR));
-
-static alpha_extra_func_info_t
-heuristic_proc_desc PARAMS ((CORE_ADDR, CORE_ADDR, struct frame_info *,
-                            struct frame_saved_regs *));
-
-static alpha_extra_func_info_t
-find_proc_desc PARAMS ((CORE_ADDR, struct frame_info *,
-                       struct frame_saved_regs *));
-
-/* Heuristic_proc_start may hunt through the text section for a long
-   time across a 2400 baud serial line.  Allows the user to limit this
-   search.  */
-static unsigned int heuristic_fence_post = 1<<16;
-
-/* Layout of a stack frame on the alpha:
-
-                |                              |
- pdr members:  |  7th ... nth arg,             |
-                |  `pushed' by caller.         |
-                |                              |
-----------------|-------------------------------|<--  old_sp == vfp
-   ^  ^  ^  ^  |                               |
-   |  |  |  |  |                               |
-   |  |localoff        |  Copies of 1st .. 6th         |
-   |  |  |  |  |  argument if necessary.       |
-   |  |  |  v  |                               |
-   |  |  |  ---        |-------------------------------|<-- FRAME_LOCALS_ADDRESS
-   |  |  |      |                              |
-   |  |  |      |  Locals and temporaries.     |
-   |  |  |      |                              |
-   |  |  |      |-------------------------------|
-   |  |  |      |                              |
-   |-fregoffset        |  Saved float registers.       |
-   |  |  |      |  F9                          |
-   |  |  |      |   .                          |
-   |  |  |      |   .                          |
-   |  |  |      |  F2                          |
-   |  |  v      |                              |
-   |  |  -------|-------------------------------|
-   |  |         |                              |
-   |  |         |  Saved registers.            |
-   |  |         |  S6                          |
-   |-regoffset |   .                           |
-   |  |         |   .                          |
-   |  |         |  S0                          |
-   |  |         |  pdr.pcreg                   |
-   |  v         |                              |
-   |  ----------|-------------------------------|
-   |            |                              |
- frameoffset    |  Argument build area, gets   |
-   |            |  7th ... nth arg for any     |
-   |            |  called procedure.           |
-   v            |                              |
-   -------------|-------------------------------|<-- sp
-                |                              |            */
-
-#define PROC_LOW_ADDR(PROC) ((PROC)->pdr.adr)              /* least address */
-#define PROC_HIGH_ADDR(PROC) ((PROC)->pdr.iline)      /* upper address bound */
-#define PROC_DUMMY_FRAME(PROC) ((PROC)->pdr.cbLineOffset) /*CALL_DUMMY frame */
-#define PROC_FRAME_OFFSET(PROC) ((PROC)->pdr.frameoffset)
-#define PROC_FRAME_REG(PROC) ((PROC)->pdr.framereg)
-#define PROC_REG_MASK(PROC) ((PROC)->pdr.regmask)
-#define PROC_FREG_MASK(PROC) ((PROC)->pdr.fregmask)
-#define PROC_REG_OFFSET(PROC) ((PROC)->pdr.regoffset)
-#define PROC_FREG_OFFSET(PROC) ((PROC)->pdr.fregoffset)
-#define PROC_PC_REG(PROC) ((PROC)->pdr.pcreg)
-#define PROC_LOCALOFF(PROC) ((PROC)->pdr.localoff)
-
-/* Local storage allocation/deallocation functions.  trace_alloc does
-   a malloc, but also chains allocated blocks on trace_alloc_chain, so
-   they may all be freed on exit from __gnat_backtrace. */
-
-struct alloc_chain
-{
-  struct alloc_chain *next;
-  double x[0];
-};
-struct alloc_chain *trace_alloc_chain;
-
-static void * 
-trace_alloc (n)
-     unsigned int n;
-{
-  struct alloc_chain * result = malloc (n + sizeof(struct alloc_chain));
-
-  result->next = trace_alloc_chain;
-  trace_alloc_chain = result;
-  return (void*) result->x;
-}
-
-static void
-free_trace_alloc ()
-{
-  while (trace_alloc_chain != 0)
-    {
-      struct alloc_chain *old = trace_alloc_chain;
-
-      trace_alloc_chain = trace_alloc_chain->next;
-      free (old);
-    }
-}
-
-/* Read value at ADDR into *DEST, returning 0 if this is valid, != 0
-   otherwise. */
-
-static int
-read_memory_safe4 (addr, dest)
-     CORE_ADDR addr;
-     unsigned int *dest;
-{
-  *dest = *((unsigned int*) addr);
-  return 0;
-}
-
-/* Read value at ADDR into *DEST, returning 0 if this is valid, != 0
-   otherwise. */
-
-static int
-read_memory_safe8 (addr, dest)
-     CORE_ADDR addr;
-     CORE_ADDR *dest;
-{
-  *dest = *((CORE_ADDR*) addr);
-  return 0;
-}
-
-static CORE_ADDR
-read_register (regno)
-     int regno;
-{
-  if (regno >= 0 && regno < 31)
-    return theRegisters[regno];
-
-  return (CORE_ADDR) 0;
-}
-
-static void
-frame_saved_regs_zalloc (fi)
-     struct frame_info *fi;
-{
-  fi->saved_regs = (CORE_ADDR *) trace_alloc (SIZEOF_FRAME_SAVED_REGS);
-  memset (fi->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
-}
-
-static void *
-frame_obstack_alloc (size)
-     unsigned long size;
-{
-  return (void *) trace_alloc (size);
-}
-
-static int
-inside_entry_file (addr)
-     CORE_ADDR addr;
-{
-  if (addr == 0)
-    return 1;
-  else
-    return 0;
-}
-
-static CORE_ADDR
-alpha_saved_pc_after_call (frame)
-     struct frame_info *frame;
-{
-  CORE_ADDR pc = frame->pc;
-  alpha_extra_func_info_t proc_desc;
-  int pcreg;
-
-  proc_desc = find_proc_desc (pc, frame->next, NULL);
-  pcreg = proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM;
-
-  return read_register (pcreg);
-}
-
-/* Guaranteed to set frame->saved_regs to some values (it never leaves it
-   NULL).  */
-
-static void
-alpha_find_saved_regs (frame)
-     struct frame_info *frame;
-{
-  int ireg;
-  CORE_ADDR reg_position;
-  unsigned long mask;
-  alpha_extra_func_info_t proc_desc;
-  int returnreg;
-
-  frame_saved_regs_zalloc (frame);
-
-  /* If it is the frame for __sigtramp, the saved registers are located in a
-     sigcontext structure somewhere on the stack. __sigtramp passes a pointer
-     to the sigcontext structure on the stack.  If the stack layout for
-     __sigtramp changes, or if sigcontext offsets change, we might have to
-     update this code.  */
-
-#ifndef SIGFRAME_PC_OFF
-#define SIGFRAME_PC_OFF                (2 * 8)
-#define SIGFRAME_REGSAVE_OFF   (4 * 8)
-#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
-#endif
-
-  proc_desc = frame->proc_desc;
-  if (proc_desc == NULL)
-    /* I'm not sure how/whether this can happen.  Normally when we can't
-       find a proc_desc, we "synthesize" one using heuristic_proc_desc
-       and set the saved_regs right away.  */
-    return;
-
-  /* Fill in the offsets for the registers which gen_mask says
-     were saved.  */
-
-  reg_position = frame->frame + PROC_REG_OFFSET (proc_desc);
-  mask = PROC_REG_MASK (proc_desc);
-
-  returnreg = PROC_PC_REG (proc_desc);
-
-  /* Note that RA is always saved first, regardless of its actual
-     register number.  */
-  if (mask & (1 << returnreg))
-    {
-      frame->saved_regs[returnreg] = reg_position;
-      reg_position += 8;
-      mask &= ~(1 << returnreg);       /* Clear bit for RA so we
-                                          don't save again later. */
-    }
-
-  for (ireg = 0; ireg <= 31; ireg++)
-    if (mask & (1 << ireg))
-      {
-       frame->saved_regs[ireg] = reg_position;
-       reg_position += 8;
-      }
-
-  /* Fill in the offsets for the registers which float_mask says
-     were saved.  */
-
-  reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc);
-  mask = PROC_FREG_MASK (proc_desc);
-
-  for (ireg = 0; ireg <= 31; ireg++)
-    if (mask & (1 << ireg))
-      {
-       frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
-       reg_position += 8;
-      }
-
-  frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg];
-}
-
-static CORE_ADDR
-read_next_frame_reg (fi, regno)
-     struct frame_info *fi;
-     int regno;
-{
-  CORE_ADDR result;
-  for (; fi; fi = fi->next)
-    {
-      /* We have to get the saved sp from the sigcontext
-         if it is a signal handler frame.  */
-      if (regno == SP_REGNUM)
-       return fi->frame;
-      else
-       {
-         if (fi->saved_regs == 0)
-           alpha_find_saved_regs (fi);
-
-         if (fi->saved_regs[regno])
-           {
-             if (read_memory_safe8 (fi->saved_regs[regno], &result) == 0)
-               return result;
-             else
-               return 0;
-           }
-       }
-    }
-
-  return read_register (regno);
-}
-
-static CORE_ADDR
-alpha_frame_saved_pc (frame)
-     struct frame_info *frame;
-{
-  return read_next_frame_reg (frame, frame->pc_reg);
-}
-
-static struct alpha_extra_func_info temp_proc_desc;
-
-/* Nonzero if instruction at PC is a return instruction.  "ret
-   $zero,($ra),1" on alpha. */
-
-static int
-alpha_about_to_return (pc)
-     CORE_ADDR pc;
-{
-  int inst;
-
-  read_memory_safe4 (pc, &inst);
-  return inst == 0x6bfa8001;
-}
-
-/* A heuristically computed start address for the subprogram
-   containing address PC.   Returns 0 if none detected. */
-
-static CORE_ADDR
-heuristic_proc_start (pc)
-     CORE_ADDR pc;
-{
-  CORE_ADDR start_pc = pc;
-  CORE_ADDR fence = start_pc - heuristic_fence_post;
-
-  if (start_pc == 0)
-    return 0;
-
-  if (heuristic_fence_post == UINT_MAX
-      || fence < VM_MIN_ADDRESS)
-    fence = VM_MIN_ADDRESS;
-
-  /* search back for previous return */
-  for (start_pc -= 4; ; start_pc -= 4)
-    {
-      if (start_pc < fence)
-       return 0;
-      else if (alpha_about_to_return (start_pc))
-       break;
-    }
-
-  start_pc += 4;               /* skip return */
-  return start_pc;
-}
-
-static alpha_extra_func_info_t
-heuristic_proc_desc (start_pc, limit_pc, next_frame, saved_regs_p)
-     CORE_ADDR start_pc;
-     CORE_ADDR limit_pc;
-     struct frame_info *next_frame;
-     struct frame_saved_regs *saved_regs_p;
-{
-  CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
-  CORE_ADDR cur_pc;
-  int frame_size;
-  int has_frame_reg = 0;
-  unsigned long reg_mask = 0;
-  int pcreg = -1;
-
-  if (start_pc == 0)
-    return 0;
-
-  memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc));
-  if (saved_regs_p != 0)
-    memset (saved_regs_p, '\0', sizeof (struct frame_saved_regs));
-
-  PROC_LOW_ADDR (&temp_proc_desc) = start_pc;
-
-  if (start_pc + 200 < limit_pc)
-    limit_pc = start_pc + 200;
-
-  frame_size = 0;
-  for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4)
-    {
-      unsigned int word;
-      int status;
-
-      status = read_memory_safe4 (cur_pc, &word);
-      if (status)
-       return 0;
-
-      if ((word & 0xffff0000) == 0x23de0000)   /* lda $sp,n($sp) */
-       {
-         if (word & 0x8000)
-           frame_size += (-word) & 0xffff;
-         else
-           /* Exit loop if a positive stack adjustment is found, which
-              usually means that the stack cleanup code in the function
-              epilogue is reached.  */
-           break;
-       }
-      else if ((word & 0xfc1f0000) == 0xb41e0000       /* stq reg,n($sp) */
-              && (word & 0xffff0000) != 0xb7fe0000)    /* reg != $zero */
-       {
-         int reg = (word & 0x03e00000) >> 21;
-
-         reg_mask |= 1 << reg;
-         if (saved_regs_p != 0)
-           saved_regs_p->regs[reg] = sp + (short) word;
-
-         /* Starting with OSF/1-3.2C, the system libraries are shipped
-            without local symbols, but they still contain procedure
-            descriptors without a symbol reference. GDB is currently
-            unable to find these procedure descriptors and uses
-            heuristic_proc_desc instead.
-            As some low level compiler support routines (__div*, __add*)
-            use a non-standard return address register, we have to
-            add some heuristics to determine the return address register,
-            or stepping over these routines will fail.
-            Usually the return address register is the first register
-            saved on the stack, but assembler optimization might
-            rearrange the register saves.
-            So we recognize only a few registers (t7, t9, ra) within
-            the procedure prologue as valid return address registers.
-            If we encounter a return instruction, we extract the
-            the return address register from it.
-
-            FIXME: Rewriting GDB to access the procedure descriptors,
-            e.g. via the minimal symbol table, might obviate this hack.  */
-         if (pcreg == -1
-             && cur_pc < (start_pc + 80)
-             && (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM))
-           pcreg = reg;
-       }
-      else if ((word & 0xffe0ffff) == 0x6be08001)      /* ret zero,reg,1 */
-       pcreg = (word >> 16) & 0x1f;
-      else if (word == 0x47de040f)     /* bis sp,sp fp */
-       has_frame_reg = 1;
-    }
-
-  if (pcreg == -1)
-    {
-      /* If we haven't found a valid return address register yet,
-         keep searching in the procedure prologue.  */
-      while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80))
-       {
-         unsigned int word;
-
-         if (read_memory_safe4 (cur_pc, &word))
-           break;
-         cur_pc += 4;
-
-         if ((word & 0xfc1f0000) == 0xb41e0000         /* stq reg,n($sp) */
-             && (word & 0xffff0000) != 0xb7fe0000)     /* reg != $zero */
-           {
-             int reg = (word & 0x03e00000) >> 21;
-
-             if (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM)
-               {
-                 pcreg = reg;
-                 break;
-               }
-           }
-         else if ((word & 0xffe0ffff) == 0x6be08001)   /* ret zero,reg,1 */
-           {
-             pcreg = (word >> 16) & 0x1f;
-             break;
-           }
-       }
-    }
-
-  if (has_frame_reg)
-    PROC_FRAME_REG (&temp_proc_desc) = GCC_FP_REGNUM;
-  else
-    PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
-
-  PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
-  PROC_REG_MASK (&temp_proc_desc) = reg_mask;
-  PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? RA_REGNUM : pcreg;
-  PROC_LOCALOFF (&temp_proc_desc) = 0; /* XXX - bogus */
-
-  return &temp_proc_desc;
-}
-
-static alpha_extra_func_info_t
-find_proc_desc (pc, next_frame, saved_regs)
-     CORE_ADDR pc;
-     struct frame_info *next_frame;
-     struct frame_saved_regs *saved_regs;
-{
-  CORE_ADDR startaddr;
-
-  /* If heuristic_fence_post is non-zero, determine the procedure
-     start address by examining the instructions.
-     This allows us to find the start address of static functions which
-     have no symbolic information, as startaddr would have been set to
-     the preceding global function start address by the
-     find_pc_partial_function call above.  */
-  startaddr = heuristic_proc_start (pc);
-
-  return heuristic_proc_desc (startaddr, pc, next_frame, saved_regs);
-}
-
-static CORE_ADDR
-alpha_frame_chain (frame)
-     struct frame_info *frame;
-{
-  alpha_extra_func_info_t proc_desc;
-  CORE_ADDR saved_pc = FRAME_SAVED_PC (frame);
-
-  if (saved_pc == 0 || inside_entry_file (saved_pc))
-    return 0;
-
-  proc_desc = find_proc_desc (saved_pc, frame, NULL);
-  if (!proc_desc)
-    return 0;
-
-  /* If no frame pointer and frame size is zero, we must be at end
-     of stack (or otherwise hosed).  If we don't check frame size,
-     we loop forever if we see a zero size frame.  */
-  if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
-      && PROC_FRAME_OFFSET (proc_desc) == 0)
-    return 0;
-  else
-    return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
-      + PROC_FRAME_OFFSET (proc_desc);
-}
-
-static void
-init_extra_frame_info (frame)
-     struct frame_info *frame;
-{
-  struct frame_saved_regs temp_saved_regs;
-  alpha_extra_func_info_t proc_desc = 
-    find_proc_desc (frame->pc, frame->next, &temp_saved_regs);
-
-  frame->saved_regs = NULL;
-  frame->localoff = 0;
-  frame->pc_reg = RA_REGNUM;
-  frame->proc_desc = proc_desc;
-
-  if (proc_desc)
-    {
-      /* Get the locals offset and the saved pc register from the
-         procedure descriptor, they are valid even if we are in the
-         middle of the prologue.  */
-      frame->localoff = PROC_LOCALOFF (proc_desc);
-      frame->pc_reg = PROC_PC_REG (proc_desc);
-
-      /* Fixup frame-pointer - only needed for top frame */
-
-      /* This may not be quite right, if proc has a real frame register.
-         Get the value of the frame relative sp, procedure might have been
-         interrupted by a signal at it's very start.  */
-      if (frame->pc == PROC_LOW_ADDR (proc_desc))
-       frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
-      else
-       frame->frame
-         = (read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc))
-            + PROC_FRAME_OFFSET (proc_desc));
-
-      frame->saved_regs
-       = (CORE_ADDR *) frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
-      memcpy
-        (frame->saved_regs, temp_saved_regs.regs, SIZEOF_FRAME_SAVED_REGS);
-      frame->saved_regs[PC_REGNUM] = frame->saved_regs[RA_REGNUM];
-    }
-}
-
-/* Create an arbitrary (i.e. address specified by user) or innermost frame.
-   Always returns a non-NULL value.  */
-
-static struct frame_info *
-create_new_frame (addr, pc)
-     CORE_ADDR addr;
-     CORE_ADDR pc;
-{
-  struct frame_info *fi;
-
-  fi = (struct frame_info *)
-    trace_alloc (sizeof (struct frame_info));
-
-  /* Arbitrary frame */
-  fi->next = NULL;
-  fi->prev = NULL;
-  fi->frame = addr;
-  fi->pc = pc;
-
-#ifdef INIT_EXTRA_FRAME_INFO
-  INIT_EXTRA_FRAME_INFO (0, fi);
-#endif
-
-  return fi;
-}
-
-static CORE_ADDR current_pc;
-
-static void
-set_current_pc ()
-{
-  current_pc = (CORE_ADDR) __builtin_return_address (0);
-}
-
-static CORE_ADDR
-read_pc ()
-{
-  return current_pc;
-}
-
-static struct frame_info *
-get_current_frame ()
-{
-  return create_new_frame (0, read_pc ());
-}
-
-/* Return the frame that called FI.
-   If FI is the original frame (it has no caller), return 0.  */
-
-static struct frame_info *
-get_prev_frame (next_frame)
-     struct frame_info *next_frame;
-{
-  CORE_ADDR address = 0;
-  struct frame_info *prev;
-  int fromleaf = 0;
-
-  /* If we have the prev one, return it */
-  if (next_frame->prev)
-    return next_frame->prev;
-
-  /* On some machines it is possible to call a function without
-     setting up a stack frame for it.  On these machines, we
-     define this macro to take two args; a frameinfo pointer
-     identifying a frame and a variable to set or clear if it is
-     or isn't leafless.  */
-
-  /* Two macros defined in tm.h specify the machine-dependent
-     actions to be performed here.
-
-     First, get the frame's chain-pointer.  If that is zero, the frame
-     is the outermost frame or a leaf called by the outermost frame.
-     This means that if start calls main without a frame, we'll return
-     0 (which is fine anyway).
-
-     Nope; there's a problem.  This also returns when the current
-     routine is a leaf of main.  This is unacceptable.  We move
-     this to after the ffi test; I'd rather have backtraces from
-     start go curfluy than have an abort called from main not show
-     main.  */
-
-  address = FRAME_CHAIN (next_frame);
-  if (!FRAME_CHAIN_VALID (address, next_frame))
-    return 0;
-  address = FRAME_CHAIN_COMBINE (address, next_frame);
-
-  if (address == 0)
-    return 0;
-
-  prev = (struct frame_info *) trace_alloc (sizeof (struct frame_info));
-
-  prev->saved_regs = NULL;
-  if (next_frame)
-    next_frame->prev = prev;
-
-  prev->next = next_frame;
-  prev->prev = (struct frame_info *) 0;
-  prev->frame = address;
-
-  /* This change should not be needed, FIXME!  We should
-     determine whether any targets *need* INIT_FRAME_PC to happen
-     after INIT_EXTRA_FRAME_INFO and come up with a simple way to
-     express what goes on here.
-
-     INIT_EXTRA_FRAME_INFO is called from two places: create_new_frame
-     (where the PC is already set up) and here (where it isn't).
-     INIT_FRAME_PC is only called from here, always after
-     INIT_EXTRA_FRAME_INFO.
-
-     The catch is the MIPS, where INIT_EXTRA_FRAME_INFO requires the PC
-     value (which hasn't been set yet).  Some other machines appear to
-     require INIT_EXTRA_FRAME_INFO before they can do INIT_FRAME_PC.  Phoo.
-
-     We shouldn't need INIT_FRAME_PC_FIRST to add more complication to
-     an already overcomplicated part of GDB.   gnu@cygnus.com, 15Sep92.
-
-     Assuming that some machines need INIT_FRAME_PC after
-     INIT_EXTRA_FRAME_INFO, one possible scheme:
-
-     SETUP_INNERMOST_FRAME()
-     Default version is just create_new_frame (read_fp ()),
-     read_pc ()).  Machines with extra frame info would do that (or the
-     local equivalent) and then set the extra fields.
-     INIT_PREV_FRAME(fromleaf, prev)
-     Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC.  This should
-     also return a flag saying whether to keep the new frame, or
-     whether to discard it, because on some machines (e.g.  mips) it
-     is really awkward to have FRAME_CHAIN_VALID called *before*
-     INIT_EXTRA_FRAME_INFO (there is no good way to get information
-     deduced in FRAME_CHAIN_VALID into the extra fields of the new frame).
-     std_frame_pc(fromleaf, prev)
-     This is the default setting for INIT_PREV_FRAME.  It just does what
-     the default INIT_FRAME_PC does.  Some machines will call it from
-     INIT_PREV_FRAME (either at the beginning, the end, or in the middle).
-     Some machines won't use it.
-     kingdon@cygnus.com, 13Apr93, 31Jan94, 14Dec94.  */
-
-#ifdef INIT_FRAME_PC_FIRST
-  INIT_FRAME_PC_FIRST (fromleaf, prev);
-#endif
-
-#ifdef INIT_EXTRA_FRAME_INFO
-  INIT_EXTRA_FRAME_INFO (fromleaf, prev);
-#endif
-
-  /* This entry is in the frame queue now, which is good since
-     FRAME_SAVED_PC may use that queue to figure out its value
-     (see tm-sparc.h).  We want the pc saved in the inferior frame. */
-  INIT_FRAME_PC (fromleaf, prev);
-
-  /* If ->frame and ->pc are unchanged, we are in the process of getting
-     ourselves into an infinite backtrace.  Some architectures check this
-     in FRAME_CHAIN or thereabouts, but it seems like there is no reason
-     this can't be an architecture-independent check.  */
-  if (next_frame != NULL)
-    {
-      if (prev->frame == next_frame->frame
-         && prev->pc == next_frame->pc)
-       {
-         next_frame->prev = NULL;
-         free (prev);
-         return NULL;
-       }
-    }
-
-  return prev;
-}
-
-#define SAVE(regno,disp) \
-    "stq $" #regno ", " #disp "(%0)\n" 
-
-int
-__gnat_backtrace (array, size, exclude_min, exclude_max)
-     void **array;
-     int size;
-     void *exclude_min;
-     void *exclude_max;
-{
-  struct frame_info* top;
-  struct frame_info* current;
-  int cnt;
-
-  /* This function is not thread safe, protect it */
-  (*Lock_Task) ();
-  asm volatile (
-      SAVE (9,72)
-      SAVE (10,80)
-      SAVE (11,88)
-      SAVE (12,96)
-      SAVE (13,104)
-      SAVE (14,112)
-      SAVE (15,120)
-      SAVE (16,128)
-      SAVE (17,136)
-      SAVE (18,144)
-      SAVE (19,152)
-      SAVE (20,160)
-      SAVE (21,168)
-      SAVE (22,176)
-      SAVE (23,184)
-      SAVE (24,192)
-      SAVE (25,200)
-      SAVE (26,208)
-      SAVE (27,216)
-      SAVE (28,224)
-      SAVE (29,232)
-      SAVE (30,240)
-      : : "r" (&theRegisters));
-
-  trace_alloc_chain = NULL;
-  set_current_pc ();
-
-  top = current = get_current_frame ();
-  cnt = 0;
-
-  /* We skip the call to this function, it makes no sense to record it.  */
-  for (cnt = 0; cnt < SKIP_FRAME; cnt += 1) {
-    current = get_prev_frame (current);
-  }
-
-  cnt = 0;
-  while (cnt < size)
-    {
-      if (STOP_FRAME)
-        break;
-
-      if (current->pc < (CORE_ADDR) exclude_min
-         || current->pc > (CORE_ADDR) exclude_max)
-        array[cnt++] = (void*) (current->pc + PC_ADJUST);
-
-      current = get_prev_frame (current);
-    }
-
-  free_trace_alloc ();
-  (*Unlock_Task) ();
-
-  return cnt;
-}
-#endif