/* Print values for GNU debugger GDB.
- Copyright 1986, 87, 88, 89, 90, 91, 93, 94, 95, 1998
- Free Software Foundation, Inc.
+ Copyright 1986-1991, 1993-1995, 1998, 2000 Free Software Foundation, Inc.
This file is part of GDB.
#include "annotate.h"
#include "symfile.h" /* for overlay functions */
#include "objfiles.h" /* ditto */
+#ifdef UI_OUT
+#include "ui-out.h"
+#endif
extern int asm_demangle; /* Whether to demangle syms in asm printouts */
extern int addressprint; /* Whether to print hex addresses in HLL " */
static void printf_command PARAMS ((char *, int));
-static void print_frame_nameless_args PARAMS ((struct frame_info *, long,
- int, int, GDB_FILE *));
+static void print_frame_nameless_args (struct frame_info *, long,
+ int, int, struct ui_file *);
static void display_info PARAMS ((char *, int));
static void do_examine PARAMS ((struct format_data, CORE_ADDR addr, asection * section));
-static void print_formatted PARAMS ((value_ptr, int, int));
+static void print_formatted (value_ptr, int, int, struct ui_file *);
static struct format_data decode_format PARAMS ((char **, int, int));
-static int print_insn PARAMS ((CORE_ADDR, GDB_FILE *));
+static int print_insn (CORE_ADDR, struct ui_file *);
static void sym_info PARAMS ((char *, int));
\f
return val;
}
\f
-/* Print value VAL on gdb_stdout according to FORMAT, a letter or 0.
+/* Print value VAL on stream according to FORMAT, a letter or 0.
Do not end with a newline.
0 means print VAL according to its own type.
SIZE is the letter for the size of datum being printed.
This is used to pad hex numbers so they line up. */
static void
-print_formatted (val, format, size)
+print_formatted (val, format, size, stream)
register value_ptr val;
register int format;
int size;
+ struct ui_file *stream;
{
struct type *type = check_typedef (VALUE_TYPE (val));
int len = TYPE_LENGTH (type);
case 's':
/* FIXME: Need to handle wchar_t's here... */
next_address = VALUE_ADDRESS (val)
- + val_print_string (VALUE_ADDRESS (val), -1, 1, gdb_stdout);
+ + val_print_string (VALUE_ADDRESS (val), -1, 1, stream);
next_section = VALUE_BFD_SECTION (val);
break;
/* We often wrap here if there are long symbolic names. */
wrap_here (" ");
next_address = VALUE_ADDRESS (val)
- + print_insn (VALUE_ADDRESS (val), gdb_stdout);
+ + print_insn (VALUE_ADDRESS (val), stream);
next_section = VALUE_BFD_SECTION (val);
break;
* we have to use language rules to print it as
* a series of scalars.
*/
- value_print (val, gdb_stdout, format, Val_pretty_default);
+ value_print (val, stream, format, Val_pretty_default);
else
/* User specified format, so don't look to the
* the type to tell us what to do.
*/
print_scalar_formatted (VALUE_CONTENTS (val), type,
- format, size, gdb_stdout);
+ format, size, stream);
}
}
struct type *type;
int format;
int size;
- GDB_FILE *stream;
+ struct ui_file *stream;
{
LONGEST val_long;
unsigned int len = TYPE_LENGTH (type);
break;
case 'a':
- print_address (unpack_pointer (type, valaddr), stream);
+ {
+ /* Truncate address to the size of a target pointer, avoiding
+ shifts larger or equal than the width of a CORE_ADDR. */
+ CORE_ADDR addr = unpack_pointer (type, valaddr);
+ if (TARGET_PTR_BIT < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
+ addr &= ((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1;
+ print_address (addr, stream);
+ }
break;
case 'c':
void
print_address_symbolic (addr, stream, do_demangle, leadin)
CORE_ADDR addr;
- GDB_FILE *stream;
+ struct ui_file *stream;
int do_demangle;
char *leadin;
+{
+ char *name = NULL;
+ char *filename = NULL;
+ int unmapped = 0;
+ int offset = 0;
+ int line = 0;
+
+ struct cleanup *cleanup_chain = make_cleanup (free, name);
+ if (print_symbol_filename)
+ make_cleanup (free, filename);
+
+ if (build_address_symbolic (addr, do_demangle, &name, &offset, &filename, &line, &unmapped))
+ return;
+
+ fputs_filtered (leadin, stream);
+ if (unmapped)
+ fputs_filtered ("<*", stream);
+ else
+ fputs_filtered ("<", stream);
+ fputs_filtered (name, stream);
+ if (offset != 0)
+ fprintf_filtered (stream, "+%u", (unsigned int) offset);
+
+ /* Append source filename and line number if desired. Give specific
+ line # of this addr, if we have it; else line # of the nearest symbol. */
+ if (print_symbol_filename && filename != NULL)
+ {
+ if (line != -1)
+ fprintf_filtered (stream, " at %s:%d", filename, line);
+ else
+ fprintf_filtered (stream, " in %s", filename);
+ }
+ if (unmapped)
+ fputs_filtered ("*>", stream);
+ else
+ fputs_filtered (">", stream);
+
+ do_cleanups (cleanup_chain);
+}
+
+/* Given an address ADDR return all the elements needed to print the
+ address in a symbolic form. NAME can be mangled or not depending
+ on DO_DEMANGLE (and also on the asm_demangle global variable,
+ manipulated via ''set print asm-demangle''). Return 0 in case of
+ success, when all the info in the OUT paramters is valid. Return 1
+ otherwise. */
+int
+build_address_symbolic (CORE_ADDR addr, /* IN */
+ int do_demangle, /* IN */
+ char **name, /* OUT */
+ int *offset, /* OUT */
+ char **filename, /* OUT */
+ int *line, /* OUT */
+ int *unmapped) /* OUT */
{
struct minimal_symbol *msymbol;
struct symbol *symbol;
struct symtab *symtab = 0;
CORE_ADDR name_location = 0;
- char *name = "";
asection *section = 0;
- int unmapped = 0;
+ char *name_temp = "";
+
+ /* Let's say it is unmapped. */
+ *unmapped = 0;
- /* Determine if the address is in an overlay, and whether it is mapped. */
+ /* Determine if the address is in an overlay, and whether it is
+ mapped. */
if (overlay_debugging)
{
section = find_pc_overlay (addr);
if (pc_in_unmapped_range (addr, section))
{
- unmapped = 1;
+ *unmapped = 1;
addr = overlay_mapped_address (addr, section);
}
}
{
name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
if (do_demangle)
- name = SYMBOL_SOURCE_NAME (symbol);
+ name_temp = SYMBOL_SOURCE_NAME (symbol);
else
- name = SYMBOL_LINKAGE_NAME (symbol);
+ name_temp = SYMBOL_LINKAGE_NAME (symbol);
}
if (msymbol != NULL)
symtab = 0;
name_location = SYMBOL_VALUE_ADDRESS (msymbol);
if (do_demangle)
- name = SYMBOL_SOURCE_NAME (msymbol);
+ name_temp = SYMBOL_SOURCE_NAME (msymbol);
else
- name = SYMBOL_LINKAGE_NAME (msymbol);
+ name_temp = SYMBOL_LINKAGE_NAME (msymbol);
}
}
if (symbol == NULL && msymbol == NULL)
- return;
+ return 1;
/* On some targets, mask out extra "flag" bits from PC for handsome
disassembly. */
of the address space back to the beginning, giving bogus comparison. */
if (addr > name_location + max_symbolic_offset
&& name_location + max_symbolic_offset > name_location)
- return;
+ return 1;
- fputs_filtered (leadin, stream);
- if (unmapped)
- fputs_filtered ("<*", stream);
- else
- fputs_filtered ("<", stream);
- fputs_filtered (name, stream);
- if (addr != name_location)
- fprintf_filtered (stream, "+%u", (unsigned int) (addr - name_location));
+ *offset = addr - name_location;
+
+ *name = xstrdup (name_temp);
- /* Append source filename and line number if desired. Give specific
- line # of this addr, if we have it; else line # of the nearest symbol. */
if (print_symbol_filename)
{
struct symtab_and_line sal;
sal = find_pc_sect_line (addr, section, 0);
if (sal.symtab)
- fprintf_filtered (stream, " at %s:%d", sal.symtab->filename, sal.line);
+ {
+ *filename = xstrdup (sal.symtab->filename);
+ *line = sal.line;
+ }
else if (symtab && symbol && symbol->line)
- fprintf_filtered (stream, " at %s:%d", symtab->filename, symbol->line);
+ {
+ *filename = xstrdup (symtab->filename);
+ *line = symbol->line;
+ }
else if (symtab)
- fprintf_filtered (stream, " in %s", symtab->filename);
+ {
+ *filename = xstrdup (symtab->filename);
+ *line = -1;
+ }
}
- if (unmapped)
- fputs_filtered ("*>", stream);
- else
- fputs_filtered (">", stream);
+ return 0;
}
-
/* Print address ADDR on STREAM. USE_LOCAL means the same thing as for
print_longest. */
void
print_address_numeric (addr, use_local, stream)
CORE_ADDR addr;
int use_local;
- GDB_FILE *stream;
+ struct ui_file *stream;
{
/* This assumes a CORE_ADDR can fit in a LONGEST. Probably a safe
assumption. */
void
print_address (addr, stream)
CORE_ADDR addr;
- GDB_FILE *stream;
+ struct ui_file *stream;
{
print_address_numeric (addr, 1, stream);
print_address_symbolic (addr, stream, asm_demangle, " ");
void
print_address_demangle (addr, stream, do_demangle)
CORE_ADDR addr;
- GDB_FILE *stream;
+ struct ui_file *stream;
int do_demangle;
{
if (addr == 0)
if (last_examine_value)
release_value (last_examine_value);
- print_formatted (last_examine_value, format, size);
+ print_formatted (last_examine_value, format, size, gdb_stdout);
}
printf_filtered ("\n");
gdb_flush (gdb_stdout);
if (histindex >= 0)
annotate_value_history_value ();
- print_formatted (val, format, fmt.size);
+ print_formatted (val, format, fmt.size, gdb_stdout);
printf_filtered ("\n");
if (histindex >= 0)
annotate_value_begin (VALUE_TYPE (val));
- print_formatted (val, format, fmt.size);
+ print_formatted (val, format, fmt.size, gdb_stdout);
annotate_value_end ();
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+
do_cleanups (old_chain);
}
annotate_display_expression ();
print_formatted (evaluate_expression (d->exp),
- d->format.format, d->format.size);
+ d->format.format, d->format.size, gdb_stdout);
printf_filtered ("\n");
}
print_variable_value (var, frame, stream)
struct symbol *var;
struct frame_info *frame;
- GDB_FILE *stream;
+ struct ui_file *stream;
{
value_ptr val = read_var_value (var, frame);
struct symbol *func;
struct frame_info *fi;
int num;
- GDB_FILE *stream;
+ struct ui_file *stream;
{
struct block *b = NULL;
int nsyms = 0;
int arg_size;
/* Number of ints of arguments that we have printed so far. */
int args_printed = 0;
+#ifdef UI_OUT
+ struct cleanup *old_chain;
+ struct ui_stream *stb;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup ((make_cleanup_func) ui_out_stream_delete, stb);
+#endif /* UI_OUT */
if (func)
{
sym = nsym;
}
+#ifdef UI_OUT
+ /* Print the current arg. */
+ if (!first)
+ ui_out_text (uiout, ", ");
+ ui_out_wrap_hint (uiout, " ");
+
+ annotate_arg_begin ();
+
+ ui_out_list_begin (uiout, NULL);
+ fprintf_symbol_filtered (stb->stream, SYMBOL_SOURCE_NAME (sym),
+ SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI);
+ ui_out_field_stream (uiout, "name", stb);
+ annotate_arg_name_end ();
+ ui_out_text (uiout, "=");
+#else
/* Print the current arg. */
if (!first)
fprintf_filtered (stream, ", ");
SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI);
annotate_arg_name_end ();
fputs_filtered ("=", stream);
+#endif
/* Avoid value_print because it will deref ref parameters. We just
want to print their addresses. Print ??? for args whose address
if (GDB_TARGET_IS_D10V
&& SYMBOL_CLASS (sym) == LOC_REGPARM && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR)
TYPE_LENGTH (VALUE_TYPE (val)) = 2;
+#ifdef UI_OUT
+ val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
+ VALUE_ADDRESS (val),
+ stb->stream, 0, 0, 2, Val_no_prettyprint);
+ ui_out_field_stream (uiout, "value", stb);
+ }
+ else
+ ui_out_text (uiout, "???");
+
+ ui_out_list_end (uiout);
+#else
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
VALUE_ADDRESS (val),
stream, 0, 0, 2, Val_no_prettyprint);
}
else
fputs_filtered ("???", stream);
+#endif
annotate_arg_end ();
print_frame_nameless_args (fi, start, num - args_printed,
first, stream);
}
+#ifdef UI_OUT
+ do_cleanups (old_chain);
+#endif /* no UI_OUT */
}
/* Print nameless args on STREAM.
long start;
int num;
int first;
- GDB_FILE *stream;
+ struct ui_file *stream;
{
int i;
CORE_ADDR argsaddr;
static int
print_insn (memaddr, stream)
CORE_ADDR memaddr;
- GDB_FILE *stream;
+ struct ui_file *stream;
{
if (TARGET_BYTE_ORDER == BIG_ENDIAN)
TARGET_PRINT_INSN_INFO->endian = BFD_ENDIAN_BIG;