1/* Definitions for frame unwinder, for GDB, the GNU debugger. 2 3 Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "defs.h" 21#include "frame.h" 22#include "frame-unwind.h" 23#include "gdb_assert.h" 24#include "dummy-frame.h" 25#include "gdb_obstack.h" 26 27static struct gdbarch_data *frame_unwind_data; 28 29struct frame_unwind_table_entry 30{ 31 frame_unwind_sniffer_ftype *sniffer; 32 const struct frame_unwind *unwinder; 33 struct frame_unwind_table_entry *next; 34}; 35 36struct frame_unwind_table 37{ 38 struct frame_unwind_table_entry *list; 39 /* The head of the OSABI part of the search list. */ 40 struct frame_unwind_table_entry **osabi_head; 41}; 42 43static void * 44frame_unwind_init (struct obstack *obstack) 45{ 46 struct frame_unwind_table *table 47 = OBSTACK_ZALLOC (obstack, struct frame_unwind_table); 48 /* Start the table out with a few default sniffers. OSABI code 49 can't override this. */ 50 table->list = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry); 51 table->list->unwinder = dummy_frame_unwind; 52 /* The insertion point for OSABI sniffers. */ 53 table->osabi_head = &table->list->next; 54 return table; 55} 56 57void 58frame_unwind_append_sniffer (struct gdbarch *gdbarch, 59 frame_unwind_sniffer_ftype *sniffer) 60{ 61 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); 62 struct frame_unwind_table_entry **ip; 63 64 /* Find the end of the list and insert the new entry there. */ 65 for (ip = table->osabi_head; (*ip) != NULL; ip = &(*ip)->next); 66 (*ip) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry); 67 (*ip)->sniffer = sniffer; 68} 69 70void 71frame_unwind_prepend_unwinder (struct gdbarch *gdbarch, 72 const struct frame_unwind *unwinder) 73{ 74 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); 75 struct frame_unwind_table_entry *entry; 76 77 /* Insert the new entry at the start of the list. */ 78 entry = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry); 79 entry->unwinder = unwinder; 80 entry->next = (*table->osabi_head); 81 (*table->osabi_head) = entry; 82} 83 84const struct frame_unwind * 85frame_unwind_find_by_frame (struct frame_info *next_frame, void **this_cache) 86{ 87 int i; 88 struct gdbarch *gdbarch = get_frame_arch (next_frame); 89 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); 90 struct frame_unwind_table_entry *entry; 91 for (entry = table->list; entry != NULL; entry = entry->next) 92 { 93 if (entry->sniffer != NULL) 94 { 95 const struct frame_unwind *desc = NULL; 96 desc = entry->sniffer (next_frame); 97 if (desc != NULL) 98 return desc; 99 } 100 if (entry->unwinder != NULL) 101 { 102 if (entry->unwinder->sniffer (entry->unwinder, next_frame, 103 this_cache)) 104 return entry->unwinder; 105 } 106 } 107 internal_error (__FILE__, __LINE__, _("frame_unwind_find_by_frame failed")); 108} 109 110extern initialize_file_ftype _initialize_frame_unwind; /* -Wmissing-prototypes */ 111 112void 113_initialize_frame_unwind (void) 114{ 115 frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init); 116} 117