aboutsummaryrefslogtreecommitdiff
path: root/gdb/frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/frame.c')
-rw-r--r--gdb/frame.c74
1 files changed, 42 insertions, 32 deletions
diff --git a/gdb/frame.c b/gdb/frame.c
index a6900b2..fc4cbca 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1,6 +1,6 @@
/* Cache and manage frames for GDB, the GNU debugger.
- Copyright (C) 1986-2024 Free Software Foundation, Inc.
+ Copyright (C) 1986-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -25,7 +25,6 @@
#include "inferior.h"
#include "regcache.h"
#include "user-regs.h"
-#include "gdbsupport/gdb_obstack.h"
#include "dummy-frame.h"
#include "sentinel-frame.h"
#include "gdbcore.h"
@@ -269,12 +268,10 @@ frame_addr_hash_eq (const void *a, const void *b)
static void
frame_info_del (frame_info *frame)
{
- if (frame->prologue_cache != nullptr
- && frame->unwind->dealloc_cache != nullptr)
+ if (frame->prologue_cache != nullptr)
frame->unwind->dealloc_cache (frame, frame->prologue_cache);
- if (frame->base_cache != nullptr
- && frame->base->unwind->dealloc_cache != nullptr)
+ if (frame->base_cache != nullptr)
frame->base->unwind->dealloc_cache (frame, frame->base_cache);
}
@@ -487,12 +484,12 @@ frame_info::to_string () const
res += string_printf ("{level=%d,", fi->level);
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
res += "type=<unknown>,";
if (fi->unwind != NULL)
- res += string_printf ("unwinder=\"%s\",", fi->unwind->name);
+ res += string_printf ("unwinder=\"%s\",", fi->unwind->name ());
else
res += "unwinder=<unknown>,";
@@ -1112,7 +1109,7 @@ frame_save_as_regcache (const frame_info_ptr &this_frame)
{
auto cooked_read = [this_frame] (int regnum, gdb::array_view<gdb_byte> buf)
{
- if (!deprecated_frame_register_read (this_frame, regnum, buf.data ()))
+ if (!deprecated_frame_register_read (this_frame, regnum, buf))
return REG_UNAVAILABLE;
else
return REG_VALID;
@@ -1177,17 +1174,17 @@ void
frame_register_unwind (const frame_info_ptr &next_frame, int regnum,
int *optimizedp, int *unavailablep,
enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *bufferp)
+ int *realnump,
+ gdb::array_view<gdb_byte> buffer)
{
struct value *value;
- /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates
+ /* Require all but BUFFER to be valid. An empty BUFFER indicates
that the value proper does not need to be fetched. */
gdb_assert (optimizedp != NULL);
gdb_assert (lvalp != NULL);
gdb_assert (addrp != NULL);
gdb_assert (realnump != NULL);
- /* gdb_assert (bufferp != NULL); */
value = frame_unwind_register_value (next_frame, regnum);
@@ -1202,13 +1199,15 @@ frame_register_unwind (const frame_info_ptr &next_frame, int regnum,
else
*realnump = -1;
- if (bufferp)
+ if (!buffer.empty ())
{
+ gdb_assert (buffer.size () >= value->type ()->length ());
+
if (!*optimizedp && !*unavailablep)
- memcpy (bufferp, value->contents_all ().data (),
+ memcpy (buffer.data (), value->contents_all ().data (),
value->type ()->length ());
else
- memset (bufferp, 0, value->type ()->length ());
+ memset (buffer.data (), 0, value->type ()->length ());
}
/* Dispose of the new value. This prevents watchpoints from
@@ -1217,7 +1216,8 @@ frame_register_unwind (const frame_info_ptr &next_frame, int regnum,
}
void
-frame_unwind_register (const frame_info_ptr &next_frame, int regnum, gdb_byte *buf)
+frame_unwind_register (const frame_info_ptr &next_frame, int regnum,
+ gdb::array_view<gdb_byte> buf)
{
int optimized;
int unavailable;
@@ -1238,7 +1238,7 @@ frame_unwind_register (const frame_info_ptr &next_frame, int regnum, gdb_byte *b
void
get_frame_register (const frame_info_ptr &frame,
- int regnum, gdb_byte *buf)
+ int regnum, gdb::array_view<gdb_byte> buf)
{
frame_unwind_register (frame_info_ptr (frame->next), regnum, buf);
}
@@ -1447,7 +1447,7 @@ put_frame_register (const frame_info_ptr &next_frame, int regnum,
gdb_assert (buf.size () == size);
frame_register_unwind (next_frame, regnum, &optim, &unavail, &lval, &addr,
- &realnum, nullptr);
+ &realnum);
if (optim)
error (_("Attempt to assign to a register that was not saved."));
switch (lval)
@@ -1482,7 +1482,7 @@ put_frame_register (const frame_info_ptr &next_frame, int regnum,
bool
deprecated_frame_register_read (const frame_info_ptr &frame, int regnum,
- gdb_byte *myaddr)
+ gdb::array_view<gdb_byte> myaddr)
{
int optimized;
int unavailable;
@@ -1541,7 +1541,7 @@ get_frame_register_bytes (const frame_info_ptr &next_frame, int regnum,
int realnum;
frame_register_unwind (next_frame, regnum, optimizedp, unavailablep,
- &lval, &addr, &realnum, buffer.data ());
+ &lval, &addr, &realnum, buffer);
if (*optimizedp || *unavailablep)
return false;
}
@@ -2159,7 +2159,7 @@ frame_register_unwind_location (const frame_info_ptr &initial_this_frame,
int unavailable;
frame_register_unwind (this_frame, regnum, optimizedp, &unavailable,
- lvalp, addrp, realnump, NULL);
+ lvalp, addrp, realnump);
if (*optimizedp)
break;
@@ -2325,7 +2325,22 @@ get_prev_frame_always_1 (const frame_info_ptr &this_frame)
until we have unwound all the way down to the previous non-inline
frame. */
if (get_frame_type (this_frame) == INLINE_FRAME)
- return get_prev_frame_maybe_check_cycle (this_frame);
+ {
+ frame_info_ptr fi = get_prev_frame_maybe_check_cycle (this_frame);
+
+ /* If this_frame is the current frame, then compute and stash its frame
+ id so that the cycle check in get_prev_frame_maybe_check_cycle works
+ correctly in the case where inline frame 0 has been duplicated.
+
+ The this_id.p check is required to avoid recursion as computing the
+ frame id results in a call to inline_frame_this_id which calls back
+ into get_prev_frame_always. */
+ if (this_frame->level == 0
+ && this_frame->this_id.p != frame_id_status::COMPUTING)
+ get_frame_id (this_frame);
+
+ return fi;
+ }
/* If this_frame is the current frame, then compute and stash its
frame id prior to fetching and computing the frame id of the
@@ -2363,7 +2378,7 @@ get_prev_frame_always_1 (const frame_info_ptr &this_frame)
This check is valid only if this frame and the next frame are NORMAL.
See the comment at frame_id_inner for details. */
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)),
get_frame_id (this_frame),
get_frame_id (frame_info_ptr (this_frame->next))))
@@ -2991,7 +3006,7 @@ get_frame_type (const frame_info_ptr &frame)
/* Initialize the frame's unwinder because that's what
provides the frame's type. */
frame_unwind_find_by_frame (frame, &frame->prologue_cache);
- return frame->unwind->type;
+ return frame->unwind->type ();
}
struct program_space *
@@ -3072,11 +3087,8 @@ frame_unwind_arch (const frame_info_ptr &next_frame)
if (next_frame->unwind == NULL)
frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache);
- if (next_frame->unwind->prev_arch != NULL)
- arch = next_frame->unwind->prev_arch (next_frame,
- &next_frame->prologue_cache);
- else
- arch = get_frame_arch (next_frame);
+ arch = next_frame->unwind->prev_arch (next_frame,
+ &next_frame->prologue_cache);
next_frame->prev_arch.arch = arch;
next_frame->prev_arch.p = true;
@@ -3412,9 +3424,7 @@ frame_info_ptr::reinflate () const
return m_ptr;
}
-void _initialize_frame ();
-void
-_initialize_frame ()
+INIT_GDB_FILE (frame)
{
obstack_init (&frame_cache_obstack);