#include "gdbthread.h"
#include "cp-support.h"
#include "disasm.h"
+#include "inline-frame.h"
#include "gdb_assert.h"
#include <ctype.h>
return 0;
}
+/* Return 1 if we should display the address in addition to the location,
+ because we are in the middle of a statement. */
+
+static int
+frame_show_address (struct frame_info *frame,
+ struct symtab_and_line sal)
+{
+ /* If there is a line number, but no PC, then there is no location
+ information associated with this sal. The only way that should
+ happen is for the call sites of inlined functions (SAL comes from
+ find_frame_sal). Otherwise, we would have some PC range if the
+ SAL came from a line table. */
+ if (sal.line != 0 && sal.pc == 0 && sal.end == 0)
+ {
+ if (get_next_frame (frame) == NULL)
+ gdb_assert (inline_skipped_frames (inferior_ptid) > 0);
+ else
+ gdb_assert (get_frame_type (get_next_frame (frame)) == INLINE_FRAME);
+ return 0;
+ }
+
+ return get_frame_pc (frame) != sal.pc;
+}
+
/* Show or print a stack frame FRAME briefly. The output is format
according to PRINT_LEVEL and PRINT_WHAT printing the frame's
relative level, function name, argument list, and file name and
print_frame_nameless_args (struct frame_info *frame, long start, int num,
int first, struct ui_file *stream)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i;
CORE_ADDR argsaddr;
long arg_value;
argsaddr = get_frame_args_address (frame);
if (!argsaddr)
return;
- arg_value = read_memory_integer (argsaddr + start, sizeof (int));
+ arg_value = read_memory_integer (argsaddr + start,
+ sizeof (int), byte_order);
if (!first)
fprintf_filtered (stream, ", ");
fprintf_filtered (stream, "%ld", arg_value);
struct gdb_disassembly_stub_args
{
+ struct gdbarch *gdbarch;
int how_many;
CORE_ADDR low;
CORE_ADDR high;
gdb_disassembly_stub (void *args)
{
struct gdb_disassembly_stub_args *p = args;
- gdb_disassembly (uiout, 0, 0, p->how_many, p->low, p->high);
+ gdb_disassembly (p->gdbarch, uiout, 0,
+ DISASSEMBLY_RAW_INSN, p->how_many,
+ p->low, p->high);
}
/* Use TRY_CATCH to catch the exception from the gdb_disassembly
because it will be broken by filter sometime. */
static void
-do_gdb_disassembly (int how_many, CORE_ADDR low, CORE_ADDR high)
+do_gdb_disassembly (struct gdbarch *gdbarch,
+ int how_many, CORE_ADDR low, CORE_ADDR high)
{
volatile struct gdb_exception exception;
struct gdb_disassembly_stub_args args;
+ args.gdbarch = gdbarch;
args.how_many = how_many;
args.low = low;
args.high = high;
print_frame_info (struct frame_info *frame, int print_level,
enum print_what print_what, int print_args)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
struct symtab_and_line sal;
int source_print;
int location_print;
if (get_frame_type (frame) == DUMMY_FRAME
- || get_frame_type (frame) == SIGTRAMP_FRAME)
+ || get_frame_type (frame) == SIGTRAMP_FRAME
+ || get_frame_type (frame) == ARCH_FRAME)
{
struct cleanup *uiout_cleanup
= make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
- get_frame_pc (frame));
+ gdbarch, get_frame_pc (frame));
/* Do this regardless of SOURCE because we don't have any source
to list for this frame. */
if (ui_out_is_mi_like_p (uiout))
{
annotate_frame_address ();
- ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+ ui_out_field_core_addr (uiout, "addr",
+ gdbarch, get_frame_pc (frame));
annotate_frame_address_end ();
}
annotate_signal_handler_caller ();
ui_out_field_string (uiout, "func", "<signal handler called>");
}
+ else if (get_frame_type (frame) == ARCH_FRAME)
+ {
+ ui_out_field_string (uiout, "func", "<cross-architecture call>");
+ }
ui_out_text (uiout, "\n");
annotate_frame_end ();
if ((disassemble_next_line == AUTO_BOOLEAN_AUTO
|| disassemble_next_line == AUTO_BOOLEAN_TRUE)
&& source_print && !sal.symtab)
- do_gdb_disassembly (1, get_frame_pc (frame), get_frame_pc (frame) + 1);
+ do_gdb_disassembly (get_frame_arch (frame), 1,
+ get_frame_pc (frame), get_frame_pc (frame) + 1);
if (source_print && sal.symtab)
{
int done = 0;
int mid_statement = ((print_what == SRC_LINE)
- && (get_frame_pc (frame) != sal.pc));
+ && frame_show_address (frame, sal));
if (annotation_level)
done = identify_source_line (sal.symtab, sal.line, mid_statement,
ability to decide for themselves if it is desired. */
if (opts.addressprint && mid_statement)
{
- ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+ ui_out_field_core_addr (uiout, "addr",
+ gdbarch, get_frame_pc (frame));
ui_out_text (uiout, "\t");
}
/* If disassemble-next-line is set to on and there is line debug
messages, output assembly codes for next line. */
if (disassemble_next_line == AUTO_BOOLEAN_TRUE)
- do_gdb_disassembly (-1, get_frame_pc (frame), sal.end);
+ do_gdb_disassembly (get_frame_arch (frame), -1,
+ get_frame_pc (frame), sal.end);
}
if (print_what != LOCATION)
*funname = NULL;
*funlang = language_unknown;
- func = find_pc_function (get_frame_address_in_block (frame));
+ func = get_frame_function (frame);
if (func)
{
/* In certain pathological cases, the symtabs give the wrong
changed (and we'll create a find_pc_minimal_function or some
such). */
- struct minimal_symbol *msymbol =
- lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
+ struct minimal_symbol *msymbol = NULL;
+
+ /* Don't attempt to do this for inlined functions, which do not
+ have a corresponding minimal symbol. */
+ if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func)))
+ msymbol
+ = lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame));
if (msymbol != NULL
&& (SYMBOL_VALUE_ADDRESS (msymbol)
enum print_what print_what, int print_args,
struct symtab_and_line sal)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
char *funname = NULL;
enum language funlang = language_unknown;
struct ui_stream *stb;
find_frame_funname (frame, &funname, &funlang);
annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
- get_frame_pc (frame));
+ gdbarch, get_frame_pc (frame));
list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
}
get_user_print_options (&opts);
if (opts.addressprint)
- if (get_frame_pc (frame) != sal.pc || !sal.symtab
+ if (frame_show_address (frame, sal) || !sal.symtab
|| print_what == LOC_AND_ADDRESS)
{
annotate_frame_address ();
- ui_out_field_core_addr (uiout, "addr", get_frame_pc (frame));
+ ui_out_field_core_addr (uiout, "addr", gdbarch, get_frame_pc (frame));
annotate_frame_address_end ();
ui_out_text (uiout, " in ");
}
{
printf_filtered (_("Stack frame at "));
}
- fputs_filtered (paddress (get_frame_base (fi)), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, get_frame_base (fi)), gdb_stdout);
printf_filtered (":\n");
printf_filtered (" %s = ", pc_regname);
- fputs_filtered (paddress (get_frame_pc (fi)), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, get_frame_pc (fi)), gdb_stdout);
wrap_here (" ");
if (funname)
puts_filtered ("; ");
wrap_here (" ");
printf_filtered ("saved %s ", pc_regname);
- fputs_filtered (paddress (frame_unwind_caller_pc (fi)), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, frame_unwind_caller_pc (fi)), gdb_stdout);
printf_filtered ("\n");
if (calling_frame_info == NULL)
printf_filtered (_(" Outermost frame: %s\n"),
frame_stop_reason_string (reason));
}
-
- if (calling_frame_info)
+ else if (get_frame_type (fi) == INLINE_FRAME)
+ printf_filtered (" inlined into frame %d",
+ frame_relative_level (get_prev_frame (fi)));
+ else
{
printf_filtered (" called by frame at ");
- fputs_filtered (paddress (get_frame_base (calling_frame_info)),
+ fputs_filtered (paddress (gdbarch, get_frame_base (calling_frame_info)),
gdb_stdout);
}
if (get_next_frame (fi) && calling_frame_info)
if (get_next_frame (fi))
{
printf_filtered (" caller of frame at ");
- fputs_filtered (paddress (get_frame_base (get_next_frame (fi))),
+ fputs_filtered (paddress (gdbarch, get_frame_base (get_next_frame (fi))),
gdb_stdout);
}
if (get_next_frame (fi) || calling_frame_info)
else
{
printf_filtered (" Arglist at ");
- fputs_filtered (paddress (arg_list), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, arg_list), gdb_stdout);
printf_filtered (",");
if (!gdbarch_frame_num_args_p (gdbarch))
else
{
printf_filtered (" Locals at ");
- fputs_filtered (paddress (arg_list), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, arg_list), gdb_stdout);
printf_filtered (",");
}
}
&realnum, NULL);
if (!optimized && lval == not_lval)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ int sp_size = register_size (gdbarch, gdbarch_sp_regnum (gdbarch));
gdb_byte value[MAX_REGISTER_SIZE];
CORE_ADDR sp;
frame_register_unwind (fi, gdbarch_sp_regnum (gdbarch),
/* NOTE: cagney/2003-05-22: This is assuming that the
stack pointer was packed as an unsigned integer. That
may or may not be valid. */
- sp = extract_unsigned_integer (value,
- register_size (gdbarch,
- gdbarch_sp_regnum (gdbarch)));
+ sp = extract_unsigned_integer (value, sp_size, byte_order);
printf_filtered (" Previous frame's sp is ");
- fputs_filtered (paddress (sp), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, sp), gdb_stdout);
printf_filtered ("\n");
need_nl = 0;
}
else if (!optimized && lval == lval_memory)
{
printf_filtered (" Previous frame's sp at ");
- fputs_filtered (paddress (addr), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
printf_filtered ("\n");
need_nl = 0;
}
wrap_here (" ");
printf_filtered (" %s at ",
gdbarch_register_name (gdbarch, i));
- fputs_filtered (paddress (addr), gdb_stdout);
+ fputs_filtered (paddress (gdbarch, addr), gdb_stdout);
count++;
}
}
of frames which we should print, or -1 if all of them. */
trailing = get_current_frame ();
- /* The target can be in a state where there is no valid frames
- (e.g., just connected). */
- if (trailing == NULL)
- error (_("No stack."));
-
trailing_level = 0;
if (count_exp)
{
/* Same, but print labels. */
static int
-print_block_frame_labels (struct block *b, int *have_default,
- struct ui_file *stream)
+print_block_frame_labels (struct gdbarch *gdbarch, struct block *b,
+ int *have_default, struct ui_file *stream)
{
struct dict_iterator iter;
struct symbol *sym;
if (opts.addressprint)
{
fprintf_filtered (stream, " ");
- fputs_filtered (paddress (SYMBOL_VALUE_ADDRESS (sym)), stream);
+ fputs_filtered (paddress (gdbarch, SYMBOL_VALUE_ADDRESS (sym)),
+ stream);
}
fprintf_filtered (stream, " in file %s, line %d\n",
sal.symtab->filename, sal.line);
if (print_block_frame_locals (block, frame, num_tabs, stream))
values_printed = 1;
/* After handling the function's top-level block, stop. Don't
- continue to its superblock, the block of per-file symbols. */
+ continue to its superblock, the block of per-file symbols.
+ Also do not continue to the containing function of an inlined
+ function. */
if (BLOCK_FUNCTION (block))
break;
block = BLOCK_SUPERBLOCK (block);
#else
struct blockvector *bl;
struct block *block = get_frame_block (frame, 0);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
int values_printed = 0;
int index, have_default = 0;
char *blocks_printed;
{
if (blocks_printed[index] == 0)
{
- if (print_block_frame_labels (BLOCKVECTOR_BLOCK (bl, index),
+ if (print_block_frame_labels (gdbarch,
+ BLOCKVECTOR_BLOCK (bl, index),
&have_default, stream))
values_printed = 1;
blocks_printed[index] = 1;
return;
/* After handling the function's top-level block, stop. Don't
- continue to its superblock, the block of per-file symbols. */
+ continue to its superblock, the block of per-file symbols.
+ Also do not continue to the containing function of an inlined
+ function. */
if (BLOCK_FUNCTION (block))
break;
block = BLOCK_SUPERBLOCK (block);
thisfun = get_frame_function (thisframe);
gdbarch = get_frame_arch (thisframe);
+ if (get_frame_type (get_current_frame ()) == INLINE_FRAME)
+ error (_("Can not force return from an inlined function."));
+
/* Compute the return value. If the computation triggers an error,
let it bail. If the return type can't be handled, set
RETURN_VALUE to NULL, and QUERY_PREFIX to an informational