Commit | Line | Data |
---|---|---|
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 | #ifndef TRAD_FRAME_H | |
21 | #define TRAD_FRAME_H | |
22 | ||
0db9b4b7 AC |
23 | #include "frame.h" /* For "struct frame_id". */ |
24 | ||
2cdf3c63 | 25 | struct frame_info; |
498f7407 | 26 | struct regcache_map_entry; |
0db9b4b7 AC |
27 | struct trad_frame_cache; |
28 | ||
29 | /* A simple, or traditional frame cache. | |
30 | ||
31 | The entire cache is populated in a single pass and then generic | |
32 | routines are used to extract the various cache values. */ | |
33 | ||
c378eb4e | 34 | struct trad_frame_cache *trad_frame_cache_zalloc (struct frame_info *); |
0db9b4b7 AC |
35 | |
36 | /* This frame's ID. */ | |
37 | void trad_frame_set_id (struct trad_frame_cache *this_trad_cache, | |
38 | struct frame_id this_id); | |
39 | void trad_frame_get_id (struct trad_frame_cache *this_trad_cache, | |
40 | struct frame_id *this_id); | |
e66299b3 AC |
41 | void trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache, |
42 | CORE_ADDR this_base); | |
43 | CORE_ADDR trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache); | |
0db9b4b7 | 44 | |
e66299b3 AC |
45 | void trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache, |
46 | int regnum, int realreg); | |
4be282b4 AC |
47 | void trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache, |
48 | int regnum, CORE_ADDR addr); | |
498f7407 JB |
49 | void trad_frame_set_reg_regmap (struct trad_frame_cache *this_trad_cache, |
50 | const struct regcache_map_entry *regmap, | |
51 | CORE_ADDR addr, size_t size); | |
61e784e7 MS |
52 | void trad_frame_set_reg_value (struct trad_frame_cache *this_cache, |
53 | int regnum, LONGEST val); | |
54 | ||
6afcd2d4 LM |
55 | /* Given the cache in THIS_TRAD_CACHE, set the value of REGNUM to the bytes |
56 | contained in BYTES with size SIZE. */ | |
57 | void trad_frame_set_reg_value_bytes (struct trad_frame_cache *this_trad_cache, | |
58 | int regnum, const gdb_byte *bytes, | |
59 | size_t size); | |
60 | ||
25492ce3 DJ |
61 | struct value *trad_frame_get_register (struct trad_frame_cache *this_trad_cache, |
62 | struct frame_info *this_frame, | |
63 | int regnum); | |
2cdf3c63 | 64 | |
098caef4 LM |
65 | /* Describes the kind of encoding a stored register has. */ |
66 | enum class trad_frame_saved_reg_kind | |
67 | { | |
68 | /* Register value is unknown. */ | |
69 | UNKNOWN = 0, | |
70 | /* Register value is a constant. */ | |
71 | VALUE, | |
72 | /* Register value is in another register. */ | |
73 | REALREG, | |
74 | /* Register value is at an address. */ | |
75 | ADDR, | |
76 | /* Register value is a sequence of bytes. */ | |
77 | VALUE_BYTES | |
78 | }; | |
3b3850e8 | 79 | |
098caef4 | 80 | /* A struct that describes a saved register in a frame. */ |
8983bd83 AC |
81 | |
82 | struct trad_frame_saved_reg | |
a0f267c7 | 83 | { |
098caef4 LM |
84 | /* Setters */ |
85 | ||
86 | /* Encode that the saved register's value is constant VAL in the | |
87 | trad-frame. */ | |
88 | void set_value (LONGEST val) | |
89 | { | |
90 | m_kind = trad_frame_saved_reg_kind::VALUE; | |
91 | m_reg.value = val; | |
92 | } | |
93 | ||
94 | /* Encode that the saved register's value is stored in register REALREG. */ | |
95 | void set_realreg (int realreg) | |
96 | { | |
97 | m_kind = trad_frame_saved_reg_kind::REALREG; | |
98 | m_reg.realreg = realreg; | |
99 | } | |
100 | ||
101 | /* Encode that the saved register's value is stored in memory at ADDR. */ | |
102 | void set_addr (LONGEST addr) | |
103 | { | |
104 | m_kind = trad_frame_saved_reg_kind::ADDR; | |
105 | m_reg.addr = addr; | |
106 | } | |
107 | ||
108 | /* Encode that the saved register's value is unknown. */ | |
109 | void set_unknown () | |
110 | { | |
111 | m_kind = trad_frame_saved_reg_kind::UNKNOWN; | |
112 | } | |
113 | ||
114 | /* Encode that the saved register's value is stored as a sequence of bytes. | |
115 | This is useful when the value is larger than what primitive types | |
116 | can hold. */ | |
117 | void set_value_bytes (const gdb_byte *value_bytes) | |
118 | { | |
119 | m_kind = trad_frame_saved_reg_kind::VALUE_BYTES; | |
120 | m_reg.value_bytes = value_bytes; | |
121 | } | |
122 | ||
123 | /* Getters */ | |
124 | ||
125 | LONGEST value () const | |
126 | { | |
127 | gdb_assert (m_kind == trad_frame_saved_reg_kind::VALUE); | |
128 | return m_reg.value; | |
129 | } | |
130 | ||
131 | int realreg () const | |
132 | { | |
133 | gdb_assert (m_kind == trad_frame_saved_reg_kind::REALREG); | |
134 | return m_reg.realreg; | |
135 | } | |
136 | ||
137 | LONGEST addr () const | |
138 | { | |
139 | gdb_assert (m_kind == trad_frame_saved_reg_kind::ADDR); | |
140 | return m_reg.addr; | |
141 | } | |
142 | ||
143 | const gdb_byte *value_bytes () const | |
144 | { | |
145 | gdb_assert (m_kind == trad_frame_saved_reg_kind::VALUE_BYTES); | |
146 | return m_reg.value_bytes; | |
147 | } | |
148 | ||
149 | /* Convenience functions, return true if the register has been | |
150 | encoded as specified. Return false otherwise. */ | |
151 | bool is_value () const | |
152 | { | |
153 | return m_kind == trad_frame_saved_reg_kind::VALUE; | |
154 | } | |
155 | ||
156 | bool is_realreg () const | |
157 | { | |
158 | return m_kind == trad_frame_saved_reg_kind::REALREG; | |
159 | } | |
160 | ||
161 | bool is_addr () const | |
162 | { | |
163 | return m_kind == trad_frame_saved_reg_kind::ADDR; | |
164 | } | |
165 | ||
166 | bool is_unknown () const | |
167 | { | |
168 | return m_kind == trad_frame_saved_reg_kind::UNKNOWN; | |
169 | } | |
170 | ||
171 | bool is_value_bytes () const | |
172 | { | |
173 | return m_kind == trad_frame_saved_reg_kind::VALUE_BYTES; | |
174 | } | |
175 | ||
176 | private: | |
177 | ||
178 | trad_frame_saved_reg_kind m_kind; | |
179 | ||
180 | union { | |
181 | LONGEST value; | |
182 | int realreg; | |
183 | LONGEST addr; | |
184 | const gdb_byte *value_bytes; | |
185 | } m_reg; | |
a0f267c7 AC |
186 | }; |
187 | ||
3b3850e8 | 188 | /* Encode REGNUM value in the trad-frame. */ |
098caef4 | 189 | void trad_frame_set_value (trad_frame_saved_reg this_saved_regs[], |
3b3850e8 AC |
190 | int regnum, LONGEST val); |
191 | ||
23e60e7a | 192 | /* Encode REGNUM is in REALREG in the trad-frame. */ |
098caef4 | 193 | void trad_frame_set_realreg (trad_frame_saved_reg this_saved_regs[], |
23e60e7a AB |
194 | int regnum, int realreg); |
195 | ||
196 | /* Encode REGNUM is at address ADDR in the trad-frame. */ | |
098caef4 | 197 | void trad_frame_set_addr (trad_frame_saved_reg this_trad_cache[], |
23e60e7a AB |
198 | int regnum, CORE_ADDR addr); |
199 | ||
3b3850e8 | 200 | /* Mark REGNUM as unknown. */ |
098caef4 | 201 | void trad_frame_set_unknown (trad_frame_saved_reg this_saved_regs[], |
3b3850e8 AC |
202 | int regnum); |
203 | ||
6afcd2d4 LM |
204 | /* Encode REGNUM value in the trad-frame as a sequence of bytes. This is |
205 | useful when the value is larger than what primitive types can hold. */ | |
098caef4 | 206 | void trad_frame_set_value_bytes (trad_frame_saved_reg this_saved_regs[], |
6afcd2d4 LM |
207 | int regnum, const gdb_byte *bytes, |
208 | size_t size); | |
209 | ||
3b3850e8 AC |
210 | /* Convenience functions, return non-zero if the register has been |
211 | encoded as specified. */ | |
098caef4 | 212 | int trad_frame_value_p (trad_frame_saved_reg this_saved_regs[], |
3b3850e8 | 213 | int regnum); |
098caef4 | 214 | int trad_frame_addr_p (trad_frame_saved_reg this_saved_regs[], |
3b3850e8 | 215 | int regnum); |
098caef4 | 216 | int trad_frame_realreg_p (trad_frame_saved_reg this_saved_regs[], |
3b3850e8 AC |
217 | int regnum); |
218 | ||
6afcd2d4 LM |
219 | /* Return TRUE if REGNUM is stored as a sequence of bytes, and FALSE |
220 | otherwise. */ | |
098caef4 | 221 | bool trad_frame_value_bytes_p (trad_frame_saved_reg this_saved_regs[], |
6afcd2d4 LM |
222 | int regnum); |
223 | ||
098caef4 | 224 | /* Reset the saved regs cache, setting register values to -1. */ |
68811f8f | 225 | void trad_frame_reset_saved_regs (struct gdbarch *gdbarch, |
098caef4 | 226 | trad_frame_saved_reg *regs); |
a0f267c7 AC |
227 | |
228 | /* Return a freshly allocated (and initialized) trad_frame array. */ | |
098caef4 LM |
229 | trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct frame_info *); |
230 | trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct gdbarch *); | |
a0f267c7 AC |
231 | |
232 | /* Given the trad_frame info, return the location of the specified | |
233 | register. */ | |
25492ce3 | 234 | struct value *trad_frame_get_prev_register (struct frame_info *this_frame, |
098caef4 | 235 | trad_frame_saved_reg this_saved_regs[], |
25492ce3 | 236 | int regnum); |
a0f267c7 AC |
237 | |
238 | #endif |