1130803Smarcel/* Definitions for frame unwinder, for GDB, the GNU debugger. 2130803Smarcel 3130803Smarcel Copyright 2003 Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or 10130803Smarcel (at your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, 13130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130803Smarcel GNU General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "frame.h" 24130803Smarcel#include "frame-unwind.h" 25130803Smarcel#include "gdb_assert.h" 26130803Smarcel#include "dummy-frame.h" 27130803Smarcel 28130803Smarcelstatic struct gdbarch_data *frame_unwind_data; 29130803Smarcel 30251858Semasteframe_unwind_sniffer_ftype *kgdb_sniffer_kluge; 31251858Semaste 32130803Smarcelstruct frame_unwind_table 33130803Smarcel{ 34130803Smarcel frame_unwind_sniffer_ftype **sniffer; 35130803Smarcel int nr; 36130803Smarcel}; 37130803Smarcel 38130803Smarcel/* Append a predicate to the end of the table. */ 39130803Smarcelstatic void 40130803Smarcelappend_predicate (struct frame_unwind_table *table, 41130803Smarcel frame_unwind_sniffer_ftype *sniffer) 42130803Smarcel{ 43130803Smarcel table->sniffer = xrealloc (table->sniffer, ((table->nr + 1) 44130803Smarcel * sizeof (frame_unwind_sniffer_ftype *))); 45130803Smarcel table->sniffer[table->nr] = sniffer; 46130803Smarcel table->nr++; 47130803Smarcel} 48130803Smarcel 49130803Smarcelstatic void * 50130803Smarcelframe_unwind_init (struct gdbarch *gdbarch) 51130803Smarcel{ 52130803Smarcel struct frame_unwind_table *table = XCALLOC (1, struct frame_unwind_table); 53130803Smarcel append_predicate (table, dummy_frame_sniffer); 54251858Semaste if (kgdb_sniffer_kluge != NULL) 55251858Semaste append_predicate (table, kgdb_sniffer_kluge); 56130803Smarcel return table; 57130803Smarcel} 58130803Smarcel 59130803Smarcelvoid 60130803Smarcelframe_unwind_append_sniffer (struct gdbarch *gdbarch, 61130803Smarcel frame_unwind_sniffer_ftype *sniffer) 62130803Smarcel{ 63130803Smarcel struct frame_unwind_table *table = 64130803Smarcel gdbarch_data (gdbarch, frame_unwind_data); 65130803Smarcel if (table == NULL) 66130803Smarcel { 67130803Smarcel /* ULGH, called during architecture initialization. Patch 68130803Smarcel things up. */ 69130803Smarcel table = frame_unwind_init (gdbarch); 70130803Smarcel set_gdbarch_data (gdbarch, frame_unwind_data, table); 71130803Smarcel } 72130803Smarcel append_predicate (table, sniffer); 73130803Smarcel} 74130803Smarcel 75130803Smarcelconst struct frame_unwind * 76130803Smarcelframe_unwind_find_by_frame (struct frame_info *next_frame) 77130803Smarcel{ 78130803Smarcel int i; 79130803Smarcel struct gdbarch *gdbarch = get_frame_arch (next_frame); 80130803Smarcel struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); 81130803Smarcel if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES && legacy_frame_p (gdbarch)) 82130803Smarcel /* Seriously old code. Don't even try to use this new mechanism. 83130803Smarcel (Note: The variable USE_GENERIC_DUMMY_FRAMES is deprecated, not 84130803Smarcel the dummy frame mechanism. All architectures should be using 85130803Smarcel generic dummy frames). */ 86130803Smarcel return legacy_saved_regs_unwind; 87130803Smarcel for (i = 0; i < table->nr; i++) 88130803Smarcel { 89130803Smarcel const struct frame_unwind *desc; 90130803Smarcel desc = table->sniffer[i] (next_frame); 91130803Smarcel if (desc != NULL) 92130803Smarcel return desc; 93130803Smarcel } 94130803Smarcel return legacy_saved_regs_unwind; 95130803Smarcel} 96130803Smarcel 97130803Smarcelextern initialize_file_ftype _initialize_frame_unwind; /* -Wmissing-prototypes */ 98130803Smarcel 99130803Smarcelvoid 100130803Smarcel_initialize_frame_unwind (void) 101130803Smarcel{ 102130803Smarcel frame_unwind_data = register_gdbarch_data (frame_unwind_init); 103130803Smarcel} 104