* dwarf2-frame.c (read_reg): Expect this_frame in the baton.
[deliverable/binutils-gdb.git] / gdb / trad-frame.c
CommitLineData
a0f267c7
AC
1/* Traditional frame unwind support, for GDB the GNU Debugger.
2
9b254dd1 3 Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
a0f267c7
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
a0f267c7
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/>. */
a0f267c7
AC
19
20#include "defs.h"
21#include "frame.h"
22#include "trad-frame.h"
23#include "regcache.h"
24
0db9b4b7
AC
25struct trad_frame_cache
26{
27 struct frame_info *next_frame;
28 CORE_ADDR this_base;
29 struct trad_frame_saved_reg *prev_regs;
30 struct frame_id this_id;
31};
32
33struct trad_frame_cache *
34trad_frame_cache_zalloc (struct frame_info *next_frame)
35{
36 struct trad_frame_cache *this_trad_cache;
37
38 this_trad_cache = FRAME_OBSTACK_ZALLOC (struct trad_frame_cache);
39 this_trad_cache->prev_regs = trad_frame_alloc_saved_regs (next_frame);
40 this_trad_cache->next_frame = next_frame;
41 return this_trad_cache;
42}
43
a0f267c7
AC
44/* A traditional frame is unwound by analysing the function prologue
45 and using the information gathered to track registers. For
46 non-optimized frames, the technique is reliable (just need to check
47 for all potential instruction sequences). */
48
8983bd83 49struct trad_frame_saved_reg *
a0f267c7
AC
50trad_frame_alloc_saved_regs (struct frame_info *next_frame)
51{
8983bd83 52 int regnum;
a0f267c7 53 struct gdbarch *gdbarch = get_frame_arch (next_frame);
40a6adc1 54 int numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
8983bd83
AC
55 struct trad_frame_saved_reg *this_saved_regs
56 = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
57 for (regnum = 0; regnum < numregs; regnum++)
3b3850e8
AC
58 {
59 this_saved_regs[regnum].realreg = regnum;
60 this_saved_regs[regnum].addr = -1;
61 }
a0f267c7
AC
62 return this_saved_regs;
63}
64
3b3850e8
AC
65enum { REG_VALUE = -1, REG_UNKNOWN = -2 };
66
67int
68trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
69{
70 return (this_saved_regs[regnum].realreg == REG_VALUE);
71}
72
73int
74trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
75{
76 return (this_saved_regs[regnum].realreg >= 0
77 && this_saved_regs[regnum].addr != -1);
78}
79
80int
81trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[],
82 int regnum)
83{
84 return (this_saved_regs[regnum].realreg >= 0
85 && this_saved_regs[regnum].addr == -1);
86}
87
a0f267c7 88void
3b3850e8
AC
89trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[],
90 int regnum, LONGEST val)
a0f267c7 91{
3b3850e8 92 /* Make the REALREG invalid, indicating that the ADDR contains the
a0f267c7 93 register's value. */
3b3850e8 94 this_saved_regs[regnum].realreg = REG_VALUE;
a0f267c7
AC
95 this_saved_regs[regnum].addr = val;
96}
97
61e784e7
MS
98void
99trad_frame_set_reg_value (struct trad_frame_cache *this_trad_cache,
100 int regnum, LONGEST val)
101{
102 /* External interface for users of trad_frame_cache
103 (who cannot access the prev_regs object directly). */
104 trad_frame_set_value (this_trad_cache->prev_regs, regnum, val);
105}
106
e66299b3
AC
107void
108trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache,
109 int regnum, int realreg)
110{
111 this_trad_cache->prev_regs[regnum].realreg = realreg;
112 this_trad_cache->prev_regs[regnum].addr = -1;
113}
114
0db9b4b7
AC
115void
116trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
117 int regnum, CORE_ADDR addr)
118{
119 this_trad_cache->prev_regs[regnum].addr = addr;
120}
121
3b3850e8
AC
122void
123trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[],
124 int regnum)
125{
126 /* Make the REALREG invalid, indicating that the value is not known. */
127 this_saved_regs[regnum].realreg = REG_UNKNOWN;
128 this_saved_regs[regnum].addr = -1;
129}
130
a0f267c7 131void
1f67027d
AC
132trad_frame_get_prev_register (struct frame_info *next_frame,
133 struct trad_frame_saved_reg this_saved_regs[],
134 int regnum, int *optimizedp,
135 enum lval_type *lvalp, CORE_ADDR *addrp,
10c42a71 136 int *realregp, gdb_byte *bufferp)
a0f267c7
AC
137{
138 struct gdbarch *gdbarch = get_frame_arch (next_frame);
3b3850e8 139 if (trad_frame_addr_p (this_saved_regs, regnum))
a0f267c7 140 {
8983bd83 141 /* The register was saved in memory. */
a0f267c7
AC
142 *optimizedp = 0;
143 *lvalp = lval_memory;
144 *addrp = this_saved_regs[regnum].addr;
3b3850e8 145 *realregp = -1;
a0f267c7
AC
146 if (bufferp != NULL)
147 {
148 /* Read the value in from memory. */
149 get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp,
150 register_size (gdbarch, regnum));
151 }
152 }
3b3850e8 153 else if (trad_frame_realreg_p (this_saved_regs, regnum))
a0f267c7 154 {
00b25ff3
AC
155 *optimizedp = 0;
156 *lvalp = lval_register;
157 *addrp = 0;
158 *realregp = this_saved_regs[regnum].realreg;
260a4188 159 /* Ask the next frame to return the value of the register. */
00b25ff3
AC
160 if (bufferp)
161 frame_unwind_register (next_frame, (*realregp), bufferp);
a0f267c7 162 }
3b3850e8 163 else if (trad_frame_value_p (this_saved_regs, regnum))
a0f267c7
AC
164 {
165 /* The register's value is available. */
166 *optimizedp = 0;
167 *lvalp = not_lval;
168 *addrp = 0;
3b3850e8 169 *realregp = -1;
a0f267c7
AC
170 if (bufferp != NULL)
171 store_unsigned_integer (bufferp, register_size (gdbarch, regnum),
172 this_saved_regs[regnum].addr);
173 }
3b3850e8
AC
174 else
175 {
8a3fe4f8 176 error (_("Register %s not available"),
3b3850e8
AC
177 gdbarch_register_name (gdbarch, regnum));
178 }
a0f267c7 179}
0db9b4b7
AC
180
181void
182trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
183 struct frame_info *next_frame,
184 int regnum, int *optimizedp,
185 enum lval_type *lvalp, CORE_ADDR *addrp,
10c42a71 186 int *realregp, gdb_byte *bufferp)
0db9b4b7 187{
1f67027d
AC
188 trad_frame_get_prev_register (next_frame, this_trad_cache->prev_regs,
189 regnum, optimizedp, lvalp, addrp, realregp,
190 bufferp);
0db9b4b7
AC
191}
192
193void
194trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
195 struct frame_id this_id)
196{
197 this_trad_cache->this_id = this_id;
198}
199
200void
201trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
202 struct frame_id *this_id)
203{
204 (*this_id) = this_trad_cache->this_id;
205}
e66299b3
AC
206
207void
208trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache,
209 CORE_ADDR this_base)
210{
211 this_trad_cache->this_base = this_base;
212}
213
214CORE_ADDR
215trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache)
216{
217 return this_trad_cache->this_base;
218}
This page took 0.608111 seconds and 4 git commands to generate.