1/* Definitions for frame address handler, for GDB, the GNU debugger. 2 3 Copyright 2003 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-base.h" 24#include "frame.h" 25 26/* A default frame base implementations. If it wasn't for the old 27 DEPRECATED_FRAME_LOCALS_ADDRESS and DEPRECATED_FRAME_ARGS_ADDRESS, 28 these could be combined into a single function. All architectures 29 really need to override this. */ 30 31static CORE_ADDR 32default_frame_base_address (struct frame_info *next_frame, void **this_cache) 33{ 34 struct frame_info *this_frame = get_prev_frame (next_frame); 35 return get_frame_base (this_frame); /* sigh! */ 36} 37 38static CORE_ADDR 39default_frame_locals_address (struct frame_info *next_frame, void **this_cache) 40{ 41 if (DEPRECATED_FRAME_LOCALS_ADDRESS_P ()) 42 { 43 /* This is bad. The computation of per-frame locals address 44 should use a per-frame frame-base. */ 45 struct frame_info *this_frame = get_prev_frame (next_frame); 46 return DEPRECATED_FRAME_LOCALS_ADDRESS (this_frame); 47 } 48 return default_frame_base_address (next_frame, this_cache); 49} 50 51static CORE_ADDR 52default_frame_args_address (struct frame_info *next_frame, void **this_cache) 53{ 54 if (DEPRECATED_FRAME_ARGS_ADDRESS_P ()) 55 { 56 struct frame_info *this_frame = get_prev_frame (next_frame); 57 return DEPRECATED_FRAME_ARGS_ADDRESS (this_frame); 58 } 59 return default_frame_base_address (next_frame, this_cache); 60} 61 62const struct frame_base default_frame_base = { 63 NULL, /* No parent. */ 64 default_frame_base_address, 65 default_frame_locals_address, 66 default_frame_args_address 67}; 68 69static struct gdbarch_data *frame_base_data; 70 71struct frame_base_table 72{ 73 frame_base_sniffer_ftype **sniffer; 74 const struct frame_base *default_base; 75 int nr; 76}; 77 78static void * 79frame_base_init (struct gdbarch *gdbarch) 80{ 81 struct frame_base_table *table = XCALLOC (1, struct frame_base_table); 82 table->default_base = &default_frame_base; 83 return table; 84} 85 86static struct frame_base_table * 87frame_base_table (struct gdbarch *gdbarch) 88{ 89 struct frame_base_table *table = gdbarch_data (gdbarch, frame_base_data); 90 if (table == NULL) 91 { 92 /* ULGH, called during architecture initialization. Patch 93 things up. */ 94 table = frame_base_init (gdbarch); 95 set_gdbarch_data (gdbarch, frame_base_data, table); 96 } 97 return table; 98} 99 100/* Append a predicate to the end of the table. */ 101static void 102append_predicate (struct frame_base_table *table, 103 frame_base_sniffer_ftype *sniffer) 104{ 105 table->sniffer = xrealloc (table->sniffer, 106 ((table->nr + 1) 107 * sizeof (frame_base_sniffer_ftype *))); 108 table->sniffer[table->nr] = sniffer; 109 table->nr++; 110} 111 112void 113frame_base_append_sniffer (struct gdbarch *gdbarch, 114 frame_base_sniffer_ftype *sniffer) 115{ 116 struct frame_base_table *table = frame_base_table (gdbarch); 117 append_predicate (table, sniffer); 118} 119 120void 121frame_base_set_default (struct gdbarch *gdbarch, 122 const struct frame_base *default_base) 123{ 124 struct frame_base_table *table = frame_base_table (gdbarch); 125 table->default_base = default_base; 126} 127 128const struct frame_base * 129frame_base_find_by_frame (struct frame_info *next_frame) 130{ 131 struct gdbarch *gdbarch = get_frame_arch (next_frame); 132 struct frame_base_table *table = frame_base_table (gdbarch); 133 int i; 134 for (i = 0; i < table->nr; i++) 135 { 136 const struct frame_base *desc = NULL; 137 desc = table->sniffer[i] (next_frame); 138 if (desc != NULL) 139 return desc; 140 } 141 return table->default_base; 142} 143 144extern initialize_file_ftype _initialize_frame_base; /* -Wmissing-prototypes */ 145 146void 147_initialize_frame_base (void) 148{ 149 frame_base_data = register_gdbarch_data (frame_base_init); 150} 151