#include "frame.h"
#include "target.h"
#include "value.h"
-#include "inferior.h" /* for inferior_ptid */
+#include "inferior.h"
#include "regcache.h"
#include "user-regs.h"
#include "gdbsupport/gdb_obstack.h"
#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
/* Deletion function for the frame cache hash table. */
static void
-frame_info_del (void *frame_v)
+frame_info_del (frame_info *frame)
{
- frame_info *frame = (frame_info *) frame_v;
-
if (frame->prologue_cache != nullptr
&& frame->unwind->dealloc_cache != nullptr)
frame->unwind->dealloc_cache (frame, frame->prologue_cache);
static void
frame_stash_create (void)
{
- frame_stash = htab_create (100,
- frame_addr_hash,
- frame_addr_hash_eq,
- frame_info_del);
+ frame_stash = htab_create
+ (100, frame_addr_hash, frame_addr_hash_eq,
+ [] (void *p)
+ {
+ auto frame = static_cast<frame_info *> (p);
+ frame_info_del (frame);
+ });
}
/* Internal function to add a frame to the frame_stash hash table.
/* This will return true if LB and RB are the same block, or
if the block with the smaller depth lexically encloses the
block with the greater depth. */
- inner = contained_in (lb, rb);
+ inner = rb->contains (lb);
}
else
/* Only return non-zero when strictly inner than. Note that, per
and get_prev_frame performs a series of checks that are relatively
expensive). This optimization is particularly useful when this function
is called from another function (such as value_fetch_lazy, case
- VALUE_LVAL (val) == lval_register) which already loops over all frames,
+ val->lval () == lval_register) which already loops over all frames,
making the overall behavior O(n^2). */
frame = frame_stash_find (id);
if (frame)
*optimizedp = value->optimized_out ();
*unavailablep = !value->entirely_available ();
- *lvalp = VALUE_LVAL (value);
+ *lvalp = value->lval ();
*addrp = value->address ();
if (*lvalp == lval_register)
*realnump = VALUE_REGNUM (value);
}
else
{
- if (VALUE_LVAL (value) == lval_register)
+ if (value->lval () == lval_register)
gdb_printf (&debug_file, " register=%d",
VALUE_REGNUM (value));
- else if (VALUE_LVAL (value) == lval_memory)
+ else if (value->lval () == lval_memory)
gdb_printf (&debug_file, " address=%s",
paddress (gdbarch,
value->address ()));
static frame_id selected_frame_id = null_frame_id;
static int selected_frame_level = -1;
+/* See frame.h. This definition should come before any definition of a static
+ frame_info_ptr, to ensure that frame_list is destroyed after any static
+ frame_info_ptr. This is necessary because the destructor of frame_info_ptr
+ uses frame_list. */
+
+intrusive_list<frame_info_ptr> frame_info_ptr::frame_list;
+
/* The cached frame_info object pointing to the selected frame.
Looked up on demand by get_selected_frame. */
static frame_info_ptr selected_frame;
invalidate_selected_frame ();
/* Invalidate cache. */
- sentinel_frame = NULL;
+ if (sentinel_frame != nullptr)
+ {
+ /* If frame 0's id is not computed, it is not in the frame stash, so its
+ dealloc functions will not be called when emptying the frame stash.
+ Call frame_info_del manually in that case. */
+ frame_info *current_frame = sentinel_frame->prev;
+ if (current_frame != nullptr
+ && current_frame->this_id.p == frame_id_status::NOT_COMPUTED)
+ frame_info_del (current_frame);
+
+ sentinel_frame = nullptr;
+ }
+
frame_stash_invalidate ();
/* Since we can't really be sure what the first object allocated was. */
if (current_program_space->symfile_object_file == nullptr)
return false;
- CORE_ADDR sym_addr;
+ CORE_ADDR sym_addr = 0;
const char *name = main_name ();
bound_minimal_symbol msymbol
= lookup_minimal_symbol (name, NULL,
current_program_space->symfile_object_file);
- if (msymbol.minsym == nullptr)
+
+ if (msymbol.minsym != nullptr)
+ sym_addr = msymbol.value_address ();
+
+ /* Favor a full symbol in Fortran, for the case where the Fortran main
+ is also called "main". */
+ if (msymbol.minsym == nullptr
+ || get_frame_language (this_frame) == language_fortran)
{
/* In some language (for example Fortran) there will be no minimal
symbol with the name of the main function. In this case we should
search the full symbols to see if we can find a match. */
struct block_symbol bs = lookup_symbol (name, NULL, VAR_DOMAIN, 0);
- if (bs.symbol == nullptr)
- return false;
- const struct block *block = bs.symbol->value_block ();
- gdb_assert (block != nullptr);
- sym_addr = block->start ();
+ /* We might have found some unrelated symbol. For example, the
+ Rust compiler can emit both a subprogram and a namespace with
+ the same name in the same scope; and due to how gdb's symbol
+ tables currently work, we can't request the one we'd
+ prefer. */
+ if (bs.symbol != nullptr && bs.symbol->aclass () == LOC_BLOCK)
+ {
+ const struct block *block = bs.symbol->value_block ();
+ gdb_assert (block != nullptr);
+ sym_addr = block->start ();
+ }
+ else if (msymbol.minsym == nullptr)
+ return false;
}
- else
- sym_addr = msymbol.value_address ();
/* Convert any function descriptor addresses into the actual function
code address. */
- sym_addr = gdbarch_convert_from_func_ptr_addr
- (get_frame_arch (this_frame), sym_addr, current_inferior ()->top_target ());
+ sym_addr = (gdbarch_convert_from_func_ptr_addr
+ (get_frame_arch (this_frame), sym_addr,
+ current_inferior ()->top_target ()));
return sym_addr == get_frame_func (this_frame);
}
}
/* Return a structure containing various interesting information about
- the frame that called THIS_FRAME. Returns NULL if there is entier
+ the frame that called THIS_FRAME. Returns NULL if there is either
no such frame or the frame fails any of a set of target-independent
condition that should terminate the frame chain (e.g., as unwinding
past main()).
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
/* See frame-info-ptr.h. */
-intrusive_list<frame_info_ptr> frame_info_ptr::frame_list;
-
-/* See frame-info-ptr.h. */
-
frame_info_ptr::frame_info_ptr (struct frame_info *ptr)
: m_ptr (ptr)
{