PR22150, ld keeps a version reference for gc'd symbols
[deliverable/binutils-gdb.git] / gdb / trad-frame.c
CommitLineData
a0f267c7
AC
1/* Traditional frame unwind support, for GDB the GNU Debugger.
2
61baf725 3 Copyright (C) 2003-2017 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
61e784e7
MS
108void
109trad_frame_set_reg_value (struct trad_frame_cache *this_trad_cache,
110 int regnum, LONGEST val)
111{
112 /* External interface for users of trad_frame_cache
113 (who cannot access the prev_regs object directly). */
114 trad_frame_set_value (this_trad_cache->prev_regs, regnum, val);
115}
116
e66299b3
AC
117void
118trad_frame_set_reg_realreg (struct trad_frame_cache *this_trad_cache,
119 int regnum, int realreg)
120{
121 this_trad_cache->prev_regs[regnum].realreg = realreg;
122 this_trad_cache->prev_regs[regnum].addr = -1;
123}
124
0db9b4b7
AC
125void
126trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
127 int regnum, CORE_ADDR addr)
128{
129 this_trad_cache->prev_regs[regnum].addr = addr;
130}
131
3b3850e8
AC
132void
133trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[],
134 int regnum)
135{
136 /* Make the REALREG invalid, indicating that the value is not known. */
ee99023e 137 this_saved_regs[regnum].realreg = TF_REG_UNKNOWN;
3b3850e8
AC
138 this_saved_regs[regnum].addr = -1;
139}
140
25492ce3
DJ
141struct value *
142trad_frame_get_prev_register (struct frame_info *this_frame,
1f67027d 143 struct trad_frame_saved_reg this_saved_regs[],
25492ce3 144 int regnum)
a0f267c7 145{
3b3850e8 146 if (trad_frame_addr_p (this_saved_regs, regnum))
25492ce3
DJ
147 /* The register was saved in memory. */
148 return frame_unwind_got_memory (this_frame, regnum,
149 this_saved_regs[regnum].addr);
3b3850e8 150 else if (trad_frame_realreg_p (this_saved_regs, regnum))
25492ce3
DJ
151 return frame_unwind_got_register (this_frame, regnum,
152 this_saved_regs[regnum].realreg);
3b3850e8 153 else if (trad_frame_value_p (this_saved_regs, regnum))
25492ce3
DJ
154 /* The register's value is available. */
155 return frame_unwind_got_constant (this_frame, regnum,
156 this_saved_regs[regnum].addr);
3b3850e8 157 else
25492ce3 158 return frame_unwind_got_optimized (this_frame, regnum);
a0f267c7 159}
0db9b4b7 160
25492ce3 161struct value *
0db9b4b7 162trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
25492ce3
DJ
163 struct frame_info *this_frame,
164 int regnum)
165{
166 return trad_frame_get_prev_register (this_frame, this_trad_cache->prev_regs,
167 regnum);
0db9b4b7
AC
168}
169
170void
171trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
172 struct frame_id this_id)
173{
174 this_trad_cache->this_id = this_id;
175}
176
177void
178trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
179 struct frame_id *this_id)
180{
181 (*this_id) = this_trad_cache->this_id;
182}
e66299b3
AC
183
184void
185trad_frame_set_this_base (struct trad_frame_cache *this_trad_cache,
186 CORE_ADDR this_base)
187{
188 this_trad_cache->this_base = this_base;
189}
190
191CORE_ADDR
192trad_frame_get_this_base (struct trad_frame_cache *this_trad_cache)
193{
194 return this_trad_cache->this_base;
195}
This page took 1.531931 seconds and 4 git commands to generate.