0 for innermost, 1 for its caller, ...
or -1 for frame specified by address with no defined level. */
-/* FIXME: cagney/2002-04-21: The variable `selected_frame_level' is
- deprecated. It will dissapear `real soon now'. */
-
-int selected_frame_level; /* DEPRECATED */
-
/* Level of the selected frame: 0 for innermost, 1 for its caller, ...
or -1 for NULL frame. */
print_frame (fi, level, source, args, sal);
source_print = (source == SRC_LINE || source == SRC_AND_LOC);
+ if (sal.symtab)
+ {
+ current_source_symtab = sal.symtab;
+ current_source_line = sal.line;
+ }
if (source_print && sal.symtab)
{
if (!done)
{
if (print_frame_info_listing_hook)
- {
- print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
- current_source_symtab = sal.symtab;
- }
+ print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
else
{
/* We used to do this earlier, but that is clearly
stb = ui_out_stream_new (uiout);
old_chain = make_cleanup_ui_out_stream_delete (stb);
- func = find_pc_function (fi->pc);
+ func = find_pc_function (frame_address_in_block (fi));
if (func)
{
/* In certain pathological cases, the symtabs give the wrong
ever changed many parts of GDB will need to be changed (and we'll
create a find_pc_minimal_function or some such). */
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (frame_address_in_block (fi));
if (msymbol != NULL
&& (SYMBOL_VALUE_ADDRESS (msymbol)
> BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
}
else
{
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
+ struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (frame_address_in_block (fi));
if (msymbol != NULL)
{
funname = SYMBOL_NAME (msymbol);
}
}
- FRAME_INIT_SAVED_REGS (fi);
- if (fi->saved_regs != NULL)
- {
- /* The sp is special; what's returned isn't the save address, but
- actually the value of the previous frame's sp. */
- printf_filtered (" Previous frame's sp is ");
- print_address_numeric (fi->saved_regs[SP_REGNUM], 1, gdb_stdout);
- printf_filtered ("\n");
- count = 0;
- numregs = NUM_REGS + NUM_PSEUDO_REGS;
- for (i = 0; i < numregs; i++)
- if (fi->saved_regs[i] && i != SP_REGNUM)
+ if (fi->saved_regs == NULL)
+ FRAME_INIT_SAVED_REGS (fi);
+ /* Print as much information as possible on the location of all the
+ registers. */
+ {
+ enum lval_type lval;
+ int optimized;
+ CORE_ADDR addr;
+ int realnum;
+ int count;
+ int i;
+ int need_nl = 1;
+
+ /* The sp is special; what's displayed isn't the save address, but
+ the value of the previous frame's sp. This is a legacy thing,
+ at one stage the frame cached the previous frame's SP instead
+ of its address, hence it was easiest to just display the cached
+ value. */
+ if (SP_REGNUM >= 0)
+ {
+ /* Find out the location of the saved stack pointer with out
+ actually evaluating it. */
+ frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr,
+ &realnum, NULL);
+ if (!optimized && lval == not_lval)
{
- if (count == 0)
- puts_filtered (" Saved registers:\n ");
- else
- puts_filtered (",");
- wrap_here (" ");
- printf_filtered (" %s at ", REGISTER_NAME (i));
- print_address_numeric (fi->saved_regs[i], 1, gdb_stdout);
- count++;
+ void *value = alloca (MAX_REGISTER_RAW_SIZE);
+ CORE_ADDR sp;
+ frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr,
+ &realnum, value);
+ sp = extract_address (value, REGISTER_RAW_SIZE (SP_REGNUM));
+ printf_filtered (" Previous frame's sp is ");
+ print_address_numeric (sp, 1, gdb_stdout);
+ printf_filtered ("\n");
+ need_nl = 0;
}
- if (count)
- puts_filtered ("\n");
- }
- else
- {
- /* We could get some information about saved registers by
- calling get_saved_register on each register. Which info goes
- with which frame is necessarily lost, however, and I suspect
- that the users don't care whether they get the info. */
+ else if (!optimized && lval == lval_memory)
+ {
+ printf_filtered (" Previous frame's sp at ");
+ print_address_numeric (addr, 1, gdb_stdout);
+ printf_filtered ("\n");
+ need_nl = 0;
+ }
+ else if (!optimized && lval == lval_register)
+ {
+ printf_filtered (" Previous frame's sp in %s\n",
+ REGISTER_NAME (realnum));
+ need_nl = 0;
+ }
+ /* else keep quiet. */
+ }
+
+ count = 0;
+ numregs = NUM_REGS + NUM_PSEUDO_REGS;
+ for (i = 0; i < numregs; i++)
+ if (i != SP_REGNUM)
+ {
+ /* Find out the location of the saved register without
+ fetching the corresponding value. */
+ frame_register_unwind (fi, i, &optimized, &lval, &addr, &realnum,
+ NULL);
+ /* For moment, only display registers that were saved on the
+ stack. */
+ if (!optimized && lval == lval_memory)
+ {
+ if (count == 0)
+ puts_filtered (" Saved registers:\n ");
+ else
+ puts_filtered (",");
+ wrap_here (" ");
+ printf_filtered (" %s at ", REGISTER_NAME (i));
+ print_address_numeric (addr, 1, gdb_stdout);
+ count++;
+ }
+ }
+ if (count || need_nl)
puts_filtered ("\n");
- }
+ }
}
#if 0
fi = get_prev_frame (fi))
{
QUIT;
- ps = find_pc_psymtab (fi->pc);
+ ps = find_pc_psymtab (frame_address_in_block (fi));
if (ps)
PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in */
}
}
\f
-/* Select frame FI, and note that its stack level is LEVEL.
- LEVEL may be -1 if an actual level number is not known. */
+/* Select frame FI (or NULL - to invalidate the current frame). */
void
-select_frame (struct frame_info *fi, int level)
+select_frame (struct frame_info *fi)
{
register struct symtab *s;
selected_frame = fi;
- /* FIXME: cagney/2002-04-21: The variable `selected_frame_level' is
- deprecated. It will dissapear `real soon now'. */
- selected_frame_level = level; /* DEPRECATED */
- /* FIXME: cagney/2002-04-05: It can't be this easy (and looking at
- the increasingly complex list of checkes, it wasn't)! GDB is
- dragging around, and constantly updating, the global variable
- selected_frame_level. Surely all that was needed was for the
- level to be computed direct from the frame (by counting back to
- the inner-most frame) or, as has been done here using a cached
- value. For moment, check that the expected and the actual level
- are consistent. If, after a few weeks, no one reports that this
- assertion has failed, the global selected_frame_level and many
- many parameters can all be deleted. */
- if (fi == NULL && level == -1)
- /* Ok. The target is clearing the selected frame as part of a
- cache flush. */
- ;
- else if (fi != NULL && fi->level == level)
- /* Ok. What you would expect. Level is redundant. */
- ;
- else if (fi != NULL && level == -1)
- /* Ok. See breakpoint.c. The watchpoint code changes the
- selected frame to the frame that contains the watchpoint and
- then, later changes it back to the old value. The -1 is used
- as a marker so that the watchpoint code can easily detect that
- things are not what they should be. Why the watchpoint code
- can't mindlessly save/restore the selected frame I don't know,
- hopefully it can be simplified that way. Hopefully the global
- selected_frame can be replaced by a frame parameter, making
- still more simplification possible. */
- ;
- else
- internal_error (__FILE__, __LINE__,
- "Conflicting frame levels fi->level=%d, level=%d",
- (fi ? fi->level : -1),
- level);
+ /* NOTE: cagney/2002-05-04: FI can be NULL. This occures when the
+ frame is being invalidated. */
if (selected_frame_level_changed_hook)
- selected_frame_level_changed_hook (level);
+ selected_frame_level_changed_hook (frame_relative_level (fi));
+
+ /* FIXME: kseitz/2002-08-28: It would be nice to call
+ selected_frame_level_changed_event right here, but due to limitations
+ in the current interfaces, we would end up flooding UIs with events
+ because select_frame is used extensively internally.
+
+ Once we have frame-parameterized frame (and frame-related) commands,
+ the event notification can be moved here, since this function will only
+ be called when the users selected frame is being changed. */
/* Ensure that symbols for this frame are read in. Also, determine the
source language of this frame, and switch to it if desired. */
}
\f
-/* Select frame FI, noting that its stack level is LEVEL. Also print
- the stack frame and show the source if this is the tui version. */
-void
-select_and_print_frame (struct frame_info *fi, int level)
+/* Select frame FI. Also print the stack frame and show the source if
+ this is the tui version. */
+static void
+select_and_print_frame (struct frame_info *fi)
{
- select_frame (fi, level);
+ select_frame (fi);
if (fi)
{
- print_stack_frame (fi, level, 1);
+ print_stack_frame (fi, frame_relative_level (fi), 1);
}
}
\f
-
-/* Store the selected frame and its level into *FRAMEP and *LEVELP.
- If there is no selected frame, *FRAMEP is set to NULL. */
-
-void
-record_selected_frame (CORE_ADDR *frameaddrp, int *levelp)
-{
- *frameaddrp = selected_frame ? selected_frame->frame : 0;
- *levelp = frame_relative_level (selected_frame);
-}
-
/* Return the symbol-block in which the selected frame is executing.
Can return zero under various legitimate circumstances.
static void
select_frame_command (char *level_exp, int from_tty)
{
- register struct frame_info *frame, *frame1;
- unsigned int level = 0;
+ struct frame_info *frame;
+ int level = frame_relative_level (selected_frame);
if (!target_has_stack)
error ("No stack.");
frame = parse_frame_specification (level_exp);
- /* Try to figure out what level this frame is. But if there is
- no current stack, don't error out -- let the user set one. */
- frame1 = 0;
- if (get_current_frame ())
- {
- for (frame1 = get_prev_frame (0);
- frame1 && frame1 != frame;
- frame1 = get_prev_frame (frame1))
- level++;
- }
-
- if (!frame1)
- level = 0;
-
- select_frame (frame, level);
+ select_frame (frame);
+ if (level != frame_relative_level (selected_frame))
+ selected_frame_level_changed_event (frame_relative_level (selected_frame));
}
/* The "frame" command. With no arg, print selected frame briefly.
fi = find_relative_frame (selected_frame, &count1);
if (count1 != 0 && count_exp == 0)
error ("Initial frame selected; you cannot go up.");
- select_frame (fi, frame_relative_level (selected_frame) + count - count1);
+ select_frame (fi);
+ selected_frame_level_changed_event (frame_relative_level (selected_frame));
}
static void
error ("Bottom (i.e., innermost) frame selected; you cannot go down.");
}
- select_frame (frame, frame_relative_level (selected_frame) + count - count1);
+ select_frame (frame);
+ selected_frame_level_changed_event (frame_relative_level (selected_frame));
}
/* ARGSUSED */
if (!found)
printf_filtered ("'%s' not within current stack frame.\n", arg);
else if (fp != selected_frame)
- select_and_print_frame (fp, level);
+ select_and_print_frame (fp);
}
/* Gets the language of the current frame. */