2011-01-05 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / frame-unwind.c
CommitLineData
494cca16
AC
1/* Definitions for frame unwinder, for GDB, the GNU debugger.
2
7b6bb8da 3 Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
4c38e0a4 4 Free Software Foundation, Inc.
494cca16
AC
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
494cca16
AC
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
494cca16
AC
20
21#include "defs.h"
22#include "frame.h"
23#include "frame-unwind.h"
494cca16 24#include "dummy-frame.h"
edb3359d 25#include "inline-frame.h"
669fac23
DJ
26#include "value.h"
27#include "regcache.h"
28
29#include "gdb_assert.h"
41fe5eb3 30#include "gdb_obstack.h"
494cca16
AC
31
32static struct gdbarch_data *frame_unwind_data;
33
41fe5eb3 34struct frame_unwind_table_entry
494cca16 35{
82417da5 36 const struct frame_unwind *unwinder;
41fe5eb3 37 struct frame_unwind_table_entry *next;
494cca16
AC
38};
39
41fe5eb3 40struct frame_unwind_table
494cca16 41{
fb2be677
AC
42 struct frame_unwind_table_entry *list;
43 /* The head of the OSABI part of the search list. */
44 struct frame_unwind_table_entry **osabi_head;
41fe5eb3 45};
494cca16
AC
46
47static void *
41fe5eb3 48frame_unwind_init (struct obstack *obstack)
494cca16 49{
41fe5eb3
AC
50 struct frame_unwind_table *table
51 = OBSTACK_ZALLOC (obstack, struct frame_unwind_table);
bb9bcb69 52
fb2be677
AC
53 /* Start the table out with a few default sniffers. OSABI code
54 can't override this. */
55 table->list = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
39d7b0e2 56 table->list->unwinder = &dummy_frame_unwind;
3e43a32a
MS
57 table->list->next = OBSTACK_ZALLOC (obstack,
58 struct frame_unwind_table_entry);
39d7b0e2 59 table->list->next->unwinder = &inline_frame_unwind;
fb2be677 60 /* The insertion point for OSABI sniffers. */
edb3359d 61 table->osabi_head = &table->list->next->next;
494cca16
AC
62 return table;
63}
64
82417da5 65void
fb2be677 66frame_unwind_prepend_unwinder (struct gdbarch *gdbarch,
82417da5
AC
67 const struct frame_unwind *unwinder)
68{
69 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
fb2be677
AC
70 struct frame_unwind_table_entry *entry;
71
72 /* Insert the new entry at the start of the list. */
73 entry = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
74 entry->unwinder = unwinder;
75 entry->next = (*table->osabi_head);
76 (*table->osabi_head) = entry;
82417da5
AC
77}
78
669fac23
DJ
79void
80frame_unwind_append_unwinder (struct gdbarch *gdbarch,
81 const struct frame_unwind *unwinder)
82{
83 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
84 struct frame_unwind_table_entry **ip;
85
86 /* Find the end of the list and insert the new entry there. */
87 for (ip = table->osabi_head; (*ip) != NULL; ip = &(*ip)->next);
88 (*ip) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
89 (*ip)->unwinder = unwinder;
90}
91
9f9a8002
JK
92/* Iterate through sniffers for THIS_FRAME frame until one returns with an
93 unwinder implementation. THIS_FRAME->UNWIND must be NULL, it will get set
94 by this function. Possibly initialize THIS_CACHE. */
95
96void
669fac23 97frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache)
e8a89fe2 98{
669fac23 99 struct gdbarch *gdbarch = get_frame_arch (this_frame);
e8a89fe2 100 struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
41fe5eb3 101 struct frame_unwind_table_entry *entry;
1c5465ac 102
fb2be677 103 for (entry = table->list; entry != NULL; entry = entry->next)
494cca16 104 {
669fac23
DJ
105 struct cleanup *old_cleanup;
106
107 old_cleanup = frame_prepare_for_sniffer (this_frame, entry->unwinder);
108 if (entry->unwinder->sniffer (entry->unwinder, this_frame,
109 this_cache))
82417da5 110 {
669fac23 111 discard_cleanups (old_cleanup);
9f9a8002 112 return;
82417da5 113 }
669fac23 114 do_cleanups (old_cleanup);
494cca16 115 }
e2e0b3e5 116 internal_error (__FILE__, __LINE__, _("frame_unwind_find_by_frame failed"));
494cca16
AC
117}
118
669fac23
DJ
119/* A default frame sniffer which always accepts the frame. Used by
120 fallback prologue unwinders. */
121
122int
123default_frame_sniffer (const struct frame_unwind *self,
124 struct frame_info *this_frame,
125 void **this_prologue_cache)
126{
127 return 1;
128}
129
130/* Helper functions for value-based register unwinding. These return
131 a (possibly lazy) value of the appropriate type. */
132
133/* Return a value which indicates that FRAME did not save REGNUM. */
134
135struct value *
136frame_unwind_got_optimized (struct frame_info *frame, int regnum)
137{
36f15f55 138 struct gdbarch *gdbarch = frame_unwind_arch (frame);
669fac23
DJ
139 struct value *reg_val;
140
141 reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
142 set_value_optimized_out (reg_val, 1);
143 return reg_val;
144}
145
146/* Return a value which indicates that FRAME copied REGNUM into
147 register NEW_REGNUM. */
148
149struct value *
3e43a32a
MS
150frame_unwind_got_register (struct frame_info *frame,
151 int regnum, int new_regnum)
669fac23
DJ
152{
153 return value_of_register_lazy (frame, new_regnum);
154}
155
156/* Return a value which indicates that FRAME saved REGNUM in memory at
157 ADDR. */
158
159struct value *
160frame_unwind_got_memory (struct frame_info *frame, int regnum, CORE_ADDR addr)
161{
36f15f55 162 struct gdbarch *gdbarch = frame_unwind_arch (frame);
4e5d721f 163 struct value *v = value_at_lazy (register_type (gdbarch, regnum), addr);
669fac23 164
4e5d721f
DE
165 set_value_stack (v, 1);
166 return v;
669fac23
DJ
167}
168
169/* Return a value which indicates that FRAME's saved version of
170 REGNUM has a known constant (computed) value of VAL. */
171
172struct value *
173frame_unwind_got_constant (struct frame_info *frame, int regnum,
174 ULONGEST val)
175{
36f15f55 176 struct gdbarch *gdbarch = frame_unwind_arch (frame);
e17a4113 177 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
669fac23
DJ
178 struct value *reg_val;
179
180 reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
181 store_unsigned_integer (value_contents_writeable (reg_val),
e17a4113 182 register_size (gdbarch, regnum), byte_order, val);
669fac23
DJ
183 return reg_val;
184}
185
15c1e57f
JB
186struct value *
187frame_unwind_got_bytes (struct frame_info *frame, int regnum, gdb_byte *buf)
188{
36f15f55 189 struct gdbarch *gdbarch = frame_unwind_arch (frame);
15c1e57f
JB
190 struct value *reg_val;
191
192 reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
193 memcpy (value_contents_raw (reg_val), buf, register_size (gdbarch, regnum));
194 return reg_val;
195}
196
669fac23
DJ
197/* Return a value which indicates that FRAME's saved version of REGNUM
198 has a known constant (computed) value of ADDR. Convert the
199 CORE_ADDR to a target address if necessary. */
200
201struct value *
202frame_unwind_got_address (struct frame_info *frame, int regnum,
203 CORE_ADDR addr)
204{
36f15f55 205 struct gdbarch *gdbarch = frame_unwind_arch (frame);
669fac23
DJ
206 struct value *reg_val;
207
208 reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
209 pack_long (value_contents_writeable (reg_val),
210 register_type (gdbarch, regnum), addr);
211 return reg_val;
212}
213
3e43a32a
MS
214/* -Wmissing-prototypes */
215extern initialize_file_ftype _initialize_frame_unwind;
b9362cc7 216
494cca16
AC
217void
218_initialize_frame_unwind (void)
219{
41fe5eb3 220 frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init);
494cca16 221}
This page took 0.616727 seconds and 4 git commands to generate.