Compare commits

...

4 Commits

Author SHA1 Message Date
Guinevere Larsen
d2b4f49047 gdb: Migrate frame unwinders to use C++ classes
Frame unwinders have historically been a structure populated with
callback pointers, so that architectures (or other specific unwinders)
could install their own way to handle the inferior. However, since
moving to c++, we could use polymorphism to get the same functionality
in a more readable way. Polymorphism also makes it simpler to add new
functionality to all frame unwinders, since all that's required is
adding it to the base class.

As part of the changes to add support to disabling frame unwinders,
this commit makes the first baby step in  using polymorphism for the
frame unwinders, by making frame_unwind a virtual class, and adds 3 new
classes. The main class added is frame_unwind_legacy, which works the
same as the previous structs, using function pointers as callbacks. This
class was added to allow the transition to happen piecemeal. New
unwinders should instead follow the lead of the other 2 classes
implemented.

The other 2, frame_unwind_python and frame_unwind_trampoline, were added
because it seemed simpler at the moment to do that instead of reworking
the dynamic allocation to work with the legacy class, and can be used as
an example to future implementations.
2024-02-21 15:38:24 +01:00
Guinevere Larsen
c5497c10ba gdb: add "unwinder class" to frame unwinders
A future patch will add a way to disable certain unwinders based on
different characteristics. This patch aims to make it more convenient
to disable related unwinders in bulk, such as architecture specific
ones, by indentifying all unwinders by which part of the code adds it.
The classes, and explanations, are as follows:

* GDB: An internal unwinder, added by GDB core, such as the unwinder
  for dummy frames;
* EXTENSION: Unwinders added by extension languages;
* DEBUGINFO: Unwinders installed by the debug info reader;
* ARCH: Unwinders installed by the architecture specific code.
2024-02-21 15:38:23 +01:00
Fedora GDB patches
fb054b5e08 gdb/testsuite: Test for a backtrace through object without debuginfo
Fedora has been carrying this test since back in the Project Archer
days. A change back then caused GDB to stop being able to backtrace when
only some of the object files had debug information. Even though the
changed code never seems to have made its way into the main GDB project,
I think it makes sense to bring the test along to ensure something like
this doesn't pass unnoticed.
2024-02-14 15:38:26 +01:00
Guinevere Larsen
e961aad01f gdb: make gdbarch store a vector of frame unwinders
Before this commit, all frame unwinders would be stored in the obstack
of a gdbarch and accessed by using the registry system. This made for
unwieldy code, and unnecessarily complex logic in the frame_unwinder
implementation, along with making frame_unwind structs be unable to have
non-trivial constructors.

Seeing as a future patch of this series wants to refactor the
frame_unwind struct to use inheritance, obstack storage would no longer
be viable. In preparation for that change, this commit adds an
std::vector to gdbarch to store the unwinders in.

There should be no user-visible changes.
2024-02-14 15:38:26 +01:00
93 changed files with 891 additions and 420 deletions

View File

