1124961Ssobomax/* Definitions for frame unwinder, for GDB, the GNU debugger.
2124961Ssobomax
3138722Snjl   Copyright 2003 Free Software Foundation, Inc.
4124961Ssobomax
5124961Ssobomax   This file is part of GDB.
6124961Ssobomax
7124961Ssobomax   This program is free software; you can redistribute it and/or modify
8124961Ssobomax   it under the terms of the GNU General Public License as published by
9124961Ssobomax   the Free Software Foundation; either version 2 of the License, or
10124961Ssobomax   (at your option) any later version.
11124961Ssobomax
12124961Ssobomax   This program is distributed in the hope that it will be useful,
13124961Ssobomax   but WITHOUT ANY WARRANTY; without even the implied warranty of
14124961Ssobomax   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15124961Ssobomax   GNU General Public License for more details.
16124961Ssobomax
17124961Ssobomax   You should have received a copy of the GNU General Public License
18124961Ssobomax   along with this program; if not, write to the Free Software
19124961Ssobomax   Foundation, Inc., 59 Temple Place - Suite 330,
20124961Ssobomax   Boston, MA 02111-1307, USA.  */
21124961Ssobomax
22124961Ssobomax#include "defs.h"
23124961Ssobomax#include "frame.h"
24124961Ssobomax#include "frame-unwind.h"
25124961Ssobomax#include "gdb_assert.h"
26124961Ssobomax#include "dummy-frame.h"
27124961Ssobomax
28124961Ssobomaxstatic struct gdbarch_data *frame_unwind_data;
29124961Ssobomax
30124961Ssobomaxframe_unwind_sniffer_ftype *kgdb_sniffer_kluge;
31124961Ssobomax
32124961Ssobomaxstruct frame_unwind_table
33124961Ssobomax{
34124961Ssobomax  frame_unwind_sniffer_ftype **sniffer;
35124961Ssobomax  int nr;
36124961Ssobomax};
37124961Ssobomax
38124961Ssobomax/* Append a predicate to the end of the table.  */
39124961Ssobomaxstatic void
40124961Ssobomaxappend_predicate (struct frame_unwind_table *table,
41124961Ssobomax		  frame_unwind_sniffer_ftype *sniffer)
42124961Ssobomax{
43124961Ssobomax  table->sniffer = xrealloc (table->sniffer, ((table->nr + 1)
44124961Ssobomax					      * sizeof (frame_unwind_sniffer_ftype *)));
45124961Ssobomax  table->sniffer[table->nr] = sniffer;
46124961Ssobomax  table->nr++;
47124961Ssobomax}
48124961Ssobomax
49185341Sjkimstatic void *
50124961Ssobomaxframe_unwind_init (struct gdbarch *gdbarch)
51124961Ssobomax{
52124961Ssobomax  struct frame_unwind_table *table = XCALLOC (1, struct frame_unwind_table);
53124961Ssobomax  append_predicate (table, dummy_frame_sniffer);
54124961Ssobomax  if (kgdb_sniffer_kluge != NULL)
55124961Ssobomax    append_predicate (table, kgdb_sniffer_kluge);
56124961Ssobomax  return table;
57124961Ssobomax}
58124961Ssobomax
59124961Ssobomaxvoid
60124961Ssobomaxframe_unwind_append_sniffer (struct gdbarch *gdbarch,
61124961Ssobomax			     frame_unwind_sniffer_ftype *sniffer)
62124961Ssobomax{
63124961Ssobomax  struct frame_unwind_table *table =
64124961Ssobomax    gdbarch_data (gdbarch, frame_unwind_data);
65124961Ssobomax  if (table == NULL)
66124961Ssobomax    {
67124961Ssobomax      /* ULGH, called during architecture initialization.  Patch
68124961Ssobomax         things up.  */
69124961Ssobomax      table = frame_unwind_init (gdbarch);
70124961Ssobomax      set_gdbarch_data (gdbarch, frame_unwind_data, table);
71124961Ssobomax    }
72124961Ssobomax  append_predicate (table, sniffer);
73124961Ssobomax}
74124961Ssobomax
75124961Ssobomaxconst struct frame_unwind *
76124961Ssobomaxframe_unwind_find_by_frame (struct frame_info *next_frame)
77124961Ssobomax{
78124961Ssobomax  int i;
79124961Ssobomax  struct gdbarch *gdbarch = get_frame_arch (next_frame);
80124961Ssobomax  struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
81124961Ssobomax  if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES && legacy_frame_p (gdbarch))
82124961Ssobomax    /* Seriously old code.  Don't even try to use this new mechanism.
83124961Ssobomax       (Note: The variable USE_GENERIC_DUMMY_FRAMES is deprecated, not
84124961Ssobomax       the dummy frame mechanism.  All architectures should be using
85124961Ssobomax       generic dummy frames).  */
86124961Ssobomax    return legacy_saved_regs_unwind;
87214346Sjhb  for (i = 0; i < table->nr; i++)
88124961Ssobomax    {
89124961Ssobomax      const struct frame_unwind *desc;
90124961Ssobomax      desc = table->sniffer[i] (next_frame);
91214346Sjhb      if (desc != NULL)
92124961Ssobomax	return desc;
93124961Ssobomax    }
94124961Ssobomax  return legacy_saved_regs_unwind;
95124961Ssobomax}
96124961Ssobomax
97124961Ssobomaxextern initialize_file_ftype _initialize_frame_unwind; /* -Wmissing-prototypes */
98124961Ssobomax
99124961Ssobomaxvoid
100124961Ssobomax_initialize_frame_unwind (void)
101124961Ssobomax{
102124961Ssobomax  frame_unwind_data = register_gdbarch_data (frame_unwind_init);
103124961Ssobomax}
104124961Ssobomax