]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tramp-frame.c
PR31692, objdump fails .debug_info size check
[thirdparty/binutils-gdb.git] / gdb / tramp-frame.c
CommitLineData
d2259dd3
AC
1/* Signal trampoline unwinder, for GDB the GNU Debugger.
2
1d506c26 3 Copyright (C) 2004-2024 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 19
d2259dd3 20#include "tramp-frame.h"
ec452525 21#include "extract-store-integer.h"
d2259dd3
AC
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 *
8480a37e 43tramp_frame_cache (const frame_info_ptr &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
8480a37e 61tramp_frame_this_id (const frame_info_ptr &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 71static struct value *
8480a37e 72tramp_frame_prev_register (const frame_info_ptr &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,
8480a37e 84 const frame_info_ptr &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;
bdec2917 105 size_t insn_size = tramp->insn_size;
5d502164 106
2cd8546d 107 if (tramp->insn[i].bytes == TRAMP_SENTINEL_INSN)
d2259dd3 108 return func;
25492ce3 109 if (!safe_frame_unwind_memory (this_frame,
bdec2917
LM
110 func + i * insn_size,
111 {buf, insn_size}))
d2259dd3 112 break;
bdec2917 113 insn = extract_unsigned_integer (buf, insn_size, byte_order);
2cd8546d 114 if (tramp->insn[i].bytes != (insn & tramp->insn[i].mask))
d2259dd3
AC
115 break;
116 }
117 }
118 /* Trampoline doesn't match. */
119 return 0;
120}
121
122static int
123tramp_frame_sniffer (const struct frame_unwind *self,
8480a37e 124 const frame_info_ptr &this_frame,
d2259dd3
AC
125 void **this_cache)
126{
127 const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
25492ce3 128 CORE_ADDR pc = get_frame_pc (this_frame);
d2259dd3 129 CORE_ADDR func;
d2259dd3
AC
130 struct tramp_frame_cache *tramp_cache;
131
0efcf9dc
RC
132 /* tausq/2004-12-12: We used to assume if pc has a name or is in a valid
133 section, then this is not a trampoline. However, this assumption is
134 false on HPUX which has a signal trampoline that has a name; it can
135 also be false when using an alternative signal stack. */
25492ce3 136 func = tramp_frame_start (tramp, this_frame, pc);
d2259dd3
AC
137 if (func == 0)
138 return 0;
139 tramp_cache = FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache);
140 tramp_cache->func = func;
141 tramp_cache->tramp_frame = tramp;
142 (*this_cache) = tramp_cache;
143 return 1;
144}
145
146void
fb2be677
AC
147tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
148 const struct tramp_frame *tramp_frame)
d2259dd3
AC
149{
150 struct frame_data *data;
151 struct frame_unwind *unwinder;
1196bfda
AC
152 int i;
153
154 /* Check that the instruction sequence contains a sentinel. */
155 for (i = 0; i < ARRAY_SIZE (tramp_frame->insn); i++)
156 {
2cd8546d 157 if (tramp_frame->insn[i].bytes == TRAMP_SENTINEL_INSN)
1196bfda
AC
158 break;
159 }
160 gdb_assert (i < ARRAY_SIZE (tramp_frame->insn));
2cd8546d 161 gdb_assert (tramp_frame->insn_size <= sizeof (tramp_frame->insn[0].bytes));
d2259dd3
AC
162
163 data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
164 unwinder = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
165
166 data->tramp_frame = tramp_frame;
1f586765 167 unwinder->type = tramp_frame->frame_type;
d2259dd3
AC
168 unwinder->unwind_data = data;
169 unwinder->sniffer = tramp_frame_sniffer;
4a2fbb50 170 unwinder->stop_reason = default_frame_unwind_stop_reason;
d2259dd3
AC
171 unwinder->this_id = tramp_frame_this_id;
172 unwinder->prev_register = tramp_frame_prev_register;
5add3fce 173 unwinder->prev_arch = tramp_frame->prev_arch;
fb2be677 174 frame_unwind_prepend_unwinder (gdbarch, unwinder);
d2259dd3 175}