diff options
Diffstat (limited to 'gdb/frame.c')
-rw-r--r-- | gdb/frame.c | 74 |
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); |