diff options
author | Tom Tromey <tromey@adacore.com> | 2023-10-24 07:59:51 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2023-11-14 08:43:34 -0700 |
commit | 19b83d5c9bac1db207dce26859c6ca84135615b0 (patch) | |
tree | cde40bf66217cda28eb1b5f2d7f2da55a6296ff1 /gdb/frame.c | |
parent | ba707cadae18a7cc8bb47a736d3d0438d44262a9 (diff) | |
download | binutils-19b83d5c9bac1db207dce26859c6ca84135615b0.zip binutils-19b83d5c9bac1db207dce26859c6ca84135615b0.tar.gz binutils-19b83d5c9bac1db207dce26859c6ca84135615b0.tar.bz2 |
Move follow_static_link to frame.c
This moves the follow_static_link function to frame.c and exports it
for use elsewhere. The API is changed slightly to make it more
generically useful.
Diffstat (limited to 'gdb/frame.c')
-rw-r--r-- | gdb/frame.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/gdb/frame.c b/gdb/frame.c index 7077016..4a46ccb 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -43,6 +43,7 @@ #include "hashtab.h" #include "valprint.h" #include "cli/cli-option.h" +#include "dwarf2/loc.h" /* The sentinel frame terminates the innermost end of the frame chain. If unwound, it returns the information needed to construct an @@ -3120,6 +3121,45 @@ get_frame_sp (frame_info_ptr this_frame) return gdbarch_unwind_sp (gdbarch, frame_info_ptr (this_frame->next)); } +/* See frame.h. */ + +frame_info_ptr +frame_follow_static_link (frame_info_ptr frame) +{ + const block *frame_block = get_frame_block (frame, nullptr); + frame_block = frame_block->function_block (); + + const struct dynamic_prop *static_link = frame_block->static_link (); + if (static_link == nullptr) + return {}; + + CORE_ADDR upper_frame_base; + + if (!dwarf2_evaluate_property (static_link, frame, NULL, &upper_frame_base)) + return {}; + + /* Now climb up the stack frame until we reach the frame we are interested + in. */ + for (; frame != nullptr; frame = get_prev_frame (frame)) + { + struct symbol *framefunc = get_frame_function (frame); + + /* Stacks can be quite deep: give the user a chance to stop this. */ + QUIT; + + /* If we don't know how to compute FRAME's base address, don't give up: + maybe the frame we are looking for is upper in the stack frame. */ + if (framefunc != NULL + && SYMBOL_BLOCK_OPS (framefunc) != NULL + && SYMBOL_BLOCK_OPS (framefunc)->get_frame_base != NULL + && (SYMBOL_BLOCK_OPS (framefunc)->get_frame_base (framefunc, frame) + == upper_frame_base)) + break; + } + + return frame; +} + /* Return the reason why we can't unwind past FRAME. */ enum unwind_stop_reason |