1 /* Signal trampoline unwinder, for GDB the GNU Debugger.
3 Copyright (C) 2004-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "tramp-frame.h"
21 #include "extract-store-integer.h"
22 #include "frame-unwind.h"
27 #include "trad-frame.h"
28 #include "frame-base.h"
32 const struct tramp_frame
*tramp_frame
;
35 struct tramp_frame_cache
38 const struct tramp_frame
*tramp_frame
;
39 struct trad_frame_cache
*trad_cache
;
42 static struct trad_frame_cache
*
43 tramp_frame_cache (const frame_info_ptr
&this_frame
,
46 struct tramp_frame_cache
*tramp_cache
47 = (struct tramp_frame_cache
*) *this_cache
;
49 if (tramp_cache
->trad_cache
== NULL
)
51 tramp_cache
->trad_cache
= trad_frame_cache_zalloc (this_frame
);
52 tramp_cache
->tramp_frame
->init (tramp_cache
->tramp_frame
,
54 tramp_cache
->trad_cache
,
57 return tramp_cache
->trad_cache
;
60 class frame_unwind_trampoline
: public frame_unwind
63 frame_unwind_trampoline (enum frame_type type
, const struct frame_data
*data
,
64 frame_prev_arch_ftype
*prev_arch_func
)
65 : frame_unwind ("trampoline", type
, FRAME_UNWIND_GDB
, data
),
66 m_prev_arch (prev_arch_func
)
69 int sniff (const frame_info_ptr
&this_frame
,
70 void **this_prologue_cache
) const override
;
72 void this_id (const frame_info_ptr
&this_frame
, void **this_prologue_cache
,
73 struct frame_id
*id
) const override
;
75 value
*prev_register (const frame_info_ptr
&this_frame
,
76 void **this_prologue_cache
,
77 int regnum
) const override
;
79 struct gdbarch
*prev_arch (const frame_info_ptr
&this_frame
,
80 void **this_prologue_cache
) const override
82 if (m_prev_arch
== nullptr)
83 return frame_unwind::prev_arch (this_frame
, this_prologue_cache
);
84 return m_prev_arch (this_frame
, this_prologue_cache
);
88 frame_prev_arch_ftype
*m_prev_arch
;
92 frame_unwind_trampoline::this_id (const frame_info_ptr
&this_frame
,
94 struct frame_id
*this_id
) const
96 struct trad_frame_cache
*trad_cache
97 = tramp_frame_cache (this_frame
, this_cache
);
99 trad_frame_get_id (trad_cache
, this_id
);
103 frame_unwind_trampoline::prev_register (const frame_info_ptr
&this_frame
,
105 int prev_regnum
) const
107 struct trad_frame_cache
*trad_cache
108 = tramp_frame_cache (this_frame
, this_cache
);
110 return trad_frame_get_register (trad_cache
, this_frame
, prev_regnum
);
114 tramp_frame_start (const struct tramp_frame
*tramp
,
115 const frame_info_ptr
&this_frame
, CORE_ADDR pc
)
117 struct gdbarch
*gdbarch
= get_frame_arch (this_frame
);
118 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
121 /* Check if we can use this trampoline. */
122 if (tramp
->validate
&& !tramp
->validate (tramp
, this_frame
, &pc
))
125 /* Search through the trampoline for one that matches the
126 instruction sequence around PC. */
127 for (ti
= 0; tramp
->insn
[ti
].bytes
!= TRAMP_SENTINEL_INSN
; ti
++)
129 CORE_ADDR func
= pc
- tramp
->insn_size
* ti
;
134 gdb_byte buf
[sizeof (tramp
->insn
[0])];
136 size_t insn_size
= tramp
->insn_size
;
138 if (tramp
->insn
[i
].bytes
== TRAMP_SENTINEL_INSN
)
140 if (!safe_frame_unwind_memory (this_frame
,
141 func
+ i
* insn_size
,
144 insn
= extract_unsigned_integer (buf
, insn_size
, byte_order
);
145 if (tramp
->insn
[i
].bytes
!= (insn
& tramp
->insn
[i
].mask
))
149 /* Trampoline doesn't match. */
154 frame_unwind_trampoline::sniff (const frame_info_ptr
&this_frame
,
155 void **this_cache
) const
157 const struct tramp_frame
*tramp
= unwind_data ()->tramp_frame
;
158 CORE_ADDR pc
= get_frame_pc (this_frame
);
160 struct tramp_frame_cache
*tramp_cache
;
162 /* tausq/2004-12-12: We used to assume if pc has a name or is in a valid
163 section, then this is not a trampoline. However, this assumption is
164 false on HPUX which has a signal trampoline that has a name; it can
165 also be false when using an alternative signal stack. */
166 func
= tramp_frame_start (tramp
, this_frame
, pc
);
169 tramp_cache
= FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache
);
170 tramp_cache
->func
= func
;
171 tramp_cache
->tramp_frame
= tramp
;
172 (*this_cache
) = tramp_cache
;
177 tramp_frame_prepend_unwinder (struct gdbarch
*gdbarch
,
178 const struct tramp_frame
*tramp_frame
)
180 struct frame_data
*data
;
181 struct frame_unwind
*unwinder
;
184 /* Check that the instruction sequence contains a sentinel. */
185 for (i
= 0; i
< ARRAY_SIZE (tramp_frame
->insn
); i
++)
187 if (tramp_frame
->insn
[i
].bytes
== TRAMP_SENTINEL_INSN
)
190 gdb_assert (i
< ARRAY_SIZE (tramp_frame
->insn
));
191 gdb_assert (tramp_frame
->insn_size
<= sizeof (tramp_frame
->insn
[0].bytes
));
193 data
= GDBARCH_OBSTACK_ZALLOC (gdbarch
, struct frame_data
);
194 data
->tramp_frame
= tramp_frame
;
196 unwinder
= obstack_new
<frame_unwind_trampoline
> (gdbarch_obstack (gdbarch
),
197 tramp_frame
->frame_type
,
199 tramp_frame
->prev_arch
);
200 frame_unwind_prepend_unwinder (gdbarch
, unwinder
);