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