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