mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
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.
This commit is contained in:
parent
ba707cadae
commit
19b83d5c9b
@ -31,7 +31,6 @@
|
||||
#include "block.h"
|
||||
#include "objfiles.h"
|
||||
#include "language.h"
|
||||
#include "dwarf2/loc.h"
|
||||
#include "gdbsupport/selftest.h"
|
||||
|
||||
/* Basic byte-swapping routines. All 'extract' functions return a
|
||||
@ -391,41 +390,6 @@ symbol_read_needs_frame (struct symbol *sym)
|
||||
return symbol_read_needs (sym) == SYMBOL_NEEDS_FRAME;
|
||||
}
|
||||
|
||||
/* Given static link expression and the frame it lives in, look for the frame
|
||||
the static links points to and return it. Return NULL if we could not find
|
||||
such a frame. */
|
||||
|
||||
static frame_info_ptr
|
||||
follow_static_link (frame_info_ptr frame,
|
||||
const struct dynamic_prop *static_link)
|
||||
{
|
||||
CORE_ADDR upper_frame_base;
|
||||
|
||||
if (!dwarf2_evaluate_property (static_link, frame, NULL, &upper_frame_base))
|
||||
return NULL;
|
||||
|
||||
/* Now climb up the stack frame until we reach the frame we are interested
|
||||
in. */
|
||||
for (; frame != NULL; 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;
|
||||
}
|
||||
|
||||
/* Assuming VAR is a symbol that can be reached from FRAME thanks to lexical
|
||||
rules, look for the frame that is actually hosting VAR and return it. If,
|
||||
for some reason, we found no such frame, return NULL.
|
||||
@ -494,25 +458,14 @@ get_hosting_frame (struct symbol *var, const struct block *var_block,
|
||||
/* Assuming we have a block for this frame: if we are at the function
|
||||
level, the immediate upper lexical block is in an outer function:
|
||||
follow the static link. */
|
||||
else if (frame_block->function ())
|
||||
else if (frame_block->function () != nullptr)
|
||||
{
|
||||
const struct dynamic_prop *static_link
|
||||
= frame_block->static_link ();
|
||||
int could_climb_up = 0;
|
||||
|
||||
if (static_link != NULL)
|
||||
frame = frame_follow_static_link (frame);
|
||||
if (frame != nullptr)
|
||||
{
|
||||
frame = follow_static_link (frame, static_link);
|
||||
if (frame != NULL)
|
||||
{
|
||||
frame_block = get_frame_block (frame, NULL);
|
||||
could_climb_up = frame_block != NULL;
|
||||
}
|
||||
}
|
||||
if (!could_climb_up)
|
||||
{
|
||||
frame = NULL;
|
||||
break;
|
||||
frame_block = get_frame_block (frame, nullptr);
|
||||
if (frame_block == nullptr)
|
||||
frame = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
40
gdb/frame.c
40
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
|
||||
|
@ -640,6 +640,13 @@ class address_space;
|
||||
/* Return the frame's address space. */
|
||||
extern const address_space *get_frame_address_space (frame_info_ptr);
|
||||
|
||||
/* A frame may have a "static link". That is, in some languages, a
|
||||
nested function may have access to variables from the enclosing
|
||||
block and frame. This function looks for a frame's static link.
|
||||
If found, returns the corresponding frame; otherwise, returns a
|
||||
null frame_info_ptr. */
|
||||
extern frame_info_ptr frame_follow_static_link (frame_info_ptr frame);
|
||||
|
||||
/* For frames where we can not unwind further, describe why. */
|
||||
|
||||
enum unwind_stop_reason
|
||||
|
Loading…
Reference in New Issue
Block a user