]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/trad-frame.c
2010-05-16 Michael Snyder <msnyder@vmware.com>
[thirdparty/binutils-gdb.git] / gdb / trad-frame.c
CommitLineData
a0f267c7
AC
1/* Traditional frame unwind support, for GDB the GNU Debugger.
2
4c38e0a4
JB
3 Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
a0f267c7
AC
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
a0f267c7
AC
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
a0f267c7
AC
20
21#include "defs.h"
22#include "frame.h"
23#include "trad-frame.h"
24#include "regcache.h"
25492ce3
DJ
25#include "frame-unwind.h"
26#include "value.h"
a0f267c7 27
0db9b4b7
AC
28struct trad_frame_cache
29{
25492ce3 30 struct frame_info *this_frame;
0db9b4b7
AC
31 CORE_ADDR this_base;
32 struct trad_frame_saved_reg *prev_regs;
33 struct frame_id this_id;
34};
35
36struct trad_frame_cache *
25492ce3 37trad_frame_cache_zalloc (struct frame_info *this_frame)
0db9b4b7
AC
38{
39 struct trad_frame_cache *this_trad_cache;
40
41 this_trad_cache = FRAME_OBSTACK_ZALLOC (struct trad_frame_cache);
25492ce3
DJ
42 this_trad_cache->prev_regs = trad_frame_alloc_saved_regs (this_frame);
43 this_trad_cache->this_frame = this_frame;
0db9b4b7
AC
44 return this_trad_cache;
45}
46
a0f267c7
AC
47/* A traditional frame is unwound by analysing the function prologue
48 and using the information gathered to track registers. For
49 non-optimized frames, the technique is reliable (just need to check
50 for all potential instruction sequences). */
51
8983bd83 52struct trad_frame_saved_reg *
25492ce3 53trad_frame_alloc_saved_regs (struct frame_info *this_frame)
a0f267c7 54{
8983bd83 55 int regnum;
25492ce3 56 struct gdbarch *gdbarch = get_frame_arch (this_frame);
40a6adc1 57 int numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
8983bd83
AC
58 struct trad_frame_saved_reg *this_saved_regs
59 = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
5d502164 60
8983bd83 61 for (regnum = 0; regnum < numregs; regnum++)
3b3850e8
AC
62 {
63 this_saved_regs[regnum].realreg = regnum;
64 this_saved_regs[regnum].addr = -1;
65 }
a0f267c7
AC
66 return this_saved_regs;
67}
68
3b3850e8
AC
69enum { REG_VALUE = -1, REG_UNKNOWN = -2 };
70
71int
72trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
73{
74 return (this_saved_regs[regnum].realreg == REG_VALUE);
75}
76
77int
78trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[], int regnum)
79{
80 return (this_saved_regs[regnum].realreg >= 0
81 && this_saved_regs[regnum].addr != -1);
82}
83
84int
85trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[],
86 int regnum)
87{
88 return (this_saved_regs[regnum].realreg >= 0
89 && this_saved_regs[regnum].addr == -1);
90}
91
a0f267c7 92void
3b3850e8
AC
93trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[],
94 int regnum, LONGEST val)
a0f267c7 95{
3b3850e8 96 /* Make the REALREG invalid, indicating that the ADDR contains the
a0f267c7 97 register's value. */
3b3850e8 98 this_saved_regs[regnum].realreg = REG_VALUE;
a0f267c7
AC
99 this_saved_regs[regnum].addr = val;
100}
101
61e784e7
MS
102void
103trad_frame_set_reg_value (struct trad_frame_cache *this_trad_cache,
104 int regnum, LONGEST val)
105{
106 /* External interface for users of trad_frame_cache
107 (who cannot access the prev_regs object directly). */
108 trad_frame_set_value (this_trad_cache->prev_regs, regnum, val);
109}
110
e66299b3
AC
111void
112trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache,
113 int regnum, int realreg)
114{
115 this_trad_cache->prev_regs[regnum].realreg = realreg;
116 this_trad_cache->prev_regs[regnum].addr = -1;
117}
118
0db9b4b7
AC
119void
120trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
121 int regnum, CORE_ADDR addr)
122{
123 this_trad_cache->prev_regs[regnum].addr = addr;
124}
125
3b3850e8
AC
126void
127trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[],
128 int regnum)
129{
130 /* Make the REALREG invalid, indicating that the value is not known. */
131 this_saved_regs[regnum].realreg = REG_UNKNOWN;
132 this_saved_regs[regnum].addr = -1;
133}
134
25492ce3
DJ
135struct value *
136trad_frame_get_prev_register (struct frame_info *this_frame,
1f67027d 137 struct trad_frame_saved_reg this_saved_regs[],
25492ce3 138 int regnum)
a0f267c7 139{
3b3850e8 140 if (trad_frame_addr_p (this_saved_regs, regnum))
25492ce3
DJ
141 /* The register was saved in memory. */
142 return frame_unwind_got_memory (this_frame, regnum,
143 this_saved_regs[regnum].addr);
3b3850e8 144 else if (trad_frame_realreg_p (this_saved_regs, regnum))
25492ce3
DJ
145 return frame_unwind_got_register (this_frame, regnum,
146 this_saved_regs[regnum].realreg);
3b3850e8 147 else if (trad_frame_value_p (this_saved_regs, regnum))
25492ce3
DJ
148 /* The register's value is available. */
149 return frame_unwind_got_constant (this_frame, regnum,
150 this_saved_regs[regnum].addr);
3b3850e8 151 else
25492ce3 152 return frame_unwind_got_optimized (this_frame, regnum);
a0f267c7 153}
0db9b4b7 154
25492ce3 155struct value *
0db9b4b7 156trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
25492ce3
DJ
157 struct frame_info *this_frame,
158 int regnum)
159{
160 return trad_frame_get_prev_register (this_frame, this_trad_cache->prev_regs,
161 regnum);
0db9b4b7
AC
162}
163
164void
165trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
166 struct frame_id this_id)
167{
168 this_trad_cache->this_id = this_id;
169}
170
171void
172trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
173 struct frame_id *this_id)
174{
175 (*this_id) = this_trad_cache->this_id;
176}
e66299b3
AC
177
178void
179trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache,
180 CORE_ADDR this_base)
181{
182 this_trad_cache->this_base = this_base;
183}
184
185CORE_ADDR
186trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache)
187{
188 return this_trad_cache->this_base;
189}