Tweak gdb.trace/tfile.c for thumb mode
[deliverable/binutils-gdb.git] / gdb / dummy-frame.c
CommitLineData
9c1412c1
AC
1/* Code dealing with dummy stack frames, for GDB, the GNU debugger.
2
ecd75fc8 3 Copyright (C) 1986-2014 Free Software Foundation, Inc.
9c1412c1
AC
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
9c1412c1
AC
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
9c1412c1
AC
19
20
21#include "defs.h"
22#include "dummy-frame.h"
23#include "regcache.h"
24#include "frame.h"
25#include "inferior.h"
26#include "gdb_assert.h"
494cca16 27#include "frame-unwind.h"
00905d52
AC
28#include "command.h"
29#include "gdbcmd.h"
0e9f083f 30#include <string.h>
a45ae3ed 31#include "observer.h"
e2e4d78b 32#include "gdbthread.h"
9c1412c1 33
b67a2c6f
YQ
34struct dummy_frame_id
35{
36 /* This frame's ID. Must match the value returned by
37 gdbarch_dummy_id. */
38 struct frame_id id;
39
40 /* The thread this dummy_frame relates to. */
41 ptid_t ptid;
42};
43
44/* Return whether dummy_frame_id *ID1 and *ID2 are equal. */
45
46static int
47dummy_frame_id_eq (struct dummy_frame_id *id1,
48 struct dummy_frame_id *id2)
49{
50 return frame_id_eq (id1->id, id2->id) && ptid_equal (id1->ptid, id2->ptid);
51}
52
9c1412c1
AC
53/* Dummy frame. This saves the processor state just prior to setting
54 up the inferior function call. Older targets save the registers
55 on the target stack (but that really slows down function calls). */
56
57struct dummy_frame
58{
59 struct dummy_frame *next;
b67a2c6f
YQ
60
61 /* An id represents a dummy frame. */
62 struct dummy_frame_id id;
63
b89667eb 64 /* The caller's state prior to the call. */
16c381f0 65 struct infcall_suspend_state *caller_state;
9c1412c1
AC
66};
67
68static struct dummy_frame *dummy_frame_stack = NULL;
69
b89667eb 70/* Push the caller's state, along with the dummy frame info, onto the
96860204 71 dummy-frame stack. */
9c1412c1
AC
72
73void
16c381f0 74dummy_frame_push (struct infcall_suspend_state *caller_state,
b67a2c6f 75 const struct frame_id *dummy_id, ptid_t ptid)
9c1412c1
AC
76{
77 struct dummy_frame *dummy_frame;
9c1412c1 78
41bf6aca 79 dummy_frame = XCNEW (struct dummy_frame);
b89667eb 80 dummy_frame->caller_state = caller_state;
b67a2c6f
YQ
81 dummy_frame->id.id = (*dummy_id);
82 dummy_frame->id.ptid = ptid;
9c1412c1
AC
83 dummy_frame->next = dummy_frame_stack;
84 dummy_frame_stack = dummy_frame;
85}
86
b89667eb 87/* Remove *DUMMY_PTR from the dummy frame stack. */
a45ae3ed 88
b89667eb
DE
89static void
90remove_dummy_frame (struct dummy_frame **dummy_ptr)
a45ae3ed 91{
b89667eb 92 struct dummy_frame *dummy = *dummy_ptr;
a45ae3ed 93
b89667eb 94 *dummy_ptr = dummy->next;
16c381f0 95 discard_infcall_suspend_state (dummy->caller_state);
b89667eb 96 xfree (dummy);
a45ae3ed
UW
97}
98
e2e4d78b
JK
99/* Delete any breakpoint B which is a momentary breakpoint for return from
100 inferior call matching DUMMY_VOIDP. */
101
102static int
103pop_dummy_frame_bpt (struct breakpoint *b, void *dummy_voidp)
104{
105 struct dummy_frame *dummy = dummy_voidp;
106
b67a2c6f
YQ
107 if (b->thread == pid_to_thread_id (dummy->id.ptid)
108 && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id.id))
e2e4d78b
JK
109 {
110 while (b->related_breakpoint != b)
111 delete_breakpoint (b->related_breakpoint);
112
113 delete_breakpoint (b);
114
115 /* Stop the traversal. */
116 return 1;
117 }
118
119 /* Continue the traversal. */
120 return 0;
121}
122
b89667eb
DE
123/* Pop *DUMMY_PTR, restoring program state to that before the
124 frame was created. */
a45ae3ed
UW
125
126static void
b89667eb 127pop_dummy_frame (struct dummy_frame **dummy_ptr)
a45ae3ed 128{
e2e4d78b
JK
129 struct dummy_frame *dummy = *dummy_ptr;
130
b67a2c6f 131 gdb_assert (ptid_equal (dummy->id.ptid, inferior_ptid));
e2e4d78b 132 restore_infcall_suspend_state (dummy->caller_state);
a45ae3ed 133
e2e4d78b 134 iterate_over_breakpoints (pop_dummy_frame_bpt, dummy);
b89667eb 135
16c381f0 136 /* restore_infcall_control_state frees inf_state,
0963b4bd 137 all that remains is to pop *dummy_ptr. */
b89667eb
DE
138 *dummy_ptr = dummy->next;
139 xfree (dummy);
140
141 /* We've made right mess of GDB's local state, just discard
142 everything. */
143 reinit_frame_cache ();
144}
145
146/* Look up DUMMY_ID.
147 Return NULL if not found. */
148
149static struct dummy_frame **
b67a2c6f 150lookup_dummy_frame (struct dummy_frame_id *dummy_id)
b89667eb
DE
151{
152 struct dummy_frame **dp;
153
154 for (dp = &dummy_frame_stack; *dp != NULL; dp = &(*dp)->next)
a45ae3ed 155 {
b67a2c6f 156 if (dummy_frame_id_eq (&(*dp)->id, dummy_id))
b89667eb 157 return dp;
a45ae3ed
UW
158 }
159
b89667eb
DE
160 return NULL;
161}
162
b67a2c6f
YQ
163/* Find the dummy frame by DUMMY_ID and PTID, and pop it, restoring
164 program state to that before the frame was created.
b89667eb 165 On return reinit_frame_cache has been called.
b67a2c6f 166 If the frame isn't found, flag an internal error. */
b89667eb
DE
167
168void
b67a2c6f 169dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid)
b89667eb
DE
170{
171 struct dummy_frame **dp;
b67a2c6f 172 struct dummy_frame_id id = { dummy_id, ptid };
b89667eb 173
b67a2c6f 174 dp = lookup_dummy_frame (&id);
b89667eb
DE
175 gdb_assert (dp != NULL);
176
177 pop_dummy_frame (dp);
178}
179
b67a2c6f
YQ
180/* Find the dummy frame by DUMMY_ID and PTID and drop it. Do nothing
181 if it is not found. Do not restore its state into inferior, just
182 free its memory. */
e2e4d78b
JK
183
184void
b67a2c6f 185dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid)
e2e4d78b
JK
186{
187 struct dummy_frame **dp;
b67a2c6f 188 struct dummy_frame_id id = { dummy_id, ptid };
e2e4d78b 189
b67a2c6f 190 dp = lookup_dummy_frame (&id);
e2e4d78b
JK
191 if (dp)
192 remove_dummy_frame (dp);
193}
194
195/* There may be stale dummy frames, perhaps left over from when an uncaught
196 longjmp took us out of a function that was called by the debugger. Clean
197 them up at least once whenever we start a new inferior. */
b89667eb
DE
198
199static void
200cleanup_dummy_frames (struct target_ops *target, int from_tty)
201{
202 while (dummy_frame_stack != NULL)
203 remove_dummy_frame (&dummy_frame_stack);
a45ae3ed
UW
204}
205
d67ec5db
AC
206/* Return the dummy frame cache, it contains both the ID, and a
207 pointer to the regcache. */
208struct dummy_frame_cache
209{
210 struct frame_id this_id;
211 struct regcache *prev_regcache;
212};
213
b89667eb 214static int
d67ec5db 215dummy_frame_sniffer (const struct frame_unwind *self,
669fac23 216 struct frame_info *this_frame,
d67ec5db
AC
217 void **this_prologue_cache)
218{
d67ec5db
AC
219 /* When unwinding a normal frame, the stack structure is determined
220 by analyzing the frame's function's code (be it using brute force
221 prologue analysis, or the dwarf2 CFI). In the case of a dummy
222 frame, that simply isn't possible. The PC is either the program
223 entry point, or some random address on the stack. Trying to use
224 that PC to apply standard frame ID unwind techniques is just
225 asking for trouble. */
0c98cc2b 226
b89667eb 227 /* Don't bother unless there is at least one dummy frame. */
0c98cc2b 228 if (dummy_frame_stack != NULL)
d67ec5db 229 {
efc889c1 230 struct dummy_frame *dummyframe;
669fac23
DJ
231 /* Use an architecture specific method to extract this frame's
232 dummy ID, assuming it is a dummy frame. */
efc889c1
YQ
233 struct frame_id this_id
234 = gdbarch_dummy_id (get_frame_arch (this_frame), this_frame);
b67a2c6f 235 struct dummy_frame_id dummy_id = { this_id, inferior_ptid };
0c98cc2b
MS
236
237 /* Use that ID to find the corresponding cache entry. */
238 for (dummyframe = dummy_frame_stack;
239 dummyframe != NULL;
240 dummyframe = dummyframe->next)
3c109c8b 241 {
b67a2c6f 242 if (dummy_frame_id_eq (&dummyframe->id, &dummy_id))
0c98cc2b
MS
243 {
244 struct dummy_frame_cache *cache;
9a619af0 245
0c98cc2b 246 cache = FRAME_OBSTACK_ZALLOC (struct dummy_frame_cache);
16c381f0
JK
247 cache->prev_regcache = get_infcall_suspend_state_regcache
248 (dummyframe->caller_state);
0c98cc2b
MS
249 cache->this_id = this_id;
250 (*this_prologue_cache) = cache;
251 return 1;
252 }
3c109c8b 253 }
d67ec5db
AC
254 }
255 return 0;
256}
257
9c1412c1
AC
258/* Given a call-dummy dummy-frame, return the registers. Here the
259 register value is taken from the local copy of the register buffer. */
260
669fac23
DJ
261static struct value *
262dummy_frame_prev_register (struct frame_info *this_frame,
6dc42492 263 void **this_prologue_cache,
669fac23 264 int regnum)
9c1412c1 265{
d67ec5db 266 struct dummy_frame_cache *cache = (*this_prologue_cache);
669fac23
DJ
267 struct gdbarch *gdbarch = get_frame_arch (this_frame);
268 struct value *reg_val;
269
270 /* The dummy-frame sniffer always fills in the cache. */
d67ec5db 271 gdb_assert (cache != NULL);
9c1412c1
AC
272
273 /* Describe the register's location. Generic dummy frames always
274 have the register value in an ``expression''. */
669fac23
DJ
275 reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
276
277 /* Use the regcache_cooked_read() method so that it, on the fly,
278 constructs either a raw or pseudo register from the raw
279 register cache. */
280 regcache_cooked_read (cache->prev_regcache, regnum,
281 value_contents_writeable (reg_val));
282 return reg_val;
9c1412c1
AC
283}
284
b89667eb 285/* Assuming that THIS_FRAME is a dummy, return its ID. That ID is
6dc42492 286 determined by examining the NEXT frame's unwound registers using
669fac23 287 the method dummy_id(). As a side effect, THIS dummy frame's
7a9dd1b2 288 dummy cache is located and saved in THIS_PROLOGUE_CACHE. */
494cca16
AC
289
290static void
669fac23 291dummy_frame_this_id (struct frame_info *this_frame,
6dc42492
AC
292 void **this_prologue_cache,
293 struct frame_id *this_id)
c689142b 294{
d67ec5db
AC
295 /* The dummy-frame sniffer always fills in the cache. */
296 struct dummy_frame_cache *cache = (*this_prologue_cache);
9a619af0 297
d67ec5db
AC
298 gdb_assert (cache != NULL);
299 (*this_id) = cache->this_id;
c689142b
AC
300}
301
39d7b0e2 302const struct frame_unwind dummy_frame_unwind =
494cca16 303{
7df05f2b 304 DUMMY_FRAME,
8fbca658 305 default_frame_unwind_stop_reason,
6dc42492 306 dummy_frame_this_id,
d67ec5db
AC
307 dummy_frame_prev_register,
308 NULL,
309 dummy_frame_sniffer,
494cca16
AC
310};
311
00905d52
AC
312static void
313fprint_dummy_frames (struct ui_file *file)
314{
315 struct dummy_frame *s;
9a619af0 316
00905d52
AC
317 for (s = dummy_frame_stack; s != NULL; s = s->next)
318 {
319 gdb_print_host_address (s, file);
320 fprintf_unfiltered (file, ":");
00905d52 321 fprintf_unfiltered (file, " id=");
b67a2c6f
YQ
322 fprint_frame_id (file, s->id.id);
323 fprintf_unfiltered (file, ", ptid=%s",
324 target_pid_to_str (s->id.ptid));
00905d52
AC
325 fprintf_unfiltered (file, "\n");
326 }
327}
328
329static void
330maintenance_print_dummy_frames (char *args, int from_tty)
331{
332 if (args == NULL)
333 fprint_dummy_frames (gdb_stdout);
334 else
335 {
724b958c 336 struct cleanup *cleanups;
00905d52 337 struct ui_file *file = gdb_fopen (args, "w");
9a619af0 338
00905d52 339 if (file == NULL)
e2e0b3e5 340 perror_with_name (_("maintenance print dummy-frames"));
724b958c 341 cleanups = make_cleanup_ui_file_delete (file);
00905d52 342 fprint_dummy_frames (file);
724b958c 343 do_cleanups (cleanups);
00905d52
AC
344 }
345}
346
347extern void _initialize_dummy_frame (void);
348
349void
350_initialize_dummy_frame (void)
351{
352 add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames,
1a966eab 353 _("Print the contents of the internal dummy-frame stack."),
00905d52
AC
354 &maintenanceprintlist);
355
a45ae3ed 356 observer_attach_inferior_created (cleanup_dummy_frames);
00905d52 357}
This page took 0.759352 seconds and 4 git commands to generate.