]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/trad-frame.c
This commit was manufactured by cvs2svn to create branch
[thirdparty/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"
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
a0f267c7
AC
46/* A traditional frame is unwound by analysing the function prologue
47 and using the information gathered to track registers. For
48 non-optimized frames, the technique is reliable (just need to check
49 for all potential instruction sequences). */
50
8983bd83 51struct trad_frame_saved_reg *
25492ce3 52trad_frame_alloc_saved_regs (struct frame_info *this_frame)
a0f267c7 53{
8983bd83 54 int regnum;
25492ce3 55 struct gdbarch *gdbarch = get_frame_arch (this_frame);
40a6adc1 56 int numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
8983bd83
AC
57 struct trad_frame_saved_reg *this_saved_regs
58 = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
59 for (regnum = 0; regnum < numregs; regnum++)
3b3850e8
AC
60 {
61 this_saved_regs[regnum].realreg = regnum;
62 this_saved_regs[regnum].addr = -1;
63 }
a0f267c7
AC
64 return this_saved_regs;
65}
66
3b3850e8
AC
67enum { REG_VALUE = -1, REG_UNKNOWN = -2 };
68
69int
70trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
71{
72 return (this_saved_regs[regnum].realreg == REG_VALUE);
73}
74
75int
76trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
77{
78 return (this_saved_regs[regnum].realreg >= 0
79 && this_saved_regs[regnum].addr != -1);
80}
81
82int
83trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[],
84 int regnum)
85{
86 return (this_saved_regs[regnum].realreg >= 0
87 && this_saved_regs[regnum].addr == -1);
88}
89
a0f267c7 90void
3b3850e8
AC
91trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[],
92 int regnum, LONGEST val)
a0f267c7 93{
3b3850e8 94 /* Make the REALREG invalid, indicating that the ADDR contains the
a0f267c7 95 register's value. */
3b3850e8 96 this_saved_regs[regnum].realreg = REG_VALUE;
a0f267c7
AC
97 this_saved_regs[regnum].addr = val;
98}
99
61e784e7
MS
100void
101trad_frame_set_reg_value (struct trad_frame_cache *this_trad_cache,
102 int regnum, LONGEST val)
103{
104 /* External interface for users of trad_frame_cache
105 (who cannot access the prev_regs object directly). */
106 trad_frame_set_value (this_trad_cache->prev_regs, regnum, val);
107}
108
e66299b3
AC
109void
110trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache,
111 int regnum, int realreg)
112{
113 this_trad_cache->prev_regs[regnum].realreg = realreg;
114 this_trad_cache->prev_regs[regnum].addr = -1;
115}
116
0db9b4b7
AC
117void
118trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
119 int regnum, CORE_ADDR addr)
120{
121 this_trad_cache->prev_regs[regnum].addr = addr;
122}
123
3b3850e8
AC
124void
125trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[],
126 int regnum)
127{
128 /* Make the REALREG invalid, indicating that the value is not known. */
129 this_saved_regs[regnum].realreg = REG_UNKNOWN;
130 this_saved_regs[regnum].addr = -1;
131}
132
25492ce3
DJ
133struct value *
134trad_frame_get_prev_register (struct frame_info *this_frame,
1f67027d 135 struct trad_frame_saved_reg this_saved_regs[],
25492ce3 136 int regnum)
a0f267c7 137{
25492ce3 138 struct gdbarch *gdbarch = get_frame_arch (this_frame);
3b3850e8 139 if (trad_frame_addr_p (this_saved_regs, regnum))
25492ce3
DJ
140 /* The register was saved in memory. */
141 return frame_unwind_got_memory (this_frame, regnum,
142 this_saved_regs[regnum].addr);
3b3850e8 143 else if (trad_frame_realreg_p (this_saved_regs, regnum))
25492ce3
DJ
144 return frame_unwind_got_register (this_frame, regnum,
145 this_saved_regs[regnum].realreg);
3b3850e8 146 else if (trad_frame_value_p (this_saved_regs, regnum))
25492ce3
DJ
147 /* The register's value is available. */
148 return frame_unwind_got_constant (this_frame, regnum,
149 this_saved_regs[regnum].addr);
3b3850e8 150 else
25492ce3 151 return frame_unwind_got_optimized (this_frame, regnum);
a0f267c7 152}
0db9b4b7 153
25492ce3 154struct value *
0db9b4b7 155trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
25492ce3
DJ
156 struct frame_info *this_frame,
157 int regnum)
158{
159 return trad_frame_get_prev_register (this_frame, this_trad_cache->prev_regs,
160 regnum);
0db9b4b7
AC
161}
162
163void
164trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
165 struct frame_id this_id)
166{
167 this_trad_cache->this_id = this_id;
168}
169
170void
171trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
172 struct frame_id *this_id)
173{
174 (*this_id) = this_trad_cache->this_id;
175}
e66299b3
AC
176
177void
178trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache,
179 CORE_ADDR this_base)
180{
181 this_trad_cache->this_base = this_base;
182}
183
184CORE_ADDR
185trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache)
186{
187 return this_trad_cache->this_base;
188}