]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tramp-frame.c
Add some more casts (1/2)
[thirdparty/binutils-gdb.git] / gdb / tramp-frame.c
CommitLineData
d2259dd3
AC
1/* Signal trampoline unwinder, for GDB the GNU Debugger.
2
32d0add0 3 Copyright (C) 2004-2015 Free Software Foundation, Inc.
d2259dd3
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
d2259dd3
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/>. */
d2259dd3
AC
19
20#include "defs.h"
21#include "tramp-frame.h"
22#include "frame-unwind.h"
23#include "gdbcore.h"
24#include "symtab.h"
25#include "objfiles.h"
26#include "target.h"
27#include "trad-frame.h"
28#include "frame-base.h"
29
30struct frame_data
31{
32 const struct tramp_frame *tramp_frame;
33};
34
35struct tramp_frame_cache
36{
37 CORE_ADDR func;
38 const struct tramp_frame *tramp_frame;
39 struct trad_frame_cache *trad_cache;
40};
41
42static struct trad_frame_cache *
25492ce3 43tramp_frame_cache (struct frame_info *this_frame,
d2259dd3
AC
44 void **this_cache)
45{
d2259dd3 46 struct tramp_frame_cache *tramp_cache = (*this_cache);
5d502164 47
d2259dd3
AC
48 if (tramp_cache->trad_cache == NULL)
49 {
25492ce3 50 tramp_cache->trad_cache = trad_frame_cache_zalloc (this_frame);
d2259dd3 51 tramp_cache->tramp_frame->init (tramp_cache->tramp_frame,
25492ce3 52 this_frame,
d2259dd3
AC
53 tramp_cache->trad_cache,
54 tramp_cache->func);
55 }
56 return tramp_cache->trad_cache;
57}
58
59static void
25492ce3 60tramp_frame_this_id (struct frame_info *this_frame,
d2259dd3
AC
61 void **this_cache,
62 struct frame_id *this_id)
63{
64 struct trad_frame_cache *trad_cache
25492ce3 65 = tramp_frame_cache (this_frame, this_cache);
5d502164 66
d2259dd3
AC
67 trad_frame_get_id (trad_cache, this_id);
68}
69
25492ce3
DJ
70static struct value *
71tramp_frame_prev_register (struct frame_info *this_frame,
d2259dd3 72 void **this_cache,
25492ce3 73 int prev_regnum)
d2259dd3
AC
74{
75 struct trad_frame_cache *trad_cache
25492ce3 76 = tramp_frame_cache (this_frame, this_cache);
5d502164 77
25492ce3 78 return trad_frame_get_register (trad_cache, this_frame, prev_regnum);
d2259dd3
AC
79}
80
81static CORE_ADDR
304396fb 82tramp_frame_start (const struct tramp_frame *tramp,
25492ce3 83 struct frame_info *this_frame, CORE_ADDR pc)
d2259dd3 84{
e17a4113
UW
85 struct gdbarch *gdbarch = get_frame_arch (this_frame);
86 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
d2259dd3 87 int ti;
5d502164 88
858339f2
MR
89 /* Check if we can use this trampoline. */
90 if (tramp->validate && !tramp->validate (tramp, this_frame, &pc))
91 return 0;
92
d2259dd3
AC
93 /* Search through the trampoline for one that matches the
94 instruction sequence around PC. */
2cd8546d 95 for (ti = 0; tramp->insn[ti].bytes != TRAMP_SENTINEL_INSN; ti++)
d2259dd3
AC
96 {
97 CORE_ADDR func = pc - tramp->insn_size * ti;
98 int i;
5d502164 99
d2259dd3
AC
100 for (i = 0; 1; i++)
101 {
fc1a4b47 102 gdb_byte buf[sizeof (tramp->insn[0])];
1196bfda 103 ULONGEST insn;
5d502164 104
2cd8546d 105 if (tramp->insn[i].bytes == TRAMP_SENTINEL_INSN)
d2259dd3 106 return func;
25492ce3 107 if (!safe_frame_unwind_memory (this_frame,
304396fb
AC
108 func + i * tramp->insn_size,
109 buf, tramp->insn_size))
d2259dd3 110 break;
e17a4113 111 insn = extract_unsigned_integer (buf, tramp->insn_size, byte_order);
2cd8546d 112 if (tramp->insn[i].bytes != (insn & tramp->insn[i].mask))
d2259dd3
AC
113 break;
114 }
115 }
116 /* Trampoline doesn't match. */
117 return 0;
118}
119
120static int
121tramp_frame_sniffer (const struct frame_unwind *self,
25492ce3 122 struct frame_info *this_frame,
d2259dd3
AC
123 void **this_cache)
124{
125 const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
25492ce3 126 CORE_ADDR pc = get_frame_pc (this_frame);
d2259dd3 127 CORE_ADDR func;
d2259dd3
AC
128 struct tramp_frame_cache *tramp_cache;
129
0efcf9dc
RC
130 /* tausq/2004-12-12: We used to assume if pc has a name or is in a valid
131 section, then this is not a trampoline. However, this assumption is
132 false on HPUX which has a signal trampoline that has a name; it can
133 also be false when using an alternative signal stack. */
25492ce3 134 func = tramp_frame_start (tramp, this_frame, pc);
d2259dd3
AC
135 if (func == 0)
136 return 0;
137 tramp_cache = FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache);
138 tramp_cache->func = func;
139 tramp_cache->tramp_frame = tramp;
140 (*this_cache) = tramp_cache;
141 return 1;
142}
143
144void
fb2be677
AC
145tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
146 const struct tramp_frame *tramp_frame)
d2259dd3
AC
147{
148 struct frame_data *data;
149 struct frame_unwind *unwinder;
1196bfda
AC
150 int i;
151
152 /* Check that the instruction sequence contains a sentinel. */
153 for (i = 0; i < ARRAY_SIZE (tramp_frame->insn); i++)
154 {
2cd8546d 155 if (tramp_frame->insn[i].bytes == TRAMP_SENTINEL_INSN)
1196bfda
AC
156 break;
157 }
158 gdb_assert (i < ARRAY_SIZE (tramp_frame->insn));
2cd8546d 159 gdb_assert (tramp_frame->insn_size <= sizeof (tramp_frame->insn[0].bytes));
d2259dd3
AC
160
161 data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
162 unwinder = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
163
164 data->tramp_frame = tramp_frame;
1f586765 165 unwinder->type = tramp_frame->frame_type;
d2259dd3
AC
166 unwinder->unwind_data = data;
167 unwinder->sniffer = tramp_frame_sniffer;
4a2fbb50 168 unwinder->stop_reason = default_frame_unwind_stop_reason;
d2259dd3
AC
169 unwinder->this_id = tramp_frame_this_id;
170 unwinder->prev_register = tramp_frame_prev_register;
fb2be677 171 frame_unwind_prepend_unwinder (gdbarch, unwinder);
d2259dd3 172}