Convert some frame functions to use gdb::array_view.
[deliverable/binutils-gdb.git] / gdb / trad-frame.c
CommitLineData
a0f267c7
AC
1/* Traditional frame unwind support, for GDB the GNU Debugger.
2
3666a048 3 Copyright (C) 2003-2021 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"
25492ce3 24#include "frame-unwind.h"
498f7407 25#include "target.h"
25492ce3 26#include "value.h"
0d12e84c 27#include "gdbarch.h"
58eadc4b 28#include "gdbsupport/traits.h"
a0f267c7 29
0db9b4b7
AC
30struct trad_frame_cache
31{
25492ce3 32 struct frame_info *this_frame;
0db9b4b7 33 CORE_ADDR this_base;
098caef4 34 trad_frame_saved_reg *prev_regs;
0db9b4b7
AC
35 struct frame_id this_id;
36};
37
38struct trad_frame_cache *
25492ce3 39trad_frame_cache_zalloc (struct frame_info *this_frame)
0db9b4b7
AC
40{
41 struct trad_frame_cache *this_trad_cache;
42
43 this_trad_cache = FRAME_OBSTACK_ZALLOC (struct trad_frame_cache);
25492ce3
DJ
44 this_trad_cache->prev_regs = trad_frame_alloc_saved_regs (this_frame);
45 this_trad_cache->this_frame = this_frame;
0db9b4b7
AC
46 return this_trad_cache;
47}
48
68811f8f
AH
49/* See trad-frame.h. */
50
51void
52trad_frame_reset_saved_regs (struct gdbarch *gdbarch,
098caef4 53 trad_frame_saved_reg *regs)
68811f8f
AH
54{
55 int numregs = gdbarch_num_cooked_regs (gdbarch);
098caef4 56
68811f8f 57 for (int regnum = 0; regnum < numregs; regnum++)
098caef4 58 regs[regnum].set_realreg (regnum);
68811f8f
AH
59}
60
098caef4 61trad_frame_saved_reg *
4d9a9006 62trad_frame_alloc_saved_regs (struct gdbarch *gdbarch)
a0f267c7 63{
58eadc4b
BE
64#ifdef HAVE_IS_TRIVIALLY_CONSTRUCTIBLE
65 gdb_static_assert (std::is_trivially_constructible<trad_frame_saved_reg>::value);
66#endif
098caef4 67
f6efe3f8 68 int numregs = gdbarch_num_cooked_regs (gdbarch);
098caef4
LM
69 trad_frame_saved_reg *this_saved_regs
70 = FRAME_OBSTACK_CALLOC (numregs, trad_frame_saved_reg);
5d502164 71
68811f8f 72 trad_frame_reset_saved_regs (gdbarch, this_saved_regs);
a0f267c7
AC
73 return this_saved_regs;
74}
75
4d9a9006
YQ
76/* A traditional frame is unwound by analysing the function prologue
77 and using the information gathered to track registers. For
78 non-optimized frames, the technique is reliable (just need to check
79 for all potential instruction sequences). */
80
098caef4 81trad_frame_saved_reg *
4d9a9006
YQ
82trad_frame_alloc_saved_regs (struct frame_info *this_frame)
83{
84 struct gdbarch *gdbarch = get_frame_arch (this_frame);
85
86 return trad_frame_alloc_saved_regs (gdbarch);
87}
88
3b3850e8 89int
098caef4 90trad_frame_value_p (trad_frame_saved_reg this_saved_regs[], int regnum)
3b3850e8 91{
098caef4 92 return this_saved_regs[regnum].is_value ();
3b3850e8
AC
93}
94
95int
098caef4 96trad_frame_addr_p (trad_frame_saved_reg this_saved_regs[], int regnum)
3b3850e8 97{
098caef4 98 return this_saved_regs[regnum].is_addr ();
3b3850e8
AC
99}
100
101int
098caef4 102trad_frame_realreg_p (trad_frame_saved_reg this_saved_regs[],
3b3850e8
AC
103 int regnum)
104{
098caef4 105 return this_saved_regs[regnum].is_realreg ();
3b3850e8
AC
106}
107
6afcd2d4
LM
108/* See trad-frame.h. */
109
110bool
098caef4 111trad_frame_value_bytes_p (trad_frame_saved_reg this_saved_regs[],
6afcd2d4
LM
112 int regnum)
113{
098caef4 114 return this_saved_regs[regnum].is_value_bytes ();
6afcd2d4
LM
115}
116
a0f267c7 117void
098caef4 118trad_frame_set_value (trad_frame_saved_reg this_saved_regs[],
3b3850e8 119 int regnum, LONGEST val)
a0f267c7 120{
098caef4 121 this_saved_regs[regnum].set_value (val);
a0f267c7
AC
122}
123
23e60e7a
AB
124/* See trad-frame.h. */
125
126void
098caef4 127trad_frame_set_realreg (trad_frame_saved_reg this_saved_regs[],
23e60e7a
AB
128 int regnum, int realreg)
129{
098caef4 130 this_saved_regs[regnum].set_realreg (realreg);
23e60e7a
AB
131}
132
133/* See trad-frame.h. */
134
135void
098caef4 136trad_frame_set_addr (trad_frame_saved_reg this_saved_regs[],
23e60e7a
AB
137 int regnum, CORE_ADDR addr)
138{
098caef4 139 this_saved_regs[regnum].set_addr (addr);
23e60e7a
AB
140}
141
61e784e7
MS
142void
143trad_frame_set_reg_value (struct trad_frame_cache *this_trad_cache,
144 int regnum, LONGEST val)
145{
146 /* External interface for users of trad_frame_cache
147 (who cannot access the prev_regs object directly). */
148 trad_frame_set_value (this_trad_cache->prev_regs, regnum, val);
149}
150
e66299b3
AC
151void
152trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache,
153 int regnum, int realreg)
154{
23e60e7a 155 trad_frame_set_realreg (this_trad_cache->prev_regs, regnum, realreg);
e66299b3
AC
156}
157
0db9b4b7
AC
158void
159trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
160 int regnum, CORE_ADDR addr)
161{
23e60e7a 162 trad_frame_set_addr (this_trad_cache->prev_regs, regnum, addr);
0db9b4b7
AC
163}
164
498f7407
JB
165void
166trad_frame_set_reg_regmap (struct trad_frame_cache *this_trad_cache,
167 const struct regcache_map_entry *regmap,
168 CORE_ADDR addr, size_t size)
169{
170 struct gdbarch *gdbarch = get_frame_arch (this_trad_cache->this_frame);
171 int offs = 0, count;
172
173 for (; (count = regmap->count) != 0; regmap++)
174 {
175 int regno = regmap->regno;
176 int slot_size = regmap->size;
177
178 if (slot_size == 0 && regno != REGCACHE_MAP_SKIP)
179 slot_size = register_size (gdbarch, regno);
180
181 if (offs + slot_size > size)
182 break;
183
184 if (regno == REGCACHE_MAP_SKIP)
185 offs += count * slot_size;
186 else
187 for (; count--; regno++, offs += slot_size)
188 {
189 /* Mimic the semantics of regcache::transfer_regset if a
190 register slot's size does not match the size of a
191 register.
192
193 If a register slot is larger than a register, assume
194 the register's value is stored in the first N bytes of
195 the slot and ignore the remaining bytes.
196
197 If the register slot is smaller than the register,
198 assume that the slot contains the low N bytes of the
199 register's value. Since trad_frame assumes that
200 registers stored by address are sized according to the
201 register, read the low N bytes and zero-extend them to
202 generate a register value. */
203 if (slot_size >= register_size (gdbarch, regno))
204 trad_frame_set_reg_addr (this_trad_cache, regno, addr + offs);
205 else
206 {
207 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
208 gdb_byte buf[slot_size];
209
210 if (target_read_memory (addr + offs, buf, sizeof buf) == 0)
211 {
212 LONGEST val
213 = extract_unsigned_integer (buf, sizeof buf, byte_order);
214 trad_frame_set_reg_value (this_trad_cache, regno, val);
215 }
216 }
217 }
218 }
219}
220
3b3850e8 221void
098caef4 222trad_frame_set_unknown (trad_frame_saved_reg this_saved_regs[],
3b3850e8
AC
223 int regnum)
224{
098caef4 225 this_saved_regs[regnum].set_unknown ();
3b3850e8
AC
226}
227
6afcd2d4
LM
228/* See trad-frame.h. */
229
230void
098caef4 231trad_frame_set_value_bytes (trad_frame_saved_reg this_saved_regs[],
ccbe4c82
LM
232 int regnum,
233 gdb::array_view<const gdb_byte> bytes)
6afcd2d4 234{
6afcd2d4 235 /* Allocate the space and copy the data bytes. */
ccbe4c82
LM
236 gdb_byte *data = FRAME_OBSTACK_CALLOC (bytes.size (), gdb_byte);
237 memcpy (data, bytes.data (), bytes.size ());
098caef4 238 this_saved_regs[regnum].set_value_bytes (data);
6afcd2d4
LM
239}
240
241/* See trad-frame.h. */
242
243void
244trad_frame_set_reg_value_bytes (struct trad_frame_cache *this_trad_cache,
ccbe4c82
LM
245 int regnum,
246 gdb::array_view<const gdb_byte> bytes)
6afcd2d4
LM
247{
248 /* External interface for users of trad_frame_cache
249 (who cannot access the prev_regs object directly). */
ccbe4c82 250 trad_frame_set_value_bytes (this_trad_cache->prev_regs, regnum, bytes);
6afcd2d4
LM
251}
252
253
254
25492ce3
DJ
255struct value *
256trad_frame_get_prev_register (struct frame_info *this_frame,
098caef4 257 trad_frame_saved_reg this_saved_regs[],
25492ce3 258 int regnum)
a0f267c7 259{
3b3850e8 260 if (trad_frame_addr_p (this_saved_regs, regnum))
25492ce3
DJ
261 /* The register was saved in memory. */
262 return frame_unwind_got_memory (this_frame, regnum,
098caef4 263 this_saved_regs[regnum].addr ());
3b3850e8 264 else if (trad_frame_realreg_p (this_saved_regs, regnum))
25492ce3 265 return frame_unwind_got_register (this_frame, regnum,
098caef4 266 this_saved_regs[regnum].realreg ());
3b3850e8 267 else if (trad_frame_value_p (this_saved_regs, regnum))
25492ce3
DJ
268 /* The register's value is available. */
269 return frame_unwind_got_constant (this_frame, regnum,
098caef4 270 this_saved_regs[regnum].value ());
6afcd2d4
LM
271 else if (trad_frame_value_bytes_p (this_saved_regs, regnum))
272 /* The register's value is available as a sequence of bytes. */
273 return frame_unwind_got_bytes (this_frame, regnum,
098caef4 274 this_saved_regs[regnum].value_bytes ());
3b3850e8 275 else
25492ce3 276 return frame_unwind_got_optimized (this_frame, regnum);
a0f267c7 277}
0db9b4b7 278
25492ce3 279struct value *
0db9b4b7 280trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
25492ce3
DJ
281 struct frame_info *this_frame,
282 int regnum)
283{
284 return trad_frame_get_prev_register (this_frame, this_trad_cache->prev_regs,
285 regnum);
0db9b4b7
AC
286}
287
288void
289trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
290 struct frame_id this_id)
291{
292 this_trad_cache->this_id = this_id;
293}
294
295void
296trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
297 struct frame_id *this_id)
298{
299 (*this_id) = this_trad_cache->this_id;
300}
e66299b3
AC
301
302void
303trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache,
304 CORE_ADDR this_base)
305{
306 this_trad_cache->this_base = this_base;
307}
308
309CORE_ADDR
310trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache)
311{
312 return this_trad_cache->this_base;
313}
This page took 1.960987 seconds and 4 git commands to generate.