1 /* Definitions for frame unwinder, for GDB, the GNU debugger. 2 3 Copyright 2003, 2004 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 2 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, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22 #include "defs.h" 23 #include "frame.h" 24 #include "frame-unwind.h" 25 #include "gdb_assert.h" 26 #include "dummy-frame.h" 27 #include "gdb_obstack.h" 28 29 static struct gdbarch_data *frame_unwind_data; 30 31 struct frame_unwind_table_entry 32 { 33 frame_unwind_sniffer_ftype *sniffer; 34 const struct frame_unwind *unwinder; 35 struct frame_unwind_table_entry *next; 36 }; 37 38 struct frame_unwind_table 39 { 40 struct frame_unwind_table_entry *list; 41 /* The head of the OSABI part of the search list. */ 42 struct frame_unwind_table_entry **osabi_head; 43 }; 44 45 static void * 46 frame_unwind_init (struct obstack *obstack) 47 { 48 struct frame_unwind_table *table 49 = OBSTACK_ZALLOC (obstack, struct frame_unwind_table); 50 /* Start the table out with a few default sniffers. OSABI code 51 can't override this. */ 52 table->list = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry); 53 table->list->unwinder = dummy_frame_unwind; 54 /* The insertion point for OSABI sniffers. */ 55 table->osabi_head = &table->list->next; 56 return table; 57 } 58 59 void 60 frame_unwind_append_sniffer (struct gdbarch *gdbarch, 61 frame_unwind_sniffer_ftype *sniffer) 62 { 63 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); 64 struct frame_unwind_table_entry **ip; 65 66 /* Find the end of the list and insert the new entry there. */ 67 for (ip = table->osabi_head; (*ip) != NULL; ip = &(*ip)->next); 68 (*ip) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry); 69 (*ip)->sniffer = sniffer; 70 } 71 72 void 73 frame_unwind_prepend_unwinder (struct gdbarch *gdbarch, 74 const struct frame_unwind *unwinder) 75 { 76 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); 77 struct frame_unwind_table_entry *entry; 78 79 /* Insert the new entry at the start of the list. */ 80 entry = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry); 81 entry->unwinder = unwinder; 82 entry->next = (*table->osabi_head); 83 (*table->osabi_head) = entry; 84 } 85 86 const struct frame_unwind * 87 frame_unwind_find_by_frame (struct frame_info *next_frame, void **this_cache) 88 { 89 int i; 90 struct gdbarch *gdbarch = get_frame_arch (next_frame); 91 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); 92 struct frame_unwind_table_entry *entry; 93 for (entry = table->list; entry != NULL; entry = entry->next) 94 { 95 if (entry->sniffer != NULL) 96 { 97 const struct frame_unwind *desc = NULL; 98 desc = entry->sniffer (next_frame); 99 if (desc != NULL) 100 return desc; 101 } 102 if (entry->unwinder != NULL) 103 { 104 if (entry->unwinder->sniffer (entry->unwinder, next_frame, 105 this_cache)) 106 return entry->unwinder; 107 } 108 } 109 internal_error (__FILE__, __LINE__, "frame_unwind_find_by_frame failed"); 110 } 111 112 extern initialize_file_ftype _initialize_frame_unwind; /* -Wmissing-prototypes */ 113 114 void 115 _initialize_frame_unwind (void) 116 { 117 frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init); 118 } 119