@@ -1204,16 +1204,16 @@ aarch64_prologue_prev_register (frame_info_ptr this_frame,
} }
/* AArch64 prologue unwinder. */ /* AArch64 prologue unwinder. */
static frame_unwind aarch64_prologue_unwind = static frame_unwind_legacy aarch64_prologue_unwind (
{
"aarch64 prologue", "aarch64 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
aarch64_prologue_frame_unwind_stop_reason, aarch64_prologue_frame_unwind_stop_reason,
aarch64_prologue_this_id, aarch64_prologue_this_id,
aarch64_prologue_prev_register, aarch64_prologue_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Allocate and fill in *THIS_CACHE with information about the prologue of /* Allocate and fill in *THIS_CACHE with information about the prologue of
*THIS_FRAME. Do not do this is if *THIS_CACHE was already allocated. *THIS_FRAME. Do not do this is if *THIS_CACHE was already allocated.
@@ -1299,16 +1299,16 @@ aarch64_stub_unwind_sniffer (const struct frame_unwind *self,
} }
/* AArch64 stub unwinder. */ /* AArch64 stub unwinder. */
static frame_unwind aarch64_stub_unwind = static frame_unwind_legacy aarch64_stub_unwind (
{
"aarch64 stub", "aarch64 stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
aarch64_stub_frame_unwind_stop_reason, aarch64_stub_frame_unwind_stop_reason,
aarch64_stub_this_id, aarch64_stub_this_id,
aarch64_prologue_prev_register, aarch64_prologue_prev_register,
NULL, NULL,
aarch64_stub_unwind_sniffer aarch64_stub_unwind_sniffer
}; );
/* Return the frame base address of *THIS_FRAME. */ /* Return the frame base address of *THIS_FRAME. */

View File

@@ -331,16 +331,16 @@ alpha_mdebug_frame_sniffer (const struct frame_unwind *self,
return 1; return 1;
} }
static const struct frame_unwind alpha_mdebug_frame_unwind = static const struct frame_unwind_legacy alpha_mdebug_frame_unwind (
{
"alpha mdebug", "alpha mdebug",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
alpha_mdebug_frame_this_id, alpha_mdebug_frame_this_id,
alpha_mdebug_frame_prev_register, alpha_mdebug_frame_prev_register,
NULL, NULL,
alpha_mdebug_frame_sniffer alpha_mdebug_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
alpha_mdebug_frame_base_address (frame_info_ptr this_frame, alpha_mdebug_frame_base_address (frame_info_ptr this_frame,

View File

@@ -1007,16 +1007,16 @@ alpha_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind alpha_sigtramp_frame_unwind = static const struct frame_unwind_legacy alpha_sigtramp_frame_unwind (
{
"alpha sigtramp", "alpha sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
alpha_sigtramp_frame_this_id, alpha_sigtramp_frame_this_id,
alpha_sigtramp_frame_prev_register, alpha_sigtramp_frame_prev_register,
NULL, NULL,
alpha_sigtramp_frame_sniffer alpha_sigtramp_frame_sniffer
}; );
@@ -1426,16 +1426,16 @@ alpha_heuristic_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
} }
static const struct frame_unwind alpha_heuristic_frame_unwind = static const struct frame_unwind_legacy alpha_heuristic_frame_unwind (
{
"alpha prologue", "alpha prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
alpha_heuristic_frame_this_id, alpha_heuristic_frame_this_id,
alpha_heuristic_frame_prev_register, alpha_heuristic_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
alpha_heuristic_frame_base_address (frame_info_ptr this_frame, alpha_heuristic_frame_base_address (frame_info_ptr this_frame,

View File

@@ -402,19 +402,19 @@ amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
|| (startswith (name, "Xintr")))); || (startswith (name, "Xintr"))));
} }
static const struct frame_unwind amd64obsd_trapframe_unwind = static const struct frame_unwind_legacy amd64obsd_trapframe_unwind (
{
/* FIXME: kettenis/20051219: This really is more like an interrupt /* FIXME: kettenis/20051219: This really is more like an interrupt
frame, but SIGTRAMP_FRAME would print <signal handler called>, frame, but SIGTRAMP_FRAME would print <signal handler called>,
which really is not what we want here. */ which really is not what we want here. */
"amd64 openbsd trap", "amd64 openbsd trap",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
amd64obsd_trapframe_this_id, amd64obsd_trapframe_this_id,
amd64obsd_trapframe_prev_register, amd64obsd_trapframe_prev_register,
NULL, NULL,
amd64obsd_trapframe_sniffer amd64obsd_trapframe_sniffer
}; );
static void static void

View File

@@ -2658,16 +2658,16 @@ amd64_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind amd64_frame_unwind = static const struct frame_unwind_legacy amd64_frame_unwind (
{
"amd64 prologue", "amd64 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
amd64_frame_unwind_stop_reason, amd64_frame_unwind_stop_reason,
amd64_frame_this_id, amd64_frame_this_id,
amd64_frame_prev_register, amd64_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Generate a bytecode expression to get the value of the saved PC. */ /* Generate a bytecode expression to get the value of the saved PC. */
@@ -2804,16 +2804,16 @@ amd64_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind amd64_sigtramp_frame_unwind = static const struct frame_unwind_legacy amd64_sigtramp_frame_unwind (
{
"amd64 sigtramp", "amd64 sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
amd64_sigtramp_frame_unwind_stop_reason, amd64_sigtramp_frame_unwind_stop_reason,
amd64_sigtramp_frame_this_id, amd64_sigtramp_frame_this_id,
amd64_sigtramp_frame_prev_register, amd64_sigtramp_frame_prev_register,
NULL, NULL,
amd64_sigtramp_frame_sniffer amd64_sigtramp_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
@@ -2996,27 +2996,27 @@ amd64_epilogue_frame_this_id (frame_info_ptr this_frame,
(*this_id) = frame_id_build (cache->base + 16, cache->pc); (*this_id) = frame_id_build (cache->base + 16, cache->pc);
} }
static const struct frame_unwind amd64_epilogue_override_frame_unwind = static const struct frame_unwind_legacy amd64_epilogue_override_frame_unwind (
{
"amd64 epilogue override", "amd64 epilogue override",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
amd64_epilogue_frame_unwind_stop_reason, amd64_epilogue_frame_unwind_stop_reason,
amd64_epilogue_frame_this_id, amd64_epilogue_frame_this_id,
amd64_frame_prev_register, amd64_frame_prev_register,
NULL, NULL,
amd64_epilogue_override_frame_sniffer amd64_epilogue_override_frame_sniffer
}; );
static const struct frame_unwind amd64_epilogue_frame_unwind = static const struct frame_unwind_legacy amd64_epilogue_frame_unwind (
{
"amd64 epilogue", "amd64 epilogue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
amd64_epilogue_frame_unwind_stop_reason, amd64_epilogue_frame_unwind_stop_reason,
amd64_epilogue_frame_this_id, amd64_epilogue_frame_this_id,
amd64_frame_prev_register, amd64_frame_prev_register,
NULL, NULL,
amd64_epilogue_frame_sniffer amd64_epilogue_frame_sniffer
}; );
static struct frame_id static struct frame_id
amd64_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame) amd64_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)

View File

@@ -1181,16 +1181,16 @@ amd64_windows_frame_this_id (frame_info_ptr this_frame, void **this_cache,
/* Windows x64 SEH unwinder. */ /* Windows x64 SEH unwinder. */
static const struct frame_unwind amd64_windows_frame_unwind = static const struct frame_unwind_legacy amd64_windows_frame_unwind (
{
"amd64 windows", "amd64 windows",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
&amd64_windows_frame_this_id, &amd64_windows_frame_this_id,
&amd64_windows_frame_prev_register, &amd64_windows_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Implement the "skip_prologue" gdbarch method. */ /* Implement the "skip_prologue" gdbarch method. */

View File

@@ -892,9 +892,10 @@ amdgpu_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const frame_unwind amdgpu_frame_unwind = { static const frame_unwind_legacy amdgpu_frame_unwind (
"amdgpu", "amdgpu",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
amdgpu_frame_this_id, amdgpu_frame_this_id,
amdgpu_frame_prev_register, amdgpu_frame_prev_register,
@@ -902,7 +903,7 @@ static const frame_unwind amdgpu_frame_unwind = {
default_frame_sniffer, default_frame_sniffer,
nullptr, nullptr,
nullptr, nullptr,
}; );
static int static int
print_insn_amdgpu (bfd_vma memaddr, struct disassemble_info *info) print_insn_amdgpu (bfd_vma memaddr, struct disassemble_info *info)

View File

@@ -1900,9 +1900,10 @@ arc_sigtramp_frame_sniffer (const struct frame_unwind *self,
the fallback unwinder, we use the default frame sniffer, which always the fallback unwinder, we use the default frame sniffer, which always
accepts the frame. */ accepts the frame. */
static const struct frame_unwind arc_frame_unwind = { static const struct frame_unwind_legacy arc_frame_unwind (
"arc prologue", "arc prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
arc_frame_this_id, arc_frame_this_id,
arc_frame_prev_register, arc_frame_prev_register,
@@ -1910,15 +1911,16 @@ static const struct frame_unwind arc_frame_unwind = {
default_frame_sniffer, default_frame_sniffer,
NULL, NULL,
NULL NULL
}; );
/* Structure defining the ARC signal frame unwind functions. Custom /* Structure defining the ARC signal frame unwind functions. Custom
sniffer is used, because this frame must be accepted only in the right sniffer is used, because this frame must be accepted only in the right
context. */ context. */
static const struct frame_unwind arc_sigtramp_frame_unwind = { static const struct frame_unwind_legacy arc_sigtramp_frame_unwind (
"arc sigtramp", "arc sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
arc_sigtramp_frame_this_id, arc_sigtramp_frame_this_id,
arc_sigtramp_frame_prev_register, arc_sigtramp_frame_prev_register,
@@ -1926,7 +1928,7 @@ static const struct frame_unwind arc_sigtramp_frame_unwind = {
arc_sigtramp_frame_sniffer, arc_sigtramp_frame_sniffer,
NULL, NULL,
NULL NULL
}; );
static const struct frame_base arc_normal_base = { static const struct frame_base arc_normal_base = {

View File

@@ -1218,6 +1218,14 @@ obstack *gdbarch_obstack (gdbarch *arch)
/* See gdbarch.h. */ /* See gdbarch.h. */
std::vector<const frame_unwind*>&
gdbarch_get_unwinder_list (struct gdbarch *arch)
{
return arch->unwinders;
}
/* See gdbarch.h. */
char * char *
gdbarch_obstack_strdup (struct gdbarch *arch, const char *string) gdbarch_obstack_strdup (struct gdbarch *arch, const char *string)
{ {

View File

@@ -2469,9 +2469,10 @@ arm_prologue_prev_register (frame_info_ptr this_frame,
prev_regnum); prev_regnum);
} }
static frame_unwind arm_prologue_unwind = { static frame_unwind_legacy arm_prologue_unwind = {
"arm prologue", "arm prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
arm_prologue_unwind_stop_reason, arm_prologue_unwind_stop_reason,
arm_prologue_this_id, arm_prologue_this_id,
arm_prologue_prev_register, arm_prologue_prev_register,
@@ -3188,9 +3189,10 @@ arm_exidx_unwind_sniffer (const struct frame_unwind *self,
return 1; return 1;
} }
struct frame_unwind arm_exidx_unwind = { struct frame_unwind_legacy arm_exidx_unwind = {
"arm exidx", "arm exidx",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
arm_prologue_this_id, arm_prologue_this_id,
arm_prologue_prev_register, arm_prologue_prev_register,
@@ -3297,16 +3299,16 @@ arm_epilogue_frame_sniffer (const struct frame_unwind *self,
/* Frame unwinder from epilogue. */ /* Frame unwinder from epilogue. */
static const struct frame_unwind arm_epilogue_frame_unwind = static const struct frame_unwind_legacy arm_epilogue_frame_unwind (
{
"arm epilogue", "arm epilogue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
arm_epilogue_frame_this_id, arm_epilogue_frame_this_id,
arm_epilogue_frame_prev_register, arm_epilogue_frame_prev_register,
NULL, NULL,
arm_epilogue_frame_sniffer, arm_epilogue_frame_sniffer
}; );
/* Recognize GCC's trampoline for thumb call-indirect. If we are in a /* Recognize GCC's trampoline for thumb call-indirect. If we are in a
trampoline, return the target PC. Otherwise return 0. trampoline, return the target PC. Otherwise return 0.
@@ -3427,15 +3429,16 @@ arm_stub_unwind_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
struct frame_unwind arm_stub_unwind = { struct frame_unwind_legacy arm_stub_unwind (
"arm stub", "arm stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
arm_stub_this_id, arm_stub_this_id,
arm_prologue_prev_register, arm_prologue_prev_register,
NULL, NULL,
arm_stub_unwind_sniffer arm_stub_unwind_sniffer
}; );
/* Put here the code to store, into CACHE->saved_regs, the addresses /* Put here the code to store, into CACHE->saved_regs, the addresses
of the saved registers of frame described by THIS_FRAME. CACHE is of the saved registers of frame described by THIS_FRAME. CACHE is
@@ -3952,16 +3955,16 @@ arm_m_exception_unwind_sniffer (const struct frame_unwind *self,
/* Frame unwinder for M-profile exceptions (EXC_RETURN on stack), /* Frame unwinder for M-profile exceptions (EXC_RETURN on stack),
lockup and secure/nonsecure interstate function calls (FNC_RETURN). */ lockup and secure/nonsecure interstate function calls (FNC_RETURN). */
struct frame_unwind arm_m_exception_unwind = struct frame_unwind_legacy arm_m_exception_unwind (
{
"arm m exception lockup sec_fnc", "arm m exception lockup sec_fnc",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
arm_m_exception_frame_unwind_stop_reason, arm_m_exception_frame_unwind_stop_reason,
arm_m_exception_this_id, arm_m_exception_this_id,
arm_m_exception_prev_register, arm_m_exception_prev_register,
NULL, NULL,
arm_m_exception_unwind_sniffer arm_m_exception_unwind_sniffer
}; );
static CORE_ADDR static CORE_ADDR
arm_normal_frame_base (frame_info_ptr this_frame, void **this_cache) arm_normal_frame_base (frame_info_ptr this_frame, void **this_cache)

View File

@@ -1155,15 +1155,16 @@ avr_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
} }
static const struct frame_unwind avr_frame_unwind = { static const struct frame_unwind_legacy avr_frame_unwind (
"avr prologue", "avr prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
avr_frame_this_id, avr_frame_this_id,
avr_frame_prev_register, avr_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
avr_frame_base_address (frame_info_ptr this_frame, void **this_cache) avr_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -372,16 +372,16 @@ bfin_frame_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind bfin_frame_unwind = static const struct frame_unwind_legacy bfin_frame_unwind (
{
"bfin prologue", "bfin prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
bfin_frame_this_id, bfin_frame_this_id,
bfin_frame_prev_register, bfin_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Check for "[--SP] = <reg>;" insns. These are appear in function /* Check for "[--SP] = <reg>;" insns. These are appear in function
prologues to save misc registers onto the stack. */ prologues to save misc registers onto the stack. */

View File

@@ -182,16 +182,16 @@ bpf_frame_prev_register (frame_info_ptr this_frame,
/* Frame unwinder machinery for BPF. */ /* Frame unwinder machinery for BPF. */
static const struct frame_unwind bpf_frame_unwind = static const struct frame_unwind_legacy bpf_frame_unwind (
{
"bpf prologue", "bpf prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
bpf_frame_unwind_stop_reason, bpf_frame_unwind_stop_reason,
bpf_frame_this_id, bpf_frame_this_id,
bpf_frame_prev_register, bpf_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Breakpoints. */ /* Breakpoints. */

View File

@@ -435,16 +435,16 @@ cris_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind cris_sigtramp_frame_unwind = static const struct frame_unwind_legacy cris_sigtramp_frame_unwind (
{
"cris sigtramp", "cris sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
cris_sigtramp_frame_this_id, cris_sigtramp_frame_this_id,
cris_sigtramp_frame_prev_register, cris_sigtramp_frame_prev_register,
NULL, NULL,
cris_sigtramp_frame_sniffer cris_sigtramp_frame_sniffer
}; );
static int static int
crisv32_single_step_through_delay (struct gdbarch *gdbarch, crisv32_single_step_through_delay (struct gdbarch *gdbarch,
@@ -900,16 +900,16 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
return sp; return sp;
} }
static const struct frame_unwind cris_frame_unwind = static const struct frame_unwind_legacy cris_frame_unwind (
{
"cris prologue", "cris prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
cris_frame_this_id, cris_frame_this_id,
cris_frame_prev_register, cris_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
cris_frame_base_address (frame_info_ptr this_frame, void **this_cache) cris_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -2159,9 +2159,10 @@ csky_frame_prev_register (frame_info_ptr this_frame,
/* Data structures for the normal prologue-analysis-based /* Data structures for the normal prologue-analysis-based
unwinder. */ unwinder. */
static const struct frame_unwind csky_unwind_cache = { static const struct frame_unwind_legacy csky_unwind_cache (
"cski prologue", "cski prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
csky_frame_this_id, csky_frame_this_id,
csky_frame_prev_register, csky_frame_prev_register,
@@ -2169,7 +2170,7 @@ static const struct frame_unwind csky_unwind_cache = {
default_frame_sniffer, default_frame_sniffer,
NULL, NULL,
NULL NULL
}; );
static CORE_ADDR static CORE_ADDR
csky_check_long_branch (frame_info_ptr frame, CORE_ADDR pc) csky_check_long_branch (frame_info_ptr frame, CORE_ADDR pc)
@@ -2293,15 +2294,16 @@ csky_stub_prev_register (frame_info_ptr this_frame,
prev_regnum); prev_regnum);
} }
static frame_unwind csky_stub_unwind = { static frame_unwind_legacy csky_stub_unwind (
"csky stub", "csky stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
csky_stub_this_id, csky_stub_this_id,
csky_stub_prev_register, csky_stub_prev_register,
NULL, NULL,
csky_stub_unwind_sniffer csky_stub_unwind_sniffer
}; );
/* Implement the this_base, this_locals, and this_args hooks /* Implement the this_base, this_locals, and this_args hooks
for the normal unwinder. */ for the normal unwinder. */

View File

@@ -376,16 +376,16 @@ dummy_frame_this_id (frame_info_ptr this_frame,
(*this_id) = cache->this_id; (*this_id) = cache->this_id;
} }
const struct frame_unwind dummy_frame_unwind = const struct frame_unwind_legacy dummy_frame_unwind (
{
"dummy", "dummy",
DUMMY_FRAME, DUMMY_FRAME,
FRAME_UNWIND_GDB,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
dummy_frame_this_id, dummy_frame_this_id,
dummy_frame_prev_register, dummy_frame_prev_register,
NULL, NULL,
dummy_frame_sniffer, dummy_frame_sniffer
}; );
/* See dummy-frame.h. */ /* See dummy-frame.h. */

View File

@@ -54,7 +54,7 @@ extern void dummy_frame_discard (frame_id dummy_id, thread_info *thread);
/* If the PC falls in a dummy frame, return a dummy frame /* If the PC falls in a dummy frame, return a dummy frame
unwinder. */ unwinder. */
extern const struct frame_unwind dummy_frame_unwind; extern const struct frame_unwind_legacy dummy_frame_unwind;
/* Destructor for dummy_frame. DATA is supplied by registrant. /* Destructor for dummy_frame. DATA is supplied by registrant.
REGISTERS_VALID is 1 for dummy_frame_pop, 0 for dummy_frame_discard. */ REGISTERS_VALID is 1 for dummy_frame_pop, 0 for dummy_frame_discard. */

View File

@@ -469,10 +469,10 @@ tailcall_frame_prev_arch (frame_info_ptr this_frame,
/* Virtual tail call frame unwinder if dwarf2_tailcall_sniffer_first finds /* Virtual tail call frame unwinder if dwarf2_tailcall_sniffer_first finds
a chain to create. */ a chain to create. */
const struct frame_unwind dwarf2_tailcall_frame_unwind = const struct frame_unwind_legacy dwarf2_tailcall_frame_unwind (
{
"dwarf2 tailcall", "dwarf2 tailcall",
TAILCALL_FRAME, TAILCALL_FRAME,
FRAME_UNWIND_DEBUGINFO,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
tailcall_frame_this_id, tailcall_frame_this_id,
tailcall_frame_prev_register, tailcall_frame_prev_register,
@@ -480,7 +480,7 @@ const struct frame_unwind dwarf2_tailcall_frame_unwind =
tailcall_frame_sniffer, tailcall_frame_sniffer,
tailcall_frame_dealloc_cache, tailcall_frame_dealloc_cache,
tailcall_frame_prev_arch tailcall_frame_prev_arch
}; );
void _initialize_tailcall_frame (); void _initialize_tailcall_frame ();
void void

View File

@@ -34,6 +34,6 @@ extern struct value *
dwarf2_tailcall_prev_register_first (frame_info_ptr this_frame, dwarf2_tailcall_prev_register_first (frame_info_ptr this_frame,
void **tailcall_cachep, int regnum); void **tailcall_cachep, int regnum);
extern const struct frame_unwind dwarf2_tailcall_frame_unwind; extern const struct frame_unwind_legacy dwarf2_tailcall_frame_unwind;
#endif /* !DWARF2_FRAME_TAILCALL_H */ #endif /* !DWARF2_FRAME_TAILCALL_H */

View File

@@ -1332,30 +1332,30 @@ dwarf2_frame_sniffer (const struct frame_unwind *self,
if (fde->cie->signal_frame if (fde->cie->signal_frame
|| dwarf2_frame_signal_frame_p (get_frame_arch (this_frame), || dwarf2_frame_signal_frame_p (get_frame_arch (this_frame),
this_frame)) this_frame))
return self->type == SIGTRAMP_FRAME; return self->type () == SIGTRAMP_FRAME;
if (self->type != NORMAL_FRAME) if (self->type () != NORMAL_FRAME)
return 0; return 0;
return 1; return 1;
} }
static const struct frame_unwind dwarf2_frame_unwind = static const struct frame_unwind_legacy dwarf2_frame_unwind (
{
"dwarf2", "dwarf2",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_DEBUGINFO,
dwarf2_frame_unwind_stop_reason, dwarf2_frame_unwind_stop_reason,
dwarf2_frame_this_id, dwarf2_frame_this_id,
dwarf2_frame_prev_register, dwarf2_frame_prev_register,
NULL, NULL,
dwarf2_frame_sniffer, dwarf2_frame_sniffer,
dwarf2_frame_dealloc_cache dwarf2_frame_dealloc_cache
}; );
static const struct frame_unwind dwarf2_signal_frame_unwind = static const struct frame_unwind_legacy dwarf2_signal_frame_unwind (
{
"dwarf2 signal", "dwarf2 signal",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_DEBUGINFO,
dwarf2_frame_unwind_stop_reason, dwarf2_frame_unwind_stop_reason,
dwarf2_frame_this_id, dwarf2_frame_this_id,
dwarf2_frame_prev_register, dwarf2_frame_prev_register,
@@ -1364,7 +1364,7 @@ static const struct frame_unwind dwarf2_signal_frame_unwind =
/* TAILCALL_CACHE can never be in such frame to need dealloc_cache. */ /* TAILCALL_CACHE can never be in such frame to need dealloc_cache. */
NULL NULL
}; );
/* Append the DWARF-2 frame unwinders to GDBARCH's list. */ /* Append the DWARF-2 frame unwinders to GDBARCH's list. */

View File

@@ -31,49 +31,16 @@
#include "cli/cli-cmds.h" #include "cli/cli-cmds.h"
#include "inferior.h" #include "inferior.h"
struct frame_unwind_table_entry /* If an unwinder should be prepended to the list, this is the
index in which it should be inserted. */
static int osabi_start = -1;
/* Start the table out with a few default sniffers. OSABI code
can't override this. */
static void
initialize_frame_unwind_table (std::vector<const frame_unwind*>& table)
{ {
const struct frame_unwind *unwinder; table.push_back (&dummy_frame_unwind);
struct frame_unwind_table_entry *next;
};
struct frame_unwind_table
{
struct frame_unwind_table_entry *list = nullptr;
/* The head of the OSABI part of the search list. */
struct frame_unwind_table_entry **osabi_head = nullptr;
};
static const registry<gdbarch>::key<struct frame_unwind_table>
frame_unwind_data;
/* A helper function to add an unwinder to a list. LINK says where to
install the new unwinder. The new link is returned. */
static struct frame_unwind_table_entry **
add_unwinder (struct obstack *obstack, const struct frame_unwind *unwinder,
struct frame_unwind_table_entry **link)
{
*link = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
(*link)->unwinder = unwinder;
return &(*link)->next;
}
static struct frame_unwind_table *
get_frame_unwind_table (struct gdbarch *gdbarch)
{
struct frame_unwind_table *table = frame_unwind_data.get (gdbarch);
if (table != nullptr)
return table;
table = new frame_unwind_table;
/* Start the table out with a few default sniffers. OSABI code
can't override this. */
struct frame_unwind_table_entry **link = &table->list;
struct obstack *obstack = gdbarch_obstack (gdbarch);
link = add_unwinder (obstack, &dummy_frame_unwind, link);
/* The DWARF tailcall sniffer must come before the inline sniffer. /* The DWARF tailcall sniffer must come before the inline sniffer.
Otherwise, we can end up in a situation where a DWARF frame finds Otherwise, we can end up in a situation where a DWARF frame finds
tailcall information, but then the inline sniffer claims a frame tailcall information, but then the inline sniffer claims a frame
@@ -81,41 +48,71 @@ get_frame_unwind_table (struct gdbarch *gdbarch)
safe to do always because the tailcall sniffer can only ever be safe to do always because the tailcall sniffer can only ever be
activated if the newer frame was created using the DWARF activated if the newer frame was created using the DWARF
unwinder, and it also found tailcall information. */ unwinder, and it also found tailcall information. */
link = add_unwinder (obstack, &dwarf2_tailcall_frame_unwind, link); table.push_back (&dwarf2_tailcall_frame_unwind);
link = add_unwinder (obstack, &inline_frame_unwind, link); table.push_back (&inline_frame_unwind);
/* The insertion point for OSABI sniffers. */ /* The insertion point for OSABI sniffers. */
table->osabi_head = link; osabi_start = table.size ();
frame_unwind_data.set (gdbarch, table); }
/* This function call retrieves the list of frame unwinders available in
GDBARCH. If this list is empty, it is initialized before being
returned. */
static std::vector<const frame_unwind*>&
get_frame_unwind_table (struct gdbarch *gdbarch)
{
std::vector<const frame_unwind*>& table = gdbarch_get_unwinder_list (gdbarch);
if (table.size () == 0)
initialize_frame_unwind_table (table);
return table; return table;
} }
static const char *
frame_unwinder_class_str (frame_unwind_class uclass)
{
switch (uclass)
{
case FRAME_UNWIND_GDB:
return "FRAME_UNWIND_GDB";
case FRAME_UNWIND_EXTENSION:
return "FRAME_UNWIND_EXTENSION";
case FRAME_UNWIND_DEBUGINFO:
return "FRAME_UNWIND_DEBUGINFO";
case FRAME_UNWIND_ARCH:
return "FRAME_UNWIND_ARCH";
default:
return "<unknown class>";
};
}
void void
frame_unwind_prepend_unwinder (struct gdbarch *gdbarch, frame_unwind_prepend_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder) const struct frame_unwind *unwinder)
{ {
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch); std::vector<const frame_unwind*>& table = get_frame_unwind_table (gdbarch);
struct frame_unwind_table_entry *entry;
/* Insert the new entry at the start of the list. */ gdb_assert (osabi_start >= 0);
entry = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
entry->unwinder = unwinder; table.push_back (unwinder);
entry->next = (*table->osabi_head);
(*table->osabi_head) = entry; /* Bubble the new entry up to where new unwinders are allowed to be
inserterd. */
for (int i = table.size() - 1; i > osabi_start; i--)
std::swap(table[i], table[i-1]);
} }
void void
frame_unwind_append_unwinder (struct gdbarch *gdbarch, frame_unwind_append_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder) const struct frame_unwind *unwinder)
{ {
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch); std::vector<const frame_unwind*>& table = get_frame_unwind_table (gdbarch);
struct frame_unwind_table_entry **ip;
/* Find the end of the list and insert the new entry there. */ table.push_back (unwinder);
for (ip = table->osabi_head; (*ip) != NULL; ip = &(*ip)->next);
(*ip) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
(*ip)->unwinder = unwinder;
} }
/* Call SNIFFER from UNWINDER. If it succeeded set UNWINDER for /* Call SNIFFER from UNWINDER. If it succeeded set UNWINDER for
@@ -134,7 +131,7 @@ frame_unwind_try_unwinder (frame_info_ptr this_frame, void **this_cache,
try try
{ {
frame_debug_printf ("trying unwinder \"%s\"", unwinder->name); frame_debug_printf ("trying unwinder \"%s\"", unwinder->name ());
res = unwinder->sniffer (unwinder, this_frame, this_cache); res = unwinder->sniffer (unwinder, this_frame, this_cache);
} }
catch (const gdb_exception &ex) catch (const gdb_exception &ex)
@@ -188,9 +185,6 @@ frame_unwind_find_by_frame (frame_info_ptr this_frame, void **this_cache)
FRAME_SCOPED_DEBUG_ENTER_EXIT; FRAME_SCOPED_DEBUG_ENTER_EXIT;
frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame)); frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame));
struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch);
struct frame_unwind_table_entry *entry;
const struct frame_unwind *unwinder_from_target; const struct frame_unwind *unwinder_from_target;
unwinder_from_target = target_get_unwinder (); unwinder_from_target = target_get_unwinder ();
@@ -205,8 +199,10 @@ frame_unwind_find_by_frame (frame_info_ptr this_frame, void **this_cache)
unwinder_from_target)) unwinder_from_target))
return; return;
for (entry = table->list; entry != NULL; entry = entry->next) struct gdbarch *gdbarch = get_frame_arch (this_frame);
if (frame_unwind_try_unwinder (this_frame, this_cache, entry->unwinder)) std::vector<const frame_unwind*> table = get_frame_unwind_table (gdbarch);
for (auto unwinder: table)
if (frame_unwind_try_unwinder (this_frame, this_cache, unwinder))
return; return;
internal_error (_("frame_unwind_find_by_frame failed")); internal_error (_("frame_unwind_find_by_frame failed"));
@@ -341,29 +337,103 @@ frame_unwind_got_address (frame_info_ptr frame, int regnum,
return reg_val; return reg_val;
} }
/* See frame-unwind.h. */
enum unwind_stop_reason
frame_unwind::stop_reason (frame_info_ptr this_frame,
void **this_prologue_cache) const
{
return default_frame_unwind_stop_reason (this_frame, this_prologue_cache);
}
/* See frame-unwind.h. */
int
frame_unwind::sniffer (const struct frame_unwind *self,
frame_info_ptr this_frame,
void **this_prologue_cache) const
{
return 1;
}
/* This method just passes the parameters to the callback pointer. */
enum unwind_stop_reason
frame_unwind_legacy::stop_reason (frame_info_ptr this_frame,
void **this_prologue_cache) const
{
return stop_reason_p (this_frame, this_prologue_cache);
}
/* This method just passes the parameters to the callback pointer. */
void
frame_unwind_legacy::this_id (frame_info_ptr this_frame,
void **this_prologue_cache,
struct frame_id *id) const
{
return this_id_p (this_frame, this_prologue_cache, id);
}
/* This method just passes the parameters to the callback pointer. */
struct value *
frame_unwind_legacy::prev_register (frame_info_ptr this_frame,
void **this_prologue_cache,
int regnum) const
{
return prev_register_p (this_frame, this_prologue_cache, regnum);
}
/* This method just passes the parameters to the callback pointer. */
int
frame_unwind_legacy::sniffer (const struct frame_unwind *self,
frame_info_ptr this_frame,
void **this_prologue_cache) const
{
return sniffer_p (self, this_frame, this_prologue_cache);
}
/* This method just passes the parameters to the callback pointer. */
void
frame_unwind_legacy::dealloc_cache (frame_info *self, void *this_cache) const
{
if (dealloc_cache_p != nullptr)
dealloc_cache_p (self, this_cache);
}
/* This method just passes the parameters to the callback pointer. */
struct gdbarch *
frame_unwind_legacy::prev_arch (frame_info_ptr this_frame,
void **this_prologue_cache) const
{
if (prev_arch_p == nullptr)
error (_("No prev_arch callback installed"));
return prev_arch_p (this_frame, this_prologue_cache);
}
/* Implement "maintenance info frame-unwinders" command. */ /* Implement "maintenance info frame-unwinders" command. */
static void static void
maintenance_info_frame_unwinders (const char *args, int from_tty) maintenance_info_frame_unwinders (const char *args, int from_tty)
{ {
gdbarch *gdbarch = current_inferior ()->arch (); gdbarch *gdbarch = current_inferior ()->arch ();
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch); std::vector<const frame_unwind*> table = get_frame_unwind_table (gdbarch);
ui_out *uiout = current_uiout; ui_out *uiout = current_uiout;
ui_out_emit_table table_emitter (uiout, 2, -1, "FrameUnwinders"); ui_out_emit_table table_emitter (uiout, 3, -1, "FrameUnwinders");
uiout->table_header (27, ui_left, "name", "Name"); uiout->table_header (27, ui_left, "name", "Name");
uiout->table_header (25, ui_left, "type", "Type"); uiout->table_header (25, ui_left, "type", "Type");
uiout->table_header (25, ui_left, "class", "Class");
uiout->table_body (); uiout->table_body ();
for (struct frame_unwind_table_entry *entry = table->list; entry != NULL; for (const struct frame_unwind* unwinder: table)
entry = entry->next)
{ {
const char *name = entry->unwinder->name; const char *name = unwinder->name ();
const char *type = frame_type_str (entry->unwinder->type); const char *type = frame_type_str (unwinder->type ());
const char *uclass = frame_unwinder_class_str (unwinder->unwinder_class ());
ui_out_emit_list tuple_emitter (uiout, nullptr); ui_out_emit_list tuple_emitter (uiout, nullptr);
uiout->field_string ("name", name); uiout->field_string ("name", name);
uiout->field_string ("type", type); uiout->field_string ("type", type);
uiout->field_string ("class", uclass);
uiout->text ("\n"); uiout->text ("\n");
} }
} }

View File

@@ -156,21 +156,150 @@ typedef void (frame_dealloc_cache_ftype) (frame_info *self,
typedef struct gdbarch *(frame_prev_arch_ftype) (frame_info_ptr this_frame, typedef struct gdbarch *(frame_prev_arch_ftype) (frame_info_ptr this_frame,
void **this_prologue_cache); void **this_prologue_cache);
struct frame_unwind enum frame_unwind_class {
FRAME_UNWIND_GDB,
FRAME_UNWIND_EXTENSION,
FRAME_UNWIND_DEBUGINFO,
FRAME_UNWIND_ARCH,
};
class frame_unwind
{ {
const char *name; private:
const char *m_name;
/* The frame's type. Should this instead be a collection of /* The frame's type. Should this instead be a collection of
predicates that test the frame for various attributes? */ predicates that test the frame for various attributes? */
enum frame_type type; enum frame_type m_type;
/* What kind of unwinder is this. It generally follows from where
the unwinder was added or where it looks for information to do the
unwinding. */
enum frame_unwind_class m_unwinder_class;
const struct frame_data *m_unwind_data;
public:
frame_unwind (const char *n, frame_type t, frame_unwind_class c,
const struct frame_data *d)
: m_name (n), m_type (t), m_unwinder_class (c), m_unwind_data (d) { }
const char *name () const
{
return m_name;
}
enum frame_type type () const
{
return m_type;
}
enum frame_unwind_class unwinder_class () const
{
return m_unwinder_class;
}
const struct frame_data *unwind_data () const
{
return m_unwind_data;
}
/* Default stop_reason function. It reports NO_REASON, unless the
frame is the outermost. */
virtual enum unwind_stop_reason stop_reason (frame_info_ptr this_frame,
void **this_prologue_cache) const;
/* Default frame sniffer. Will always return that the unwinder
is able to unwind the frame. */
virtual int sniffer (const frame_unwind *self,
frame_info_ptr this_frame,
void **this_prologue_cache) const;
/* The following methods are here mostly for interface functionality. They
all throw an error when called, as a safe way to check if an unwinder has
implemented the desired functionality. */
/* Calculate the ID of the given frame using this unwinder. */
virtual void this_id (frame_info_ptr this_frame, void **this_prologue_cache,
struct frame_id *id) const
{
error (_("No method this_id implemented for unwinder %s"), m_name);
}
/* Get the value of a register in a previous frame. */
virtual struct value *prev_register (frame_info_ptr this_frame,
void **this_prologue_cache,
int regnum) const
{
error (_("No method prev_register implemented for unwinder %s"), m_name);
}
/* Properly deallocate the cache. */
virtual void dealloc_cache (frame_info *self, void *this_cache) const
{
error (_("No method dealloc_cache implemented for unwinder %s"), m_name);
}
/* Get the previous architecture. */
virtual struct gdbarch *prev_arch (frame_info_ptr this_frame,
void **this_prologue_cache) const
{
error (_("No method prev_arch implemented for unwinder %s"), m_name);
}
};
/* This is a legacy version of the frame unwinder. The original struct
used function pointers for callbacks, this updated version has a
method that just passes the parameters along to the callback
pointer. */
class frame_unwind_legacy : public frame_unwind
{
public:
/* Should an attribute indicating the frame's address-in-block go /* Should an attribute indicating the frame's address-in-block go
here? */ here? */
frame_unwind_stop_reason_ftype *stop_reason; frame_unwind_stop_reason_ftype *stop_reason_p;
frame_this_id_ftype *this_id; frame_this_id_ftype *this_id_p;
frame_prev_register_ftype *prev_register; frame_prev_register_ftype *prev_register_p;
const struct frame_data *unwind_data; frame_sniffer_ftype *sniffer_p;
frame_sniffer_ftype *sniffer; frame_dealloc_cache_ftype *dealloc_cache_p;
frame_dealloc_cache_ftype *dealloc_cache; frame_prev_arch_ftype *prev_arch_p;
frame_prev_arch_ftype *prev_arch; //public:
frame_unwind_legacy (const char *n, frame_type t, frame_unwind_class c,
frame_unwind_stop_reason_ftype *sr,
frame_this_id_ftype *ti,
frame_prev_register_ftype *pr,
const struct frame_data *ud,
frame_sniffer_ftype *s,
frame_dealloc_cache_ftype *dc = nullptr,
frame_prev_arch_ftype *pa = nullptr)
: frame_unwind (n, t, c, ud), stop_reason_p (sr),
this_id_p (ti), prev_register_p (pr), sniffer_p (s),
dealloc_cache_p (dc), prev_arch_p (pa) { }
/* This method just passes the parameters to the callback pointer. */
enum unwind_stop_reason stop_reason (frame_info_ptr this_frame,
void **this_prologue_cache) const override;
/* This method just passes the parameters to the callback pointer. */
void this_id (frame_info_ptr this_frame, void **this_prologue_cache,
struct frame_id *id) const override;
/* This method just passes the parameters to the callback pointer. */
struct value *prev_register (frame_info_ptr this_frame,
void **this_prologue_cache,
int regnum) const override;
/* This method just passes the parameters to the callback pointer. */
int sniffer (const frame_unwind *self,
frame_info_ptr this_frame,
void **this_prologue_cache) const override;
/* This method just passes the parameters to the callback pointer.
It is safe to call this method if no callback is installed, it
just turns into a noop. */
void dealloc_cache (frame_info *self, void *this_cache) const override;
/* This method just passes the parameters to the callback pointer.
If this function is called with no installed callback, this method
will error out. Wrap calls in try-catch blocks. */
struct gdbarch *prev_arch (frame_info_ptr this_frame,
void **this_prologue_cache) const override;
}; };
/* Register a frame unwinder, _prepending_ it to the front of the /* Register a frame unwinder, _prepending_ it to the front of the

View File

@@ -268,12 +268,10 @@ frame_addr_hash_eq (const void *a, const void *b)
static void static void
frame_info_del (frame_info *frame) frame_info_del (frame_info *frame)
{ {
if (frame->prologue_cache != nullptr if (frame->prologue_cache != nullptr)
&& frame->unwind->dealloc_cache != nullptr)
frame->unwind->dealloc_cache (frame, frame->prologue_cache); frame->unwind->dealloc_cache (frame, frame->prologue_cache);
if (frame->base_cache != nullptr if (frame->base_cache != nullptr)
&& frame->base->unwind->dealloc_cache != nullptr)
frame->base->unwind->dealloc_cache (frame, frame->base_cache); frame->base->unwind->dealloc_cache (frame, frame->base_cache);
} }
@@ -486,12 +484,12 @@ frame_info::to_string () const
res += string_printf ("{level=%d,", fi->level); res += string_printf ("{level=%d,", fi->level);
if (fi->unwind != NULL) if (fi->unwind != NULL)
res += string_printf ("type=%s,", frame_type_str (fi->unwind->type)); res += string_printf ("type=%s,", frame_type_str (fi->unwind->type ()));
else else
res += "type=<unknown>,"; res += "type=<unknown>,";
if (fi->unwind != NULL) if (fi->unwind != NULL)
res += string_printf ("unwinder=\"%s\",", fi->unwind->name); res += string_printf ("unwinder=\"%s\",", fi->unwind->name ());
else else
res += "unwinder=<unknown>,"; res += "unwinder=<unknown>,";
@@ -2356,7 +2354,7 @@ get_prev_frame_always_1 (frame_info_ptr this_frame)
This check is valid only if this frame and the next frame are NORMAL. This check is valid only if this frame and the next frame are NORMAL.
See the comment at frame_id_inner for details. */ See the comment at frame_id_inner for details. */
if (get_frame_type (this_frame) == NORMAL_FRAME if (get_frame_type (this_frame) == NORMAL_FRAME
&& this_frame->next->unwind->type == NORMAL_FRAME && this_frame->next->unwind->type () == NORMAL_FRAME
&& frame_id_inner (get_frame_arch (frame_info_ptr (this_frame->next)), && frame_id_inner (get_frame_arch (frame_info_ptr (this_frame->next)),
get_frame_id (this_frame), get_frame_id (this_frame),
get_frame_id (frame_info_ptr (this_frame->next)))) get_frame_id (frame_info_ptr (this_frame->next))))
@@ -2952,7 +2950,7 @@ get_frame_type (frame_info_ptr frame)
/* Initialize the frame's unwinder because that's what /* Initialize the frame's unwinder because that's what
provides the frame's type. */ provides the frame's type. */
frame_unwind_find_by_frame (frame, &frame->prologue_cache); frame_unwind_find_by_frame (frame, &frame->prologue_cache);
return frame->unwind->type; return frame->unwind->type ();
} }
struct program_space * struct program_space *
@@ -3033,11 +3031,15 @@ frame_unwind_arch (frame_info_ptr next_frame)
if (next_frame->unwind == NULL) if (next_frame->unwind == NULL)
frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache); frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache);
if (next_frame->unwind->prev_arch != NULL) try
arch = next_frame->unwind->prev_arch (next_frame, {
&next_frame->prologue_cache); arch = next_frame->unwind->prev_arch (next_frame,
else &next_frame->prologue_cache);
arch = get_frame_arch (next_frame); }
catch (gdb_exception &e)
{
arch = get_frame_arch (next_frame);
}
next_frame->prev_arch.arch = arch; next_frame->prev_arch.arch = arch;
next_frame->prev_arch.p = true; next_frame->prev_arch.p = true;

View File

@@ -332,16 +332,16 @@ frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind frv_linux_sigtramp_frame_unwind = static const struct frame_unwind_legacy frv_linux_sigtramp_frame_unwind (
{
"frv linux sigtramp", "frv linux sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
frv_linux_sigtramp_frame_this_id, frv_linux_sigtramp_frame_this_id,
frv_linux_sigtramp_frame_prev_register, frv_linux_sigtramp_frame_prev_register,
NULL, NULL,
frv_linux_sigtramp_frame_sniffer frv_linux_sigtramp_frame_sniffer
}; );
/* The FRV kernel defines ELF_NGREG as 46. We add 2 in order to include /* The FRV kernel defines ELF_NGREG as 46. We add 2 in order to include
the loadmap addresses in the register set. (See below for more info.) */ the loadmap addresses in the register set. (See below for more info.) */

View File

@@ -1405,15 +1405,16 @@ frv_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
} }
static const struct frame_unwind frv_frame_unwind = { static const struct frame_unwind_legacy frv_frame_unwind (
"frv prologue", "frv prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
frv_frame_this_id, frv_frame_this_id,
frv_frame_prev_register, frv_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
frv_frame_base_address (frame_info_ptr this_frame, void **this_cache) frv_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -524,16 +524,16 @@ ft32_frame_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind ft32_frame_unwind = static const struct frame_unwind_legacy ft32_frame_unwind (
{
"ft32 prologue", "ft32 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
ft32_frame_this_id, ft32_frame_this_id,
ft32_frame_prev_register, ft32_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Return the base address of this_frame. */ /* Return the base address of this_frame. */

View File

@@ -27,6 +27,7 @@
/* Maintain the struct gdbarch object. */ /* Maintain the struct gdbarch object. */
#include <vector>
struct gdbarch struct gdbarch
{ {
/* Has this architecture been fully initialized? */ /* Has this architecture been fully initialized? */
@@ -36,6 +37,8 @@ struct gdbarch
auto_obstack obstack; auto_obstack obstack;
/* Registry. */ /* Registry. */
registry<gdbarch> registry_fields; registry<gdbarch> registry_fields;
/* list of frame unwinders. */
std::vector<const frame_unwind *> unwinders;
/* basic architectural information. */ /* basic architectural information. */
const struct bfd_arch_info * bfd_arch_info; const struct bfd_arch_info * bfd_arch_info;

View File

@@ -30,6 +30,7 @@
#include "displaced-stepping.h" #include "displaced-stepping.h"
#include "gdbsupport/gdb-checked-static-cast.h" #include "gdbsupport/gdb-checked-static-cast.h"
#include "registry.h" #include "registry.h"
#include "frame-unwind.h"
struct floatformat; struct floatformat;
struct ui_file; struct ui_file;
@@ -310,6 +311,10 @@ extern obstack *gdbarch_obstack (gdbarch *arch);
#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) obstack_zalloc<TYPE> (gdbarch_obstack ((GDBARCH))) #define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) obstack_zalloc<TYPE> (gdbarch_obstack ((GDBARCH)))
/* Return the vector of unwinders stored in a gdbarch object. */
std::vector<const frame_unwind*>& gdbarch_get_unwinder_list (struct gdbarch *arch);
/* Duplicate STRING, returning an equivalent string that's allocated on the /* Duplicate STRING, returning an equivalent string that's allocated on the
obstack associated with GDBARCH. The string is freed when the corresponding obstack associated with GDBARCH. The string is freed when the corresponding
architecture is also freed. */ architecture is also freed. */

View File

@@ -125,6 +125,7 @@ with open("gdbarch.c", "w") as f:
print(file=f) print(file=f)
print("/* Maintain the struct gdbarch object. */", file=f) print("/* Maintain the struct gdbarch object. */", file=f)
print(file=f) print(file=f)
print("#include <vector>",file=f)
# #
# The struct definition body. # The struct definition body.
# #
@@ -137,6 +138,8 @@ with open("gdbarch.c", "w") as f:
print(" auto_obstack obstack;", file=f) print(" auto_obstack obstack;", file=f)
print(" /* Registry. */", file=f) print(" /* Registry. */", file=f)
print(" registry<gdbarch> registry_fields;", file=f) print(" registry<gdbarch> registry_fields;", file=f)
print(" /* list of frame unwinders. */", file=f)
print(" std::vector<const frame_unwind *> unwinders;", file=f)
print(file=f) print(file=f)
print(" /* basic architectural information. */", file=f) print(" /* basic architectural information. */", file=f)
for c in filter(info, components): for c in filter(info, components):

View File

@@ -500,15 +500,16 @@ h8300_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind h8300_frame_unwind = { static const struct frame_unwind_legacy h8300_frame_unwind (
"h8300 prologue", "h8300 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
h8300_frame_this_id, h8300_frame_this_id,
h8300_frame_prev_register, h8300_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
h8300_frame_base_address (frame_info_ptr this_frame, void **this_cache) h8300_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -308,15 +308,16 @@ hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = { static const struct frame_unwind_legacy hppa_linux_sigtramp_frame_unwind (
"hppa linux sigtramp", "hppa linux sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
hppa_linux_sigtramp_frame_this_id, hppa_linux_sigtramp_frame_this_id,
hppa_linux_sigtramp_frame_prev_register, hppa_linux_sigtramp_frame_prev_register,
NULL, NULL,
hppa_linux_sigtramp_frame_sniffer hppa_linux_sigtramp_frame_sniffer
}; );
/* Attempt to find (and return) the global pointer for the given /* Attempt to find (and return) the global pointer for the given
function. function.

View File

@@ -2283,16 +2283,16 @@ hppa_frame_unwind_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind hppa_frame_unwind = static const struct frame_unwind_legacy hppa_frame_unwind (
{
"hppa unwind table", "hppa unwind table",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
hppa_frame_this_id, hppa_frame_this_id,
hppa_frame_prev_register, hppa_frame_prev_register,
NULL, NULL,
hppa_frame_unwind_sniffer hppa_frame_unwind_sniffer
}; );
/* This is a generic fallback frame unwinder that kicks in if we fail all /* This is a generic fallback frame unwinder that kicks in if we fail all
the other ones. Normally we would expect the stub and regular unwinder the other ones. Normally we would expect the stub and regular unwinder
@@ -2396,16 +2396,16 @@ hppa_fallback_frame_prev_register (frame_info_ptr this_frame,
info->saved_regs, regnum); info->saved_regs, regnum);
} }
static const struct frame_unwind hppa_fallback_frame_unwind = static const struct frame_unwind_legacy hppa_fallback_frame_unwind (
{
"hppa prologue", "hppa prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
hppa_fallback_frame_this_id, hppa_fallback_frame_this_id,
hppa_fallback_frame_prev_register, hppa_fallback_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Stub frames, used for all kinds of call stubs. */ /* Stub frames, used for all kinds of call stubs. */
struct hppa_stub_unwind_cache struct hppa_stub_unwind_cache
@@ -2478,15 +2478,16 @@ hppa_stub_unwind_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind hppa_stub_frame_unwind = { static const struct frame_unwind_legacy hppa_stub_frame_unwind (
"hppa stub", "hppa stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
hppa_stub_frame_this_id, hppa_stub_frame_this_id,
hppa_stub_frame_prev_register, hppa_stub_frame_prev_register,
NULL, NULL,
hppa_stub_unwind_sniffer hppa_stub_unwind_sniffer
}; );
CORE_ADDR CORE_ADDR
hppa_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame) hppa_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)

View File

@@ -390,18 +390,19 @@ i386obsd_trapframe_sniffer (const struct frame_unwind *self,
|| startswith (name, "Xsoft"))); || startswith (name, "Xsoft")));
} }
static const struct frame_unwind i386obsd_trapframe_unwind = { static const struct frame_unwind_legacy i386obsd_trapframe_unwind (
"i386 openbsd trap", "i386 openbsd trap",
/* FIXME: kettenis/20051219: This really is more like an interrupt /* FIXME: kettenis/20051219: This really is more like an interrupt
frame, but SIGTRAMP_FRAME would print <signal handler called>, frame, but SIGTRAMP_FRAME would print <signal handler called>,
which really is not what we want here. */ which really is not what we want here. */
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
i386obsd_trapframe_this_id, i386obsd_trapframe_this_id,
i386obsd_trapframe_prev_register, i386obsd_trapframe_prev_register,
NULL, NULL,
i386obsd_trapframe_sniffer i386obsd_trapframe_sniffer
}; );
static void static void

View File

@@ -2196,16 +2196,16 @@ i386_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind i386_frame_unwind = static const struct frame_unwind_legacy i386_frame_unwind (
{
"i386 prologue", "i386 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_frame_unwind_stop_reason, i386_frame_unwind_stop_reason,
i386_frame_this_id, i386_frame_this_id,
i386_frame_prev_register, i386_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Normal frames, but in a function epilogue. */ /* Normal frames, but in a function epilogue. */
@@ -2351,27 +2351,27 @@ i386_epilogue_frame_prev_register (frame_info_ptr this_frame,
return i386_frame_prev_register (this_frame, this_cache, regnum); return i386_frame_prev_register (this_frame, this_cache, regnum);
} }
static const struct frame_unwind i386_epilogue_override_frame_unwind = static const struct frame_unwind_legacy i386_epilogue_override_frame_unwind (
{
"i386 epilogue override", "i386 epilogue override",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason, i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id, i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register, i386_epilogue_frame_prev_register,
NULL, NULL,
i386_epilogue_override_frame_sniffer i386_epilogue_override_frame_sniffer
}; );
static const struct frame_unwind i386_epilogue_frame_unwind = static const struct frame_unwind_legacy i386_epilogue_frame_unwind (
{
"i386 epilogue", "i386 epilogue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason, i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id, i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register, i386_epilogue_frame_prev_register,
NULL, NULL,
i386_epilogue_frame_sniffer i386_epilogue_frame_sniffer
}; );
/* Stack-based trampolines. */ /* Stack-based trampolines. */
@@ -2444,16 +2444,16 @@ i386_stack_tramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind i386_stack_tramp_frame_unwind = static const struct frame_unwind_legacy i386_stack_tramp_frame_unwind (
{
"i386 stack tramp", "i386 stack tramp",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason, i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id, i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register, i386_epilogue_frame_prev_register,
NULL, NULL,
i386_stack_tramp_frame_sniffer i386_stack_tramp_frame_sniffer
}; );
/* Generate a bytecode expression to get the value of the saved PC. */ /* Generate a bytecode expression to get the value of the saved PC. */
@@ -2593,16 +2593,16 @@ i386_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind i386_sigtramp_frame_unwind = static const struct frame_unwind_legacy i386_sigtramp_frame_unwind (
{
"i386 sigtramp", "i386 sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
i386_sigtramp_frame_unwind_stop_reason, i386_sigtramp_frame_unwind_stop_reason,
i386_sigtramp_frame_this_id, i386_sigtramp_frame_this_id,
i386_sigtramp_frame_prev_register, i386_sigtramp_frame_prev_register,
NULL, NULL,
i386_sigtramp_frame_sniffer i386_sigtramp_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR

View File

@@ -2162,16 +2162,16 @@ ia64_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
} }
} }
static const struct frame_unwind ia64_frame_unwind = static const struct frame_unwind_legacy ia64_frame_unwind (
{
"ia64 prologue", "ia64 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
&ia64_frame_this_id, &ia64_frame_this_id,
&ia64_frame_prev_register, &ia64_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Signal trampolines. */ /* Signal trampolines. */
@@ -2351,16 +2351,16 @@ ia64_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind ia64_sigtramp_frame_unwind = static const struct frame_unwind_legacy ia64_sigtramp_frame_unwind (
{
"ia64 sigtramp", "ia64 sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
ia64_sigtramp_frame_this_id, ia64_sigtramp_frame_this_id,
ia64_sigtramp_frame_prev_register, ia64_sigtramp_frame_prev_register,
NULL, NULL,
ia64_sigtramp_frame_sniffer ia64_sigtramp_frame_sniffer
}; );
@@ -3011,17 +3011,17 @@ ia64_libunwind_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind ia64_libunwind_frame_unwind = static const struct frame_unwind_legacy ia64_libunwind_frame_unwind (
{
"ia64 libunwind", "ia64 libunwind",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
ia64_libunwind_frame_this_id, ia64_libunwind_frame_this_id,
ia64_libunwind_frame_prev_register, ia64_libunwind_frame_prev_register,
NULL, NULL,
ia64_libunwind_frame_sniffer, ia64_libunwind_frame_sniffer,
libunwind_frame_dealloc_cache libunwind_frame_dealloc_cache
}; );
static void static void
ia64_libunwind_sigtramp_frame_this_id (frame_info_ptr this_frame, ia64_libunwind_sigtramp_frame_this_id (frame_info_ptr this_frame,
@@ -3100,16 +3100,16 @@ ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
return ia64_sigtramp_frame_sniffer (self, this_frame, this_cache); return ia64_sigtramp_frame_sniffer (self, this_frame, this_cache);
} }
static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind = static const struct frame_unwind_legacy ia64_libunwind_sigtramp_frame_unwind (
{
"ia64 libunwind sigtramp", "ia64 libunwind sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
ia64_libunwind_sigtramp_frame_this_id, ia64_libunwind_sigtramp_frame_this_id,
ia64_libunwind_sigtramp_frame_prev_register, ia64_libunwind_sigtramp_frame_prev_register,
NULL, NULL,
ia64_libunwind_sigtramp_frame_sniffer ia64_libunwind_sigtramp_frame_sniffer
}; );
/* Set of libunwind callback acccessor functions. */ /* Set of libunwind callback acccessor functions. */
unw_accessors_t ia64_unw_accessors = unw_accessors_t ia64_unw_accessors =

View File

@@ -265,15 +265,16 @@ inline_frame_sniffer (const struct frame_unwind *self,
return 1; return 1;
} }
const struct frame_unwind inline_frame_unwind = { const struct frame_unwind_legacy inline_frame_unwind (
"inline", "inline",
INLINE_FRAME, INLINE_FRAME,
FRAME_UNWIND_GDB,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
inline_frame_this_id, inline_frame_this_id,
inline_frame_prev_register, inline_frame_prev_register,
NULL, NULL,
inline_frame_sniffer inline_frame_sniffer
}; );
/* Return non-zero if BLOCK, an inlined function block containing PC, /* Return non-zero if BLOCK, an inlined function block containing PC,
has a group of contiguous instructions starting at PC (but not has a group of contiguous instructions starting at PC (but not

View File

@@ -27,7 +27,7 @@ struct process_stratum_target;
/* The inline frame unwinder. */ /* The inline frame unwinder. */
extern const struct frame_unwind inline_frame_unwind; extern const struct frame_unwind_legacy inline_frame_unwind;
/* Skip all inlined functions whose call sites are at the current PC. /* Skip all inlined functions whose call sites are at the current PC.

View File

@@ -424,15 +424,16 @@ iq2000_frame_this_id (frame_info_ptr this_frame, void **this_cache,
*this_id = frame_id_build (cache->saved_sp, cache->pc); *this_id = frame_id_build (cache->saved_sp, cache->pc);
} }
static const struct frame_unwind iq2000_frame_unwind = { static const struct frame_unwind_legacy iq2000_frame_unwind (
"iq2000 prologue", "iq2000 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
iq2000_frame_this_id, iq2000_frame_this_id,
iq2000_frame_prev_register, iq2000_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
iq2000_frame_base_address (frame_info_ptr this_frame, void **this_cache) iq2000_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -1104,17 +1104,17 @@ jit_frame_prev_register (frame_info_ptr this_frame, void **cache, int reg)
/* Relay everything back to the unwinder registered by the JIT debug /* Relay everything back to the unwinder registered by the JIT debug
info reader.*/ info reader.*/
static const struct frame_unwind jit_frame_unwind = static const struct frame_unwind_legacy jit_frame_unwind (
{
"jit", "jit",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_EXTENSION,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
jit_frame_this_id, jit_frame_this_id,
jit_frame_prev_register, jit_frame_prev_register,
NULL, NULL,
jit_frame_sniffer, jit_frame_sniffer,
jit_dealloc_cache jit_dealloc_cache
}; );
/* This is the information that is stored at jit_gdbarch_data for each /* This is the information that is stored at jit_gdbarch_data for each

View File

@@ -447,15 +447,16 @@ lm32_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
} }
static const struct frame_unwind lm32_frame_unwind = { static const struct frame_unwind_legacy lm32_frame_unwind (
"lm32 prologue", "lm32 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
lm32_frame_this_id, lm32_frame_this_id,
lm32_frame_prev_register, lm32_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
lm32_frame_base_address (frame_info_ptr this_frame, void **this_cache) lm32_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -450,17 +450,18 @@ loongarch_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_register (info, this_frame, regnum); return trad_frame_get_register (info, this_frame, regnum);
} }
static const struct frame_unwind loongarch_frame_unwind = { static const struct frame_unwind_legacy loongarch_frame_unwind (
"loongarch prologue", "loongarch prologue",
/*.type =*/NORMAL_FRAME, /*.type =*/NORMAL_FRAME,
/*.unwinder_class=*/FRAME_UNWIND_ARCH,
/*.stop_reason =*/default_frame_unwind_stop_reason, /*.stop_reason =*/default_frame_unwind_stop_reason,
/*.this_id =*/loongarch_frame_this_id, /*.this_id =*/loongarch_frame_this_id,
/*.prev_register =*/loongarch_frame_prev_register, /*.prev_register =*/loongarch_frame_prev_register,
/*.unwind_data =*/nullptr, /*.unwind_data =*/nullptr,
/*.sniffer =*/default_frame_sniffer, /*.sniffer =*/default_frame_sniffer,
/*.dealloc_cache =*/nullptr, /*.dealloc_cache =*/nullptr,
/*.prev_arch =*/nullptr, /*.prev_arch =*/nullptr
}; );
/* Write the contents of buffer VAL into the general-purpose argument /* Write the contents of buffer VAL into the general-purpose argument
register defined by GAR in REGCACHE. GAR indicates the available register defined by GAR in REGCACHE. GAR indicates the available

View File

@@ -1955,15 +1955,16 @@ m32c_prev_register (frame_info_ptr this_frame,
} }
static const struct frame_unwind m32c_unwind = { static const struct frame_unwind_legacy m32c_unwind (
"m32c prologue", "m32c prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
m32c_this_id, m32c_this_id,
m32c_prev_register, m32c_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Inferior calls. */ /* Inferior calls. */

View File

@@ -301,15 +301,16 @@ m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = { static const struct frame_unwind_legacy m32r_linux_sigtramp_frame_unwind (
"m32r linux sigtramp", "m32r linux sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
m32r_linux_sigtramp_frame_this_id, m32r_linux_sigtramp_frame_this_id,
m32r_linux_sigtramp_frame_prev_register, m32r_linux_sigtramp_frame_prev_register,
NULL, NULL,
m32r_linux_sigtramp_frame_sniffer m32r_linux_sigtramp_frame_sniffer
}; );
/* Mapping between the registers in `struct pt_regs' /* Mapping between the registers in `struct pt_regs'
format and GDB's register array layout. */ format and GDB's register array layout. */

View File

@@ -831,15 +831,16 @@ m32r_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
} }
static const struct frame_unwind m32r_frame_unwind = { static const struct frame_unwind_legacy m32r_frame_unwind (
"m32r prologue", "m32r prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
m32r_frame_this_id, m32r_frame_this_id,
m32r_frame_prev_register, m32r_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
m32r_frame_base_address (frame_info_ptr this_frame, void **this_cache) m32r_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -936,15 +936,16 @@ m68hc11_frame_prev_register (frame_info_ptr this_frame,
return value; return value;
} }
static const struct frame_unwind m68hc11_frame_unwind = { static const struct frame_unwind_legacy m68hc11_frame_unwind (
"m68hc11 prologue", "m68hc11 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
m68hc11_frame_this_id, m68hc11_frame_this_id,
m68hc11_frame_prev_register, m68hc11_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
m68hc11_frame_base_address (frame_info_ptr this_frame, void **this_cache) m68hc11_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -314,16 +314,16 @@ m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
return m68k_linux_pc_in_sigtramp (this_frame); return m68k_linux_pc_in_sigtramp (this_frame);
} }
static const struct frame_unwind m68k_linux_sigtramp_frame_unwind = static const struct frame_unwind_legacy m68k_linux_sigtramp_frame_unwind (
{
"m68k linux sigtramp", "m68k linux sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
m68k_linux_sigtramp_frame_this_id, m68k_linux_sigtramp_frame_this_id,
m68k_linux_sigtramp_frame_prev_register, m68k_linux_sigtramp_frame_prev_register,
NULL, NULL,
m68k_linux_sigtramp_frame_sniffer m68k_linux_sigtramp_frame_sniffer
}; );
/* Register maps for supply/collect regset functions. */ /* Register maps for supply/collect regset functions. */

View File

@@ -1007,16 +1007,16 @@ m68k_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind m68k_frame_unwind = static const struct frame_unwind_legacy m68k_frame_unwind (
{
"m68k prologue", "m68k prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
m68k_frame_this_id, m68k_frame_this_id,
m68k_frame_prev_register, m68k_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
m68k_frame_base_address (frame_info_ptr this_frame, void **this_cache) m68k_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -2061,15 +2061,16 @@ mep_frame_prev_register (frame_info_ptr this_frame,
} }
static const struct frame_unwind mep_frame_unwind = { static const struct frame_unwind_legacy mep_frame_unwind (
"mep prologue", "mep prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
mep_frame_this_id, mep_frame_this_id,
mep_frame_prev_register, mep_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Return values. */ /* Return values. */

View File

@@ -478,16 +478,16 @@ microblaze_frame_prev_register (frame_info_ptr this_frame,
} }
static const struct frame_unwind microblaze_frame_unwind = static const struct frame_unwind_legacy microblaze_frame_unwind (
{
"microblaze prologue", "microblaze prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
microblaze_frame_this_id, microblaze_frame_this_id,
microblaze_frame_prev_register, microblaze_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
microblaze_frame_base_address (frame_info_ptr next_frame, microblaze_frame_base_address (frame_info_ptr next_frame,

View File

@@ -161,16 +161,16 @@ mips_sde_frame_sniffer (const struct frame_unwind *self,
/* Data structure for the SDE frame unwinder. */ /* Data structure for the SDE frame unwinder. */
static const struct frame_unwind mips_sde_frame_unwind = static const struct frame_unwind_legacy mips_sde_frame_unwind (
{
"mips sde sigtramp", "mips sde sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
mips_sde_frame_this_id, mips_sde_frame_this_id,
mips_sde_frame_prev_register, mips_sde_frame_prev_register,
NULL, NULL,
mips_sde_frame_sniffer mips_sde_frame_sniffer
}; );
/* Implement the this_base, this_locals, and this_args hooks /* Implement the this_base, this_locals, and this_args hooks
for the normal unwinder. */ for the normal unwinder. */

View File

@@ -2929,16 +2929,16 @@ mips_insn16_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind mips_insn16_frame_unwind = static const struct frame_unwind_legacy mips_insn16_frame_unwind (
{
"mips insn16 prologue", "mips insn16 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
mips_insn16_frame_this_id, mips_insn16_frame_this_id,
mips_insn16_frame_prev_register, mips_insn16_frame_prev_register,
NULL, NULL,
mips_insn16_frame_sniffer mips_insn16_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
mips_insn16_frame_base_address (frame_info_ptr this_frame, mips_insn16_frame_base_address (frame_info_ptr this_frame,
@@ -3365,16 +3365,16 @@ mips_micro_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind mips_micro_frame_unwind = static const struct frame_unwind_legacy mips_micro_frame_unwind (
{
"mips micro prologue", "mips micro prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
mips_micro_frame_this_id, mips_micro_frame_this_id,
mips_micro_frame_prev_register, mips_micro_frame_prev_register,
NULL, NULL,
mips_micro_frame_sniffer mips_micro_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
mips_micro_frame_base_address (frame_info_ptr this_frame, mips_micro_frame_base_address (frame_info_ptr this_frame,
@@ -3744,16 +3744,16 @@ mips_insn32_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind mips_insn32_frame_unwind = static const struct frame_unwind_legacy mips_insn32_frame_unwind (
{
"mips insn32 prologue", "mips insn32 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
mips_insn32_frame_this_id, mips_insn32_frame_this_id,
mips_insn32_frame_prev_register, mips_insn32_frame_prev_register,
NULL, NULL,
mips_insn32_frame_sniffer mips_insn32_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
mips_insn32_frame_base_address (frame_info_ptr this_frame, mips_insn32_frame_base_address (frame_info_ptr this_frame,
@@ -3861,16 +3861,16 @@ mips_stub_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind mips_stub_frame_unwind = static const struct frame_unwind_legacy mips_stub_frame_unwind (
{
"mips stub", "mips stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
mips_stub_frame_this_id, mips_stub_frame_this_id,
mips_stub_frame_prev_register, mips_stub_frame_prev_register,
NULL, NULL,
mips_stub_frame_sniffer mips_stub_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
mips_stub_frame_base_address (frame_info_ptr this_frame, mips_stub_frame_base_address (frame_info_ptr this_frame,

View File

@@ -1127,15 +1127,16 @@ mn10300_frame_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind mn10300_frame_unwind = { static const struct frame_unwind_legacy mn10300_frame_unwind (
"mn10300 prologue", "mn10300 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
mn10300_frame_this_id, mn10300_frame_this_id,
mn10300_frame_prev_register, mn10300_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static void static void
mn10300_frame_unwind_init (struct gdbarch *gdbarch) mn10300_frame_unwind_init (struct gdbarch *gdbarch)

View File

@@ -585,15 +585,16 @@ moxie_frame_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind moxie_frame_unwind = { static const struct frame_unwind_legacy moxie_frame_unwind (
"moxie prologue", "moxie prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
moxie_frame_this_id, moxie_frame_this_id,
moxie_frame_prev_register, moxie_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Return the base address of this_frame. */ /* Return the base address of this_frame. */

View File

@@ -542,15 +542,16 @@ msp430_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind msp430_unwind = { static const struct frame_unwind_legacy msp430_unwind (
"msp430 prologue", "msp430 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
msp430_this_id, msp430_this_id,
msp430_prev_register, msp430_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Implement the "dwarf2_reg_to_regnum" gdbarch method. */ /* Implement the "dwarf2_reg_to_regnum" gdbarch method. */

View File

@@ -988,16 +988,16 @@ nds32_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind nds32_frame_unwind = static const struct frame_unwind_legacy nds32_frame_unwind (
{
"nds32 prologue", "nds32 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
nds32_frame_this_id, nds32_frame_this_id,
nds32_frame_prev_register, nds32_frame_prev_register,
NULL, NULL,
default_frame_sniffer, default_frame_sniffer
}; );
/* Return the frame base address of *THIS_FRAME. */ /* Return the frame base address of *THIS_FRAME. */
@@ -1372,16 +1372,16 @@ nds32_epilogue_frame_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind nds32_epilogue_frame_unwind = static const struct frame_unwind_legacy nds32_epilogue_frame_unwind (
{
"nds32 epilogue", "nds32 epilogue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
nds32_epilogue_frame_this_id, nds32_epilogue_frame_this_id,
nds32_epilogue_frame_prev_register, nds32_epilogue_frame_prev_register,
NULL, NULL,
nds32_epilogue_frame_sniffer nds32_epilogue_frame_sniffer
}; );
/* Floating type and struct type that has only one floating type member /* Floating type and struct type that has only one floating type member

View File

@@ -1977,16 +1977,16 @@ nios2_frame_base_address (frame_info_ptr this_frame, void **this_cache)
/* Data structures for the normal prologue-analysis-based /* Data structures for the normal prologue-analysis-based
unwinder. */ unwinder. */
static const struct frame_unwind nios2_frame_unwind = static const struct frame_unwind_legacy nios2_frame_unwind (
{
"nios2 prologue", "nios2 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
nios2_frame_this_id, nios2_frame_this_id,
nios2_frame_prev_register, nios2_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static const struct frame_base nios2_frame_base = static const struct frame_base nios2_frame_base =
{ {
@@ -2078,16 +2078,16 @@ nios2_stub_frame_sniffer (const struct frame_unwind *self,
/* Define the data structures for the stub unwinder. */ /* Define the data structures for the stub unwinder. */
static const struct frame_unwind nios2_stub_frame_unwind = static const struct frame_unwind_legacy nios2_stub_frame_unwind (
{
"nios2 stub", "nios2 stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
nios2_stub_frame_this_id, nios2_stub_frame_this_id,
nios2_stub_frame_prev_register, nios2_stub_frame_prev_register,
NULL, NULL,
nios2_stub_frame_sniffer nios2_stub_frame_sniffer
}; );

View File

@@ -1125,16 +1125,17 @@ or1k_frame_prev_register (frame_info_ptr this_frame,
/* Data structures for the normal prologue-analysis-based unwinder. */ /* Data structures for the normal prologue-analysis-based unwinder. */
static const struct frame_unwind or1k_frame_unwind = { static const struct frame_unwind_legacy or1k_frame_unwind (
"or1k prologue", "or1k prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
or1k_frame_this_id, or1k_frame_this_id,
or1k_frame_prev_register, or1k_frame_prev_register,
NULL, NULL,
default_frame_sniffer, default_frame_sniffer,
NULL, NULL
}; );
/* Architecture initialization for OpenRISC 1000. */ /* Architecture initialization for OpenRISC 1000. */

View File

@@ -262,15 +262,16 @@ ppcfbsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_register (cache, this_frame, regnum); return trad_frame_get_register (cache, this_frame, regnum);
} }
static const struct frame_unwind ppcfbsd_sigtramp_frame_unwind = { static const struct frame_unwind_legacy ppcfbsd_sigtramp_frame_unwind (
"ppc freebsd sigtramp", "ppc freebsd sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
ppcfbsd_sigtramp_frame_this_id, ppcfbsd_sigtramp_frame_this_id,
ppcfbsd_sigtramp_frame_prev_register, ppcfbsd_sigtramp_frame_prev_register,
NULL, NULL,
ppcfbsd_sigtramp_frame_sniffer ppcfbsd_sigtramp_frame_sniffer
}; );
static enum return_value_convention static enum return_value_convention
ppcfbsd_return_value (struct gdbarch *gdbarch, struct value *function, ppcfbsd_return_value (struct gdbarch *gdbarch, struct value *function,

View File

@@ -231,15 +231,16 @@ ppcobsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_register (cache, this_frame, regnum); return trad_frame_get_register (cache, this_frame, regnum);
} }
static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = { static const struct frame_unwind_legacy ppcobsd_sigtramp_frame_unwind (
"ppc openbsd sigtramp", "ppc openbsd sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
ppcobsd_sigtramp_frame_this_id, ppcobsd_sigtramp_frame_this_id,
ppcobsd_sigtramp_frame_prev_register, ppcobsd_sigtramp_frame_prev_register,
NULL, NULL,
ppcobsd_sigtramp_frame_sniffer ppcobsd_sigtramp_frame_sniffer
}; );
static void static void

View File

@@ -807,7 +807,7 @@ pyuw_sniffer (const struct frame_unwind *self, frame_info_ptr this_frame,
{ {
PYUW_SCOPED_DEBUG_ENTER_EXIT; PYUW_SCOPED_DEBUG_ENTER_EXIT;
struct gdbarch *gdbarch = (struct gdbarch *) (self->unwind_data); struct gdbarch *gdbarch = (struct gdbarch *) (self->unwind_data ());
cached_frame_info *cached_frame; cached_frame_info *cached_frame;
gdbpy_enter enter_py (gdbarch); gdbpy_enter enter_py (gdbarch);
@@ -948,6 +948,41 @@ struct pyuw_gdbarch_data_type
static const registry<gdbarch>::key<pyuw_gdbarch_data_type> pyuw_gdbarch_data; static const registry<gdbarch>::key<pyuw_gdbarch_data_type> pyuw_gdbarch_data;
/* Class for frame unwinders registered by the Python architecture callback. */
class frame_unwind_python : public frame_unwind
{
public:
frame_unwind_python (const struct frame_data *newarch)
: frame_unwind ("python", NORMAL_FRAME, FRAME_UNWIND_EXTENSION, newarch)
{ }
/* No need to override stop_reason, we want the default. */
int sniffer (const frame_unwind *self, frame_info_ptr this_frame,
void **this_prologue_cache) const override
{
return pyuw_sniffer (self, this_frame, this_prologue_cache);
}
void this_id (frame_info_ptr this_frame, void **this_prologue_cache,
struct frame_id *id) const override
{
pyuw_this_id (this_frame, this_prologue_cache, id);
}
struct value *prev_register (frame_info_ptr this_frame,
void **this_prologue_cache,
int regnum) const override
{
return pyuw_prev_register (this_frame, this_prologue_cache, regnum);
}
void dealloc_cache (frame_info *self, void *this_cache) const override
{
pyuw_dealloc_cache (self, this_cache);
}
};
/* New inferior architecture callback: register the Python unwinders /* New inferior architecture callback: register the Python unwinders
intermediary. */ intermediary. */
@@ -961,16 +996,9 @@ pyuw_on_new_gdbarch (gdbarch *newarch)
if (!data->unwinder_registered) if (!data->unwinder_registered)
{ {
struct frame_unwind *unwinder struct frame_unwind *unwinder
= GDBARCH_OBSTACK_ZALLOC (newarch, struct frame_unwind); = obstack_new<frame_unwind_python>
(gdbarch_obstack(newarch), (const struct frame_data *) newarch);
unwinder->name = "python";
unwinder->type = NORMAL_FRAME;
unwinder->stop_reason = default_frame_unwind_stop_reason;
unwinder->this_id = pyuw_this_id;
unwinder->prev_register = pyuw_prev_register;
unwinder->unwind_data = (const struct frame_data *) newarch;
unwinder->sniffer = pyuw_sniffer;
unwinder->dealloc_cache = pyuw_dealloc_cache;
frame_unwind_prepend_unwinder (newarch, unwinder); frame_unwind_prepend_unwinder (newarch, unwinder);
data->unwinder_registered = 1; data->unwinder_registered = 1;
} }

View File

@@ -1894,29 +1894,29 @@ record_btrace_frame_dealloc_cache (frame_info *self, void *this_cache)
Therefore this unwinder reports any possibly unwound registers as Therefore this unwinder reports any possibly unwound registers as
<unavailable>. */ <unavailable>. */
const struct frame_unwind record_btrace_frame_unwind = const struct frame_unwind_legacy record_btrace_frame_unwind (
{
"record-btrace", "record-btrace",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_GDB,
record_btrace_frame_unwind_stop_reason, record_btrace_frame_unwind_stop_reason,
record_btrace_frame_this_id, record_btrace_frame_this_id,
record_btrace_frame_prev_register, record_btrace_frame_prev_register,
NULL, NULL,
record_btrace_frame_sniffer, record_btrace_frame_sniffer,
record_btrace_frame_dealloc_cache record_btrace_frame_dealloc_cache
}; );
const struct frame_unwind record_btrace_tailcall_frame_unwind = const struct frame_unwind_legacy record_btrace_tailcall_frame_unwind (
{
"record-btrace tailcall", "record-btrace tailcall",
TAILCALL_FRAME, TAILCALL_FRAME,
FRAME_UNWIND_GDB,
record_btrace_frame_unwind_stop_reason, record_btrace_frame_unwind_stop_reason,
record_btrace_frame_this_id, record_btrace_frame_this_id,
record_btrace_frame_prev_register, record_btrace_frame_prev_register,
NULL, NULL,
record_btrace_tailcall_frame_sniffer, record_btrace_tailcall_frame_sniffer,
record_btrace_frame_dealloc_cache record_btrace_frame_dealloc_cache
}; );
/* Implement the get_unwinder method. */ /* Implement the get_unwinder method. */

View File

@@ -36,8 +36,8 @@ extern struct cmd_list_element *show_record_cmdlist;
extern struct cmd_list_element *info_record_cmdlist; extern struct cmd_list_element *info_record_cmdlist;
/* Unwinders for some record targets. */ /* Unwinders for some record targets. */
extern const struct frame_unwind record_btrace_frame_unwind; extern const struct frame_unwind_legacy record_btrace_frame_unwind;
extern const struct frame_unwind record_btrace_tailcall_frame_unwind; extern const struct frame_unwind_legacy record_btrace_tailcall_frame_unwind;
/* A list of different recording methods. */ /* A list of different recording methods. */
enum record_method enum record_method

View File

@@ -3901,18 +3901,18 @@ riscv_frame_prev_register (frame_info_ptr this_frame,
are the fallback unwinder (DWARF unwinder is used first), we use the are the fallback unwinder (DWARF unwinder is used first), we use the
default frame sniffer, which always accepts the frame. */ default frame sniffer, which always accepts the frame. */
static const struct frame_unwind riscv_frame_unwind = static const struct frame_unwind_legacy riscv_frame_unwind (
{
/*.name =*/ "riscv prologue", /*.name =*/ "riscv prologue",
/*.type =*/ NORMAL_FRAME, /*.type =*/ NORMAL_FRAME,
/*.unwinder_class=*/FRAME_UNWIND_ARCH,
/*.stop_reason =*/ default_frame_unwind_stop_reason, /*.stop_reason =*/ default_frame_unwind_stop_reason,
/*.this_id =*/ riscv_frame_this_id, /*.this_id =*/ riscv_frame_this_id,
/*.prev_register =*/ riscv_frame_prev_register, /*.prev_register =*/ riscv_frame_prev_register,
/*.unwind_data =*/ NULL, /*.unwind_data =*/ NULL,
/*.sniffer =*/ default_frame_sniffer, /*.sniffer =*/ default_frame_sniffer,
/*.dealloc_cache =*/ NULL, /*.dealloc_cache =*/ NULL,
/*.prev_arch =*/ NULL, /*.prev_arch =*/ NULL
}; );
/* Extract a set of required target features out of ABFD. If ABFD is /* Extract a set of required target features out of ABFD. If ABFD is
nullptr then a RISCV_GDBARCH_FEATURES is returned in its default state. */ nullptr then a RISCV_GDBARCH_FEATURES is returned in its default state. */

View File

@@ -1183,16 +1183,16 @@ rl78_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind rl78_unwind = static const struct frame_unwind_legacy rl78_unwind (
{
"rl78 prologue", "rl78 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
rl78_this_id, rl78_this_id,
rl78_prev_register, rl78_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Implement the "dwarf_reg_to_regnum" gdbarch method. */ /* Implement the "dwarf_reg_to_regnum" gdbarch method. */

View File

@@ -328,15 +328,16 @@ aix_sighandle_frame_sniffer (const struct frame_unwind *self,
/* AIX signal handler frame unwinder */ /* AIX signal handler frame unwinder */
static const struct frame_unwind aix_sighandle_frame_unwind = { static const struct frame_unwind_legacy aix_sighandle_frame_unwind (
"rs6000 aix sighandle", "rs6000 aix sighandle",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
aix_sighandle_frame_this_id, aix_sighandle_frame_this_id,
aix_sighandle_frame_prev_register, aix_sighandle_frame_prev_register,
NULL, NULL,
aix_sighandle_frame_sniffer aix_sighandle_frame_sniffer
}; );
/* Core file support. */ /* Core file support. */

View File

@@ -3838,16 +3838,16 @@ rs6000_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
} }
static const struct frame_unwind rs6000_frame_unwind = static const struct frame_unwind_legacy rs6000_frame_unwind (
{
"rs6000 prologue", "rs6000 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
rs6000_frame_this_id, rs6000_frame_this_id,
rs6000_frame_prev_register, rs6000_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Allocate and initialize a frame cache for an epilogue frame. /* Allocate and initialize a frame cache for an epilogue frame.
SP is restored and prev-PC is stored in LR. */ SP is restored and prev-PC is stored in LR. */
@@ -3979,15 +3979,15 @@ rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
/* Frame unwinder for epilogue frame. This is required for reverse step-over /* Frame unwinder for epilogue frame. This is required for reverse step-over
a function without debug information. */ a function without debug information. */
static const struct frame_unwind rs6000_epilogue_frame_unwind = static const struct frame_unwind_legacy rs6000_epilogue_frame_unwind (
{
"rs6000 epilogue", "rs6000 epilogue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register, rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
NULL, NULL,
rs6000_epilogue_frame_sniffer rs6000_epilogue_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR

View File

@@ -631,29 +631,31 @@ rx_exception_sniffer (const struct frame_unwind *self,
/* Data structure for normal code using instruction-based prologue /* Data structure for normal code using instruction-based prologue
analyzer. */ analyzer. */
static const struct frame_unwind rx_frame_unwind = { static const struct frame_unwind_legacy rx_frame_unwind (
"rx prologue", "rx prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
rx_frame_this_id, rx_frame_this_id,
rx_frame_prev_register, rx_frame_prev_register,
NULL, NULL,
rx_frame_sniffer rx_frame_sniffer
}; );
/* Data structure for exception code using instruction-based prologue /* Data structure for exception code using instruction-based prologue
analyzer. */ analyzer. */
static const struct frame_unwind rx_exception_unwind = { static const struct frame_unwind_legacy rx_exception_unwind (
"rx exception", "rx exception",
/* SIGTRAMP_FRAME could be used here, but backtraces are less informative. */ /* SIGTRAMP_FRAME could be used here, but backtraces are less informative. */
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
rx_frame_this_id, rx_frame_this_id,
rx_frame_prev_register, rx_frame_prev_register,
NULL, NULL,
rx_exception_sniffer rx_exception_sniffer
}; );
/* Implement the "push_dummy_call" gdbarch method. */ /* Implement the "push_dummy_call" gdbarch method. */
static CORE_ADDR static CORE_ADDR

View File

@@ -442,16 +442,17 @@ s12z_frame_prev_register (frame_info_ptr this_frame,
} }
/* Data structures for the normal prologue-analysis-based unwinder. */ /* Data structures for the normal prologue-analysis-based unwinder. */
static const struct frame_unwind s12z_frame_unwind = { static const struct frame_unwind_legacy s12z_frame_unwind (
"s12z prologue", "s12z prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
s12z_frame_this_id, s12z_frame_this_id,
s12z_frame_prev_register, s12z_frame_prev_register,
NULL, NULL,
default_frame_sniffer, default_frame_sniffer,
NULL, NULL
}; );
constexpr gdb_byte s12z_break_insn[] = {0x00}; constexpr gdb_byte s12z_break_insn[] = {0x00};

View File

@@ -542,15 +542,16 @@ s390_sigtramp_frame_sniffer (const struct frame_unwind *self,
/* S390 sigtramp frame unwinder. */ /* S390 sigtramp frame unwinder. */
static const struct frame_unwind s390_sigtramp_frame_unwind = { static const struct frame_unwind_legacy s390_sigtramp_frame_unwind (
"s390 linux sigtramp", "s390 linux sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
s390_sigtramp_frame_this_id, s390_sigtramp_frame_this_id,
s390_sigtramp_frame_prev_register, s390_sigtramp_frame_prev_register,
NULL, NULL,
s390_sigtramp_frame_sniffer s390_sigtramp_frame_sniffer
}; );
/* Syscall handling. */ /* Syscall handling. */

View File

@@ -2646,15 +2646,16 @@ s390_frame_prev_register (frame_info_ptr this_frame,
/* Default S390 frame unwinder. */ /* Default S390 frame unwinder. */
static const struct frame_unwind s390_frame_unwind = { static const struct frame_unwind_legacy s390_frame_unwind (
"s390 prologue", "s390 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
s390_frame_this_id, s390_frame_this_id,
s390_frame_prev_register, s390_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
/* Code stubs and their stack frames. For things like PLTs and NULL /* Code stubs and their stack frames. For things like PLTs and NULL
function calls (where there is no true frame and the return address function calls (where there is no true frame and the return address
@@ -2740,15 +2741,16 @@ s390_stub_frame_sniffer (const struct frame_unwind *self,
/* S390 stub frame unwinder. */ /* S390 stub frame unwinder. */
static const struct frame_unwind s390_stub_frame_unwind = { static const struct frame_unwind_legacy s390_stub_frame_unwind (
"s390 stub", "s390 stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
s390_stub_frame_this_id, s390_stub_frame_this_id,
s390_stub_frame_prev_register, s390_stub_frame_prev_register,
NULL, NULL,
s390_stub_frame_sniffer s390_stub_frame_sniffer
}; );
/* Frame base handling. */ /* Frame base handling. */

View File

@@ -79,15 +79,15 @@ sentinel_frame_prev_arch (frame_info_ptr this_frame,
return cache->regcache->arch (); return cache->regcache->arch ();
} }
const struct frame_unwind sentinel_frame_unwind = const struct frame_unwind_legacy sentinel_frame_unwind (
{
"sentinel", "sentinel",
SENTINEL_FRAME, SENTINEL_FRAME,
FRAME_UNWIND_GDB,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sentinel_frame_this_id, sentinel_frame_this_id,
sentinel_frame_prev_register, sentinel_frame_prev_register,
NULL, NULL,
NULL, NULL,
NULL, NULL,
sentinel_frame_prev_arch, sentinel_frame_prev_arch
}; );

View File

@@ -34,6 +34,6 @@ extern void *sentinel_frame_cache (struct regcache *regcache);
/* At present there is only one type of sentinel frame. */ /* At present there is only one type of sentinel frame. */
extern const struct frame_unwind sentinel_frame_unwind; extern const struct frame_unwind_legacy sentinel_frame_unwind;
#endif /* !defined (SENTINEL_FRAME_H) */ #endif /* !defined (SENTINEL_FRAME_H) */

View File

@@ -1929,15 +1929,16 @@ sh_frame_this_id (frame_info_ptr this_frame, void **this_cache,
*this_id = frame_id_build (cache->saved_sp, cache->pc); *this_id = frame_id_build (cache->saved_sp, cache->pc);
} }
static const struct frame_unwind sh_frame_unwind = { static const struct frame_unwind_legacy sh_frame_unwind (
"sh prologue", "sh prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sh_frame_this_id, sh_frame_this_id,
sh_frame_prev_register, sh_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
sh_frame_base_address (frame_info_ptr this_frame, void **this_cache) sh_frame_base_address (frame_info_ptr this_frame, void **this_cache)
@@ -1995,16 +1996,16 @@ sh_stub_unwind_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind sh_stub_unwind = static const struct frame_unwind_legacy sh_stub_unwind (
{
"sh stub", "sh stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sh_stub_this_id, sh_stub_this_id,
sh_frame_prev_register, sh_frame_prev_register,
NULL, NULL,
sh_stub_unwind_sniffer sh_stub_unwind_sniffer
}; );
/* Implement the stack_frame_destroyed_p gdbarch method. /* Implement the stack_frame_destroyed_p gdbarch method.

View File

@@ -249,16 +249,16 @@ sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind = static const struct frame_unwind_legacy sparc32nbsd_sigcontext_frame_unwind (
{
"sparc32 netbsd sigcontext", "sparc32 netbsd sigcontext",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc32nbsd_sigcontext_frame_this_id, sparc32nbsd_sigcontext_frame_this_id,
sparc32nbsd_sigcontext_frame_prev_register, sparc32nbsd_sigcontext_frame_prev_register,
NULL, NULL,
sparc32nbsd_sigcontext_frame_sniffer sparc32nbsd_sigcontext_frame_sniffer
}; );
/* Return the address of a system call's alternative return /* Return the address of a system call's alternative return
address. */ address. */

View File

@@ -134,16 +134,16 @@ sparc32obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind = static const struct frame_unwind_legacy sparc32obsd_sigtramp_frame_unwind (
{
"sparc32 openbsd sigtramp", "sparc32 openbsd sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc32obsd_sigtramp_frame_this_id, sparc32obsd_sigtramp_frame_this_id,
sparc32obsd_sigtramp_frame_prev_register, sparc32obsd_sigtramp_frame_prev_register,
NULL, NULL,
sparc32obsd_sigtramp_frame_sniffer sparc32obsd_sigtramp_frame_sniffer
}; );

View File

@@ -180,16 +180,16 @@ sparc32_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
return sol2_sigtramp_p (this_frame); return sol2_sigtramp_p (this_frame);
} }
static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind = static const struct frame_unwind_legacy sparc32_sol2_sigtramp_frame_unwind (
{
"sparc32 solaris sigtramp", "sparc32 solaris sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc32_sol2_sigtramp_frame_this_id, sparc32_sol2_sigtramp_frame_this_id,
sparc32_sol2_sigtramp_frame_prev_register, sparc32_sol2_sigtramp_frame_prev_register,
NULL, NULL,
sparc32_sol2_sigtramp_frame_sniffer sparc32_sol2_sigtramp_frame_sniffer
}; );

View File

@@ -1346,16 +1346,16 @@ sparc32_frame_prev_register (frame_info_ptr this_frame,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind sparc32_frame_unwind = static const struct frame_unwind_legacy sparc32_frame_unwind (
{
"sparc32 prologue", "sparc32 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc32_frame_this_id, sparc32_frame_this_id,
sparc32_frame_prev_register, sparc32_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR

View File

@@ -197,16 +197,16 @@ sparc64fbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind = static const struct frame_unwind_legacy sparc64fbsd_sigtramp_frame_unwind (
{
"sparc64 freebsd sigtramp", "sparc64 freebsd sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc64fbsd_sigtramp_frame_this_id, sparc64fbsd_sigtramp_frame_this_id,
sparc64fbsd_sigtramp_frame_prev_register, sparc64fbsd_sigtramp_frame_prev_register,
NULL, NULL,
sparc64fbsd_sigtramp_frame_sniffer sparc64fbsd_sigtramp_frame_sniffer
}; );
static const struct regset sparc64fbsd_gregset = static const struct regset sparc64fbsd_gregset =

View File

@@ -223,16 +223,16 @@ sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind = static const struct frame_unwind_legacy sparc64nbsd_sigcontext_frame_unwind (
{
"sparc64 netbsd sigcontext", "sparc64 netbsd sigcontext",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc64nbsd_sigcontext_frame_this_id, sparc64nbsd_sigcontext_frame_this_id,
sparc64nbsd_sigcontext_frame_prev_register, sparc64nbsd_sigcontext_frame_prev_register,
NULL, NULL,
sparc64nbsd_sigtramp_frame_sniffer sparc64nbsd_sigtramp_frame_sniffer
}; );
static const struct regset sparc64nbsd_gregset = static const struct regset sparc64nbsd_gregset =

View File

@@ -220,16 +220,16 @@ sparc64obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind sparc64obsd_frame_unwind = static const struct frame_unwind_legacy sparc64obsd_frame_unwind (
{
"sparc64 openbsd sigtramp", "sparc64 openbsd sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc64obsd_frame_this_id, sparc64obsd_frame_this_id,
sparc64obsd_frame_prev_register, sparc64obsd_frame_prev_register,
NULL, NULL,
sparc64obsd_sigtramp_frame_sniffer sparc64obsd_sigtramp_frame_sniffer
}; );
/* Kernel debugging support. */ /* Kernel debugging support. */
@@ -304,16 +304,16 @@ sparc64obsd_trapframe_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind sparc64obsd_trapframe_unwind = static const struct frame_unwind_legacy sparc64obsd_trapframe_unwind (
{
"sparc64 openbsd trap", "sparc64 openbsd trap",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc64obsd_trapframe_this_id, sparc64obsd_trapframe_this_id,
sparc64obsd_trapframe_prev_register, sparc64obsd_trapframe_prev_register,
NULL, NULL,
sparc64obsd_trapframe_sniffer sparc64obsd_trapframe_sniffer
}; );
/* Threads support. */ /* Threads support. */

View File

@@ -183,16 +183,16 @@ sparc64_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
return sol2_sigtramp_p (this_frame); return sol2_sigtramp_p (this_frame);
} }
static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind = static const struct frame_unwind_legacy sparc64_sol2_sigtramp_frame_unwind (
{
"sparc64 solaris sigtramp", "sparc64 solaris sigtramp",
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc64_sol2_sigtramp_frame_this_id, sparc64_sol2_sigtramp_frame_this_id,
sparc64_sol2_sigtramp_frame_prev_register, sparc64_sol2_sigtramp_frame_prev_register,
NULL, NULL,
sparc64_sol2_sigtramp_frame_sniffer sparc64_sol2_sigtramp_frame_sniffer
}; );

View File

@@ -1134,16 +1134,16 @@ sparc64_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum); return frame_unwind_got_register (this_frame, regnum, regnum);
} }
static const struct frame_unwind sparc64_frame_unwind = static const struct frame_unwind_legacy sparc64_frame_unwind (
{
"sparc64 prologue", "sparc64 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
sparc64_frame_this_id, sparc64_frame_this_id,
sparc64_frame_prev_register, sparc64_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR

View File

@@ -0,0 +1,28 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2005-2023 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
typedef int (*callback_t) (void);
int
caller (callback_t callback)
{
/* Ensure some frame content to push away the return address. */
volatile const long one = 1;
/* Modify the return value to prevent any tail-call optimization. */
return (*callback) () - one;
}

View File

@@ -0,0 +1,32 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2005-2023 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
typedef int (*callback_t) (void);
extern int caller (callback_t callback);
int
callback (void)
{
return 1;
}
int
main (void)
{
return caller (callback);
}

View File

@@ -0,0 +1,91 @@
# Copyright 2010-2023 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Test that GDB can generate accurate backtraces even if some of the stack
# trace goes through a function with no debug information.
standard_testfile -caller.c -main.c
set objmainfile ${testfile}-main.o
set objcallerfile ${testfile}-caller.o
# recompile the inferior with or without CFI information, then run the
# inferior until the point where the important test starts
# returns TRUE on an ERROR.
proc prepare_test {has_cfi} {
global srcdir subdir srcfile srcfile2 objmainfile objcallerfile binfile
if {$has_cfi} {
set extension "cfi"
if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" ${objcallerfile} \
object [list {additional_flags=-fomit-frame-pointer \
-funwind-tables -fasynchronous-unwind-tables}]] != "" } {
untested "couldn't compile without cfi"
return true
}
} else {
set extension "no-cfi"
if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" ${objcallerfile} \
object [list {additional_flags=-fomit-frame-pointer \
-fno-unwind-tables \
-fno-asynchronous-unwind-tables}]] != "" } {
untested "couldn't compile with cfi"
return true
}
}
if {[gdb_compile "${objmainfile} ${objcallerfile}" \
"${binfile}-${extension}" binfile {}] != ""} {
untested "couldn't link object files"
return true
}
clean_restart "$binfile-${extension}"
if ![runto callback] then {
fail "has_cfi=$has_cfi: Can't run to callback"
return true
}
return false
}
if {[gdb_compile "${srcdir}/${subdir}/${srcfile2}" ${objmainfile} \
object {debug}] != "" } {
untested "couldn't compile main file"
return
}
if { [prepare_test false] } {
untested ${testfile}.exp
} else {
gdb_test_multiple "bt" "verify unwinding breaks without CFI" {
-re -wrap " in \[?\]\[?\] .*" {
# It may backtrace through some random frames even to main().
pass $gdb_test_name
}
-re -wrap " in main .*" {
fail $gdb_test_name
}
}
}
if { [prepare_test true] } {
untested ${testfile}.exp
} else {
# #0 callback () at ...
# #1 0x00000000004004e9 in caller ()
# #2 0x00000000004004cd in main () at ...
gdb_test "bt" \
"#0 +callback \[^\r\n\]+\r\n#1 \[^\r\n\]+ in caller \[^\r\n\]+\r\n#2 \[^\r\n\]+ in main \[^\r\n\]+" \
"verify unwinding works for CFI without DIEs"
}

View File

@@ -452,16 +452,16 @@ tic6x_frame_base_address (frame_info_ptr this_frame, void **this_cache)
return info->base; return info->base;
} }
static const struct frame_unwind tic6x_frame_unwind = static const struct frame_unwind_legacy tic6x_frame_unwind (
{
"tic6x prologue", "tic6x prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
tic6x_frame_this_id, tic6x_frame_this_id,
tic6x_frame_prev_register, tic6x_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static const struct frame_base tic6x_frame_base = static const struct frame_base tic6x_frame_base =
{ {
@@ -515,16 +515,16 @@ tic6x_stub_unwind_sniffer (const struct frame_unwind *self,
return 0; return 0;
} }
static const struct frame_unwind tic6x_stub_unwind = static const struct frame_unwind_legacy tic6x_stub_unwind (
{
"tic6x stub", "tic6x stub",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
tic6x_stub_this_id, tic6x_stub_this_id,
tic6x_frame_prev_register, tic6x_frame_prev_register,
NULL, NULL,
tic6x_stub_unwind_sniffer tic6x_stub_unwind_sniffer
}; );
/* Return the instruction on address PC. */ /* Return the instruction on address PC. */

View File

@@ -900,16 +900,17 @@ tilegx_frame_base_address (frame_info_ptr this_frame, void **this_cache)
return cache->base; return cache->base;
} }
static const struct frame_unwind tilegx_frame_unwind = { static const struct frame_unwind_legacy tilegx_frame_unwind (
"tilegx prologue", "tilegx prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
tilegx_frame_this_id, tilegx_frame_this_id,
tilegx_frame_prev_register, tilegx_frame_prev_register,
NULL, /* const struct frame_data *unwind_data */ NULL, /* const struct frame_data *unwind_data */
default_frame_sniffer, /* frame_sniffer_ftype *sniffer */ default_frame_sniffer, /* frame_sniffer_ftype *sniffer */
NULL /* frame_prev_pc_ftype *prev_pc */ NULL /* frame_prev_pc_ftype *prev_pc */
}; );
static const struct frame_base tilegx_frame_base = { static const struct frame_base tilegx_frame_base = {
&tilegx_frame_unwind, &tilegx_frame_unwind,

View File

@@ -58,6 +58,7 @@ tramp_frame_cache (frame_info_ptr this_frame,
} }
static void static void
__attribute__ ((__used__))
tramp_frame_this_id (frame_info_ptr this_frame, tramp_frame_this_id (frame_info_ptr this_frame,
void **this_cache, void **this_cache,
struct frame_id *this_id) struct frame_id *this_id)
@@ -69,6 +70,7 @@ tramp_frame_this_id (frame_info_ptr this_frame,
} }
static struct value * static struct value *
__attribute__ ((__used__))
tramp_frame_prev_register (frame_info_ptr this_frame, tramp_frame_prev_register (frame_info_ptr this_frame,
void **this_cache, void **this_cache,
int prev_regnum) int prev_regnum)
@@ -80,6 +82,7 @@ tramp_frame_prev_register (frame_info_ptr this_frame,
} }
static CORE_ADDR static CORE_ADDR
__attribute__ ((__used__))
tramp_frame_start (const struct tramp_frame *tramp, tramp_frame_start (const struct tramp_frame *tramp,
frame_info_ptr this_frame, CORE_ADDR pc) frame_info_ptr this_frame, CORE_ADDR pc)
{ {
@@ -120,11 +123,12 @@ tramp_frame_start (const struct tramp_frame *tramp,
} }
static int static int
__attribute__ ((__used__))
tramp_frame_sniffer (const struct frame_unwind *self, tramp_frame_sniffer (const struct frame_unwind *self,
frame_info_ptr this_frame, frame_info_ptr this_frame,
void **this_cache) void **this_cache)
{ {
const struct tramp_frame *tramp = self->unwind_data->tramp_frame; const struct tramp_frame *tramp = self->unwind_data ()->tramp_frame;
CORE_ADDR pc = get_frame_pc (this_frame); CORE_ADDR pc = get_frame_pc (this_frame);
CORE_ADDR func; CORE_ADDR func;
struct tramp_frame_cache *tramp_cache; struct tramp_frame_cache *tramp_cache;
@@ -143,6 +147,39 @@ tramp_frame_sniffer (const struct frame_unwind *self,
return 1; return 1;
} }
class frame_unwind_trampoline : public frame_unwind {
private:
frame_prev_arch_ftype *prev_arch_p;
public:
frame_unwind_trampoline (enum frame_type t, const struct frame_data *d,
frame_prev_arch_ftype *pa)
: frame_unwind ("trampoline", t, FRAME_UNWIND_GDB, d), prev_arch_p (pa)
{ }
int sniffer(const frame_unwind *self, frame_info_ptr this_frame,
void **this_prologue_cache) const override
{
return tramp_frame_sniffer (self, this_frame, this_prologue_cache);
}
void this_id (frame_info_ptr this_frame, void **this_prologue_cache,
struct frame_id *id) const override
{
tramp_frame_this_id (this_frame, this_prologue_cache, id);
}
struct value *prev_register (frame_info_ptr this_frame,
void **this_prologue_cache,
int regnum) const override
{
return tramp_frame_prev_register (this_frame, this_prologue_cache, regnum);
}
struct gdbarch *prev_arch (frame_info_ptr this_frame,
void **this_prologue_cache) const override
{
return prev_arch_p (this_frame, this_prologue_cache);
}
};
void void
tramp_frame_prepend_unwinder (struct gdbarch *gdbarch, tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
const struct tramp_frame *tramp_frame) const struct tramp_frame *tramp_frame)
@@ -161,15 +198,11 @@ tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
gdb_assert (tramp_frame->insn_size <= sizeof (tramp_frame->insn[0].bytes)); gdb_assert (tramp_frame->insn_size <= sizeof (tramp_frame->insn[0].bytes));
data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data); data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
unwinder = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
data->tramp_frame = tramp_frame; data->tramp_frame = tramp_frame;
unwinder->type = tramp_frame->frame_type;
unwinder->unwind_data = data; unwinder = obstack_new <frame_unwind_trampoline> (gdbarch_obstack (gdbarch),
unwinder->sniffer = tramp_frame_sniffer; tramp_frame->frame_type,
unwinder->stop_reason = default_frame_unwind_stop_reason; data,
unwinder->this_id = tramp_frame_this_id; tramp_frame->prev_arch);
unwinder->prev_register = tramp_frame_prev_register;
unwinder->prev_arch = tramp_frame->prev_arch;
frame_unwind_prepend_unwinder (gdbarch, unwinder); frame_unwind_prepend_unwinder (gdbarch, unwinder);
} }

View File

@@ -1320,15 +1320,16 @@ v850_frame_this_id (frame_info_ptr this_frame, void **this_cache,
*this_id = frame_id_build (cache->saved_regs[E_SP_REGNUM].addr (), cache->pc); *this_id = frame_id_build (cache->saved_regs[E_SP_REGNUM].addr (), cache->pc);
} }
static const struct frame_unwind v850_frame_unwind = { static const struct frame_unwind_legacy v850_frame_unwind (
"v850 prologue", "v850 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
v850_frame_this_id, v850_frame_this_id,
v850_frame_prev_register, v850_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
v850_frame_base_address (frame_info_ptr this_frame, void **this_cache) v850_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -386,16 +386,16 @@ vax_frame_prev_register (frame_info_ptr this_frame,
return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum); return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
} }
static const struct frame_unwind vax_frame_unwind = static const struct frame_unwind_legacy vax_frame_unwind (
{
"vax prologue", "vax prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
vax_frame_this_id, vax_frame_this_id,
vax_frame_prev_register, vax_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR

View File

@@ -728,15 +728,16 @@ xstormy16_frame_base_address (frame_info_ptr this_frame, void **this_cache)
return cache->base; return cache->base;
} }
static const struct frame_unwind xstormy16_frame_unwind = { static const struct frame_unwind_legacy xstormy16_frame_unwind (
"xstormy16 prologue", "xstormy16 prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
xstormy16_frame_this_id, xstormy16_frame_this_id,
xstormy16_frame_prev_register, xstormy16_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static const struct frame_base xstormy16_frame_base = { static const struct frame_base xstormy16_frame_base = {
&xstormy16_frame_unwind, &xstormy16_frame_unwind,

View File

@@ -1496,17 +1496,17 @@ xtensa_frame_prev_register (frame_info_ptr this_frame,
} }
static const struct frame_unwind static const struct frame_unwind_legacy
xtensa_unwind = xtensa_unwind (
{
"xtensa prologue", "xtensa prologue",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
xtensa_frame_this_id, xtensa_frame_this_id,
xtensa_frame_prev_register, xtensa_frame_prev_register,
NULL, NULL,
default_frame_sniffer default_frame_sniffer
}; );
static CORE_ADDR static CORE_ADDR
xtensa_frame_base_address (frame_info_ptr this_frame, void **this_cache) xtensa_frame_base_address (frame_info_ptr this_frame, void **this_cache)

View File

@@ -1063,11 +1063,10 @@ z80_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
return 0; return 0;
} }
static const struct frame_unwind static const struct frame_unwind_legacy z80_frame_unwind (
z80_frame_unwind =
{
"z80", "z80",
NORMAL_FRAME, NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason, default_frame_unwind_stop_reason,
z80_frame_this_id, z80_frame_this_id,
z80_frame_prev_register, z80_frame_prev_register,
@@ -1075,7 +1074,7 @@ z80_frame_unwind =
default_frame_sniffer default_frame_sniffer
/*dealloc_cache*/ /*dealloc_cache*/
/*prev_arch*/ /*prev_arch*/
}; );
/* Initialize the gdbarch struct for the Z80 arch */ /* Initialize the gdbarch struct for the Z80 arch */
static struct gdbarch * static struct gdbarch *