1b725ae77Skettenis /* Code dealing with dummy stack frames, for GDB, the GNU debugger.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4*11efff7fSkettenis 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free
5*11efff7fSkettenis Software Foundation, Inc.
6b725ae77Skettenis
7b725ae77Skettenis This file is part of GDB.
8b725ae77Skettenis
9b725ae77Skettenis This program is free software; you can redistribute it and/or modify
10b725ae77Skettenis it under the terms of the GNU General Public License as published by
11b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
12b725ae77Skettenis (at your option) any later version.
13b725ae77Skettenis
14b725ae77Skettenis This program is distributed in the hope that it will be useful,
15b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
16b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17b725ae77Skettenis GNU General Public License for more details.
18b725ae77Skettenis
19b725ae77Skettenis You should have received a copy of the GNU General Public License
20b725ae77Skettenis along with this program; if not, write to the Free Software
21b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
22b725ae77Skettenis Boston, MA 02111-1307, USA. */
23b725ae77Skettenis
24b725ae77Skettenis
25b725ae77Skettenis #include "defs.h"
26b725ae77Skettenis #include "dummy-frame.h"
27b725ae77Skettenis #include "regcache.h"
28b725ae77Skettenis #include "frame.h"
29b725ae77Skettenis #include "inferior.h"
30b725ae77Skettenis #include "gdb_assert.h"
31b725ae77Skettenis #include "frame-unwind.h"
32b725ae77Skettenis #include "command.h"
33b725ae77Skettenis #include "gdbcmd.h"
34*11efff7fSkettenis #include "gdb_string.h"
35b725ae77Skettenis
36b725ae77Skettenis /* Dummy frame. This saves the processor state just prior to setting
37b725ae77Skettenis up the inferior function call. Older targets save the registers
38b725ae77Skettenis on the target stack (but that really slows down function calls). */
39b725ae77Skettenis
40b725ae77Skettenis struct dummy_frame
41b725ae77Skettenis {
42b725ae77Skettenis struct dummy_frame *next;
43*11efff7fSkettenis /* This frame's ID. Must match the value returned by
44*11efff7fSkettenis gdbarch_unwind_dummy_id. */
45b725ae77Skettenis struct frame_id id;
46*11efff7fSkettenis /* The caller's regcache. */
47b725ae77Skettenis struct regcache *regcache;
48b725ae77Skettenis };
49b725ae77Skettenis
50b725ae77Skettenis static struct dummy_frame *dummy_frame_stack = NULL;
51b725ae77Skettenis
52*11efff7fSkettenis /* Function: deprecated_pc_in_call_dummy (pc)
53b725ae77Skettenis
54*11efff7fSkettenis Return non-zero if the PC falls in a dummy frame created by gdb for
55*11efff7fSkettenis an inferior call. The code below which allows DECR_PC_AFTER_BREAK
56*11efff7fSkettenis is for infrun.c, which may give the function a PC without that
57*11efff7fSkettenis subtracted out.
58b725ae77Skettenis
59b725ae77Skettenis FIXME: cagney/2002-11-23: This is silly. Surely "infrun.c" can
60b725ae77Skettenis figure out what the real PC (as in the resume address) is BEFORE
61*11efff7fSkettenis calling this function.
62*11efff7fSkettenis
63*11efff7fSkettenis NOTE: cagney/2004-08-02: I'm pretty sure that, with the introduction of
64*11efff7fSkettenis infrun.c:adjust_pc_after_break (thanks), this function is now
65*11efff7fSkettenis always called with a correctly adjusted PC!
66*11efff7fSkettenis
67*11efff7fSkettenis NOTE: cagney/2004-08-02: Code should not need to call this. */
68b725ae77Skettenis
69b725ae77Skettenis int
deprecated_pc_in_call_dummy(CORE_ADDR pc)70*11efff7fSkettenis deprecated_pc_in_call_dummy (CORE_ADDR pc)
71b725ae77Skettenis {
72b725ae77Skettenis struct dummy_frame *dummyframe;
73b725ae77Skettenis for (dummyframe = dummy_frame_stack;
74b725ae77Skettenis dummyframe != NULL;
75b725ae77Skettenis dummyframe = dummyframe->next)
76b725ae77Skettenis {
77*11efff7fSkettenis if ((pc >= dummyframe->id.code_addr)
78*11efff7fSkettenis && (pc <= dummyframe->id.code_addr + DECR_PC_AFTER_BREAK))
79b725ae77Skettenis return 1;
80b725ae77Skettenis }
81b725ae77Skettenis return 0;
82b725ae77Skettenis }
83b725ae77Skettenis
84*11efff7fSkettenis /* Push the caller's state, along with the dummy frame info, onto a
85*11efff7fSkettenis dummy-frame stack. */
86b725ae77Skettenis
87b725ae77Skettenis void
dummy_frame_push(struct regcache * caller_regcache,const struct frame_id * dummy_id)88*11efff7fSkettenis dummy_frame_push (struct regcache *caller_regcache,
89*11efff7fSkettenis const struct frame_id *dummy_id)
90b725ae77Skettenis {
91b725ae77Skettenis struct dummy_frame *dummy_frame;
92b725ae77Skettenis
93*11efff7fSkettenis /* Check to see if there are stale dummy frames, perhaps left over
94*11efff7fSkettenis from when a longjump took us out of a function that was called by
95*11efff7fSkettenis the debugger. */
96b725ae77Skettenis dummy_frame = dummy_frame_stack;
97b725ae77Skettenis while (dummy_frame)
98*11efff7fSkettenis /* FIXME: cagney/2004-08-02: Should just test IDs. */
99*11efff7fSkettenis if (frame_id_inner (dummy_frame->id, (*dummy_id)))
100*11efff7fSkettenis /* Stale -- destroy! */
101b725ae77Skettenis {
102b725ae77Skettenis dummy_frame_stack = dummy_frame->next;
103b725ae77Skettenis regcache_xfree (dummy_frame->regcache);
104b725ae77Skettenis xfree (dummy_frame);
105b725ae77Skettenis dummy_frame = dummy_frame_stack;
106b725ae77Skettenis }
107b725ae77Skettenis else
108b725ae77Skettenis dummy_frame = dummy_frame->next;
109b725ae77Skettenis
110*11efff7fSkettenis dummy_frame = XZALLOC (struct dummy_frame);
111*11efff7fSkettenis dummy_frame->regcache = caller_regcache;
112*11efff7fSkettenis dummy_frame->id = (*dummy_id);
113b725ae77Skettenis dummy_frame->next = dummy_frame_stack;
114b725ae77Skettenis dummy_frame_stack = dummy_frame;
115b725ae77Skettenis }
116b725ae77Skettenis
117*11efff7fSkettenis /* Return the dummy frame cache, it contains both the ID, and a
118*11efff7fSkettenis pointer to the regcache. */
119*11efff7fSkettenis struct dummy_frame_cache
120b725ae77Skettenis {
121*11efff7fSkettenis struct frame_id this_id;
122*11efff7fSkettenis struct regcache *prev_regcache;
123*11efff7fSkettenis };
124*11efff7fSkettenis
125*11efff7fSkettenis int
dummy_frame_sniffer(const struct frame_unwind * self,struct frame_info * next_frame,void ** this_prologue_cache)126*11efff7fSkettenis dummy_frame_sniffer (const struct frame_unwind *self,
127*11efff7fSkettenis struct frame_info *next_frame,
128*11efff7fSkettenis void **this_prologue_cache)
129*11efff7fSkettenis {
130*11efff7fSkettenis struct dummy_frame *dummyframe;
131*11efff7fSkettenis struct frame_id this_id;
132*11efff7fSkettenis
133*11efff7fSkettenis /* When unwinding a normal frame, the stack structure is determined
134*11efff7fSkettenis by analyzing the frame's function's code (be it using brute force
135*11efff7fSkettenis prologue analysis, or the dwarf2 CFI). In the case of a dummy
136*11efff7fSkettenis frame, that simply isn't possible. The PC is either the program
137*11efff7fSkettenis entry point, or some random address on the stack. Trying to use
138*11efff7fSkettenis that PC to apply standard frame ID unwind techniques is just
139*11efff7fSkettenis asking for trouble. */
140*11efff7fSkettenis /* Use an architecture specific method to extract the prev's dummy
141*11efff7fSkettenis ID from the next frame. Note that this method uses
142*11efff7fSkettenis frame_register_unwind to obtain the register values needed to
143*11efff7fSkettenis determine the dummy frame's ID. */
144*11efff7fSkettenis this_id = gdbarch_unwind_dummy_id (get_frame_arch (next_frame), next_frame);
145*11efff7fSkettenis
146*11efff7fSkettenis /* Use that ID to find the corresponding cache entry. */
147*11efff7fSkettenis for (dummyframe = dummy_frame_stack;
148*11efff7fSkettenis dummyframe != NULL;
149*11efff7fSkettenis dummyframe = dummyframe->next)
150*11efff7fSkettenis {
151*11efff7fSkettenis if (frame_id_eq (dummyframe->id, this_id))
152*11efff7fSkettenis {
153*11efff7fSkettenis struct dummy_frame_cache *cache;
154*11efff7fSkettenis cache = FRAME_OBSTACK_ZALLOC (struct dummy_frame_cache);
155*11efff7fSkettenis cache->prev_regcache = dummyframe->regcache;
156*11efff7fSkettenis cache->this_id = this_id;
157*11efff7fSkettenis (*this_prologue_cache) = cache;
158*11efff7fSkettenis return 1;
159b725ae77Skettenis }
160b725ae77Skettenis }
161*11efff7fSkettenis return 0;
162b725ae77Skettenis }
163b725ae77Skettenis
164b725ae77Skettenis /* Given a call-dummy dummy-frame, return the registers. Here the
165b725ae77Skettenis register value is taken from the local copy of the register buffer. */
166b725ae77Skettenis
167b725ae77Skettenis static void
dummy_frame_prev_register(struct frame_info * next_frame,void ** this_prologue_cache,int regnum,int * optimized,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnum,void * bufferp)168b725ae77Skettenis dummy_frame_prev_register (struct frame_info *next_frame,
169b725ae77Skettenis void **this_prologue_cache,
170b725ae77Skettenis int regnum, int *optimized,
171b725ae77Skettenis enum lval_type *lvalp, CORE_ADDR *addrp,
172b725ae77Skettenis int *realnum, void *bufferp)
173b725ae77Skettenis {
174*11efff7fSkettenis /* The dummy-frame sniffer always fills in the cache. */
175*11efff7fSkettenis struct dummy_frame_cache *cache = (*this_prologue_cache);
176*11efff7fSkettenis gdb_assert (cache != NULL);
177b725ae77Skettenis
178b725ae77Skettenis /* Describe the register's location. Generic dummy frames always
179b725ae77Skettenis have the register value in an ``expression''. */
180b725ae77Skettenis *optimized = 0;
181b725ae77Skettenis *lvalp = not_lval;
182b725ae77Skettenis *addrp = 0;
183b725ae77Skettenis *realnum = -1;
184b725ae77Skettenis
185b725ae77Skettenis /* If needed, find and return the value of the register. */
186b725ae77Skettenis if (bufferp != NULL)
187b725ae77Skettenis {
188b725ae77Skettenis /* Return the actual value. */
189b725ae77Skettenis /* Use the regcache_cooked_read() method so that it, on the fly,
190b725ae77Skettenis constructs either a raw or pseudo register from the raw
191b725ae77Skettenis register cache. */
192*11efff7fSkettenis regcache_cooked_read (cache->prev_regcache, regnum, bufferp);
193b725ae77Skettenis }
194b725ae77Skettenis }
195b725ae77Skettenis
196b725ae77Skettenis /* Assuming that THIS frame is a dummy (remember, the NEXT and not
197b725ae77Skettenis THIS frame is passed in), return the ID of THIS frame. That ID is
198b725ae77Skettenis determined by examining the NEXT frame's unwound registers using
199b725ae77Skettenis the method unwind_dummy_id(). As a side effect, THIS dummy frame's
200b725ae77Skettenis dummy cache is located and and saved in THIS_PROLOGUE_CACHE. */
201b725ae77Skettenis
202b725ae77Skettenis static void
dummy_frame_this_id(struct frame_info * next_frame,void ** this_prologue_cache,struct frame_id * this_id)203b725ae77Skettenis dummy_frame_this_id (struct frame_info *next_frame,
204b725ae77Skettenis void **this_prologue_cache,
205b725ae77Skettenis struct frame_id *this_id)
206b725ae77Skettenis {
207*11efff7fSkettenis /* The dummy-frame sniffer always fills in the cache. */
208*11efff7fSkettenis struct dummy_frame_cache *cache = (*this_prologue_cache);
209*11efff7fSkettenis gdb_assert (cache != NULL);
210*11efff7fSkettenis (*this_id) = cache->this_id;
211b725ae77Skettenis }
212b725ae77Skettenis
213*11efff7fSkettenis static const struct frame_unwind dummy_frame_unwinder =
214b725ae77Skettenis {
215b725ae77Skettenis DUMMY_FRAME,
216b725ae77Skettenis dummy_frame_this_id,
217*11efff7fSkettenis dummy_frame_prev_register,
218*11efff7fSkettenis NULL,
219*11efff7fSkettenis dummy_frame_sniffer,
220b725ae77Skettenis };
221b725ae77Skettenis
222*11efff7fSkettenis const struct frame_unwind *const dummy_frame_unwind = {
223*11efff7fSkettenis &dummy_frame_unwinder
224*11efff7fSkettenis };
225b725ae77Skettenis
226b725ae77Skettenis static void
fprint_dummy_frames(struct ui_file * file)227b725ae77Skettenis fprint_dummy_frames (struct ui_file *file)
228b725ae77Skettenis {
229b725ae77Skettenis struct dummy_frame *s;
230b725ae77Skettenis for (s = dummy_frame_stack; s != NULL; s = s->next)
231b725ae77Skettenis {
232b725ae77Skettenis gdb_print_host_address (s, file);
233b725ae77Skettenis fprintf_unfiltered (file, ":");
234b725ae77Skettenis fprintf_unfiltered (file, " id=");
235b725ae77Skettenis fprint_frame_id (file, s->id);
236b725ae77Skettenis fprintf_unfiltered (file, "\n");
237b725ae77Skettenis }
238b725ae77Skettenis }
239b725ae77Skettenis
240b725ae77Skettenis static void
maintenance_print_dummy_frames(char * args,int from_tty)241b725ae77Skettenis maintenance_print_dummy_frames (char *args, int from_tty)
242b725ae77Skettenis {
243b725ae77Skettenis if (args == NULL)
244b725ae77Skettenis fprint_dummy_frames (gdb_stdout);
245b725ae77Skettenis else
246b725ae77Skettenis {
247b725ae77Skettenis struct ui_file *file = gdb_fopen (args, "w");
248b725ae77Skettenis if (file == NULL)
249b725ae77Skettenis perror_with_name ("maintenance print dummy-frames");
250b725ae77Skettenis fprint_dummy_frames (file);
251b725ae77Skettenis ui_file_delete (file);
252b725ae77Skettenis }
253b725ae77Skettenis }
254b725ae77Skettenis
255b725ae77Skettenis extern void _initialize_dummy_frame (void);
256b725ae77Skettenis
257b725ae77Skettenis void
_initialize_dummy_frame(void)258b725ae77Skettenis _initialize_dummy_frame (void)
259b725ae77Skettenis {
260b725ae77Skettenis add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames,
261b725ae77Skettenis "Print the contents of the internal dummy-frame stack.",
262b725ae77Skettenis &maintenanceprintlist);
263b725ae77Skettenis
264b725ae77Skettenis }
265