/* Print values for GNU debugger GDB.
- Copyright (C) 1986-2016 Free Software Foundation, Inc.
+ Copyright (C) 1986-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "ui-out.h"
#include "block.h"
#include "disasm.h"
-#include "dfp.h"
+#include "target-float.h"
#include "observer.h"
#include "solist.h"
#include "parser-defs.h"
#include "cli/cli-script.h"
#include "format.h"
#include "source.h"
+#include "common/byte-vector.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et al. */
B ? (TMP = B->next, 1): 0; \
B = TMP)
-/* Prototypes for exported functions. */
-
-void _initialize_printcmd (void);
-
/* Prototypes for local functions. */
static void do_one_display (struct display *);
int size, struct ui_file *stream)
{
struct gdbarch *gdbarch = get_type_arch (type);
- LONGEST val_long = 0;
unsigned int len = TYPE_LENGTH (type);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* String printing should go through val_print_scalar_formatted. */
gdb_assert (options->format != 's');
- if (len > sizeof(LONGEST)
- && (TYPE_CODE (type) == TYPE_CODE_INT
- || TYPE_CODE (type) == TYPE_CODE_ENUM))
- {
- switch (options->format)
- {
- case 'o':
- print_octal_chars (stream, valaddr, len, byte_order);
- return;
- case 'u':
- case 'd':
- print_decimal_chars (stream, valaddr, len, byte_order);
- return;
- case 't':
- print_binary_chars (stream, valaddr, len, byte_order);
- return;
- case 'x':
- print_hex_chars (stream, valaddr, len, byte_order);
- return;
- case 'c':
- print_char_chars (stream, type, valaddr, len, byte_order);
- return;
- default:
- break;
- };
- }
-
- if (options->format != 'f')
- val_long = unpack_long (type, valaddr);
-
/* If the value is a pointer, and pointers and addresses are not the
same, then at this point, the value's length (in target bytes) is
gdbarch_addr_bit/TARGET_CHAR_BIT, not TYPE_LENGTH (type). */
/* If we are printing it as unsigned, truncate it in case it is actually
a negative signed value (e.g. "print/u (short)-1" should print 65535
(if shorts are 16 bits) instead of 4294967295). */
- if (options->format != 'd' || TYPE_UNSIGNED (type))
+ if (options->format != 'c'
+ && (options->format != 'd' || TYPE_UNSIGNED (type)))
{
- if (len < sizeof (LONGEST))
- val_long &= ((LONGEST) 1 << HOST_CHAR_BIT * len) - 1;
+ if (len < TYPE_LENGTH (type) && byte_order == BFD_ENDIAN_BIG)
+ valaddr += TYPE_LENGTH (type) - len;
}
- switch (options->format)
+ if (size != 0 && (options->format == 'x' || options->format == 't'))
{
- case 'x':
- if (!size)
+ /* Truncate to fit. */
+ unsigned newlen;
+ switch (size)
{
- /* No size specified, like in print. Print varying # of digits. */
- print_longest (stream, 'x', 1, val_long);
+ case 'b':
+ newlen = 1;
+ break;
+ case 'h':
+ newlen = 2;
+ break;
+ case 'w':
+ newlen = 4;
+ break;
+ case 'g':
+ newlen = 8;
+ break;
+ default:
+ error (_("Undefined output size \"%c\"."), size);
}
- else
- switch (size)
- {
- case 'b':
- case 'h':
- case 'w':
- case 'g':
- print_longest (stream, size, 1, val_long);
- break;
- default:
- error (_("Undefined output size \"%c\"."), size);
- }
- break;
+ if (newlen < len && byte_order == BFD_ENDIAN_BIG)
+ valaddr += len - newlen;
+ len = newlen;
+ }
+
+ /* Historically gdb has printed floats by first casting them to a
+ long, and then printing the long. PR cli/16242 suggests changing
+ this to using C-style hex float format. */
+ gdb::byte_vector converted_float_bytes;
+ if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && (options->format == 'o'
+ || options->format == 'x'
+ || options->format == 't'
+ || options->format == 'z'
+ || options->format == 'd'
+ || options->format == 'u'))
+ {
+ LONGEST val_long = unpack_long (type, valaddr);
+ converted_float_bytes.resize (TYPE_LENGTH (type));
+ store_signed_integer (converted_float_bytes.data (), TYPE_LENGTH (type),
+ byte_order, val_long);
+ valaddr = converted_float_bytes.data ();
+ }
+ /* Printing a non-float type as 'f' will interpret the data as if it were
+ of a floating-point type of the same length, if that exists. Otherwise,
+ the data is printed as integer. */
+ char format = options->format;
+ if (format == 'f' && TYPE_CODE (type) != TYPE_CODE_FLT)
+ {
+ type = float_type_from_length (type);
+ if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ format = 0;
+ }
+
+ switch (format)
+ {
+ case 'o':
+ print_octal_chars (stream, valaddr, len, byte_order);
+ break;
case 'd':
- print_longest (stream, 'd', 1, val_long);
+ print_decimal_chars (stream, valaddr, len, true, byte_order);
break;
-
case 'u':
- print_longest (stream, 'u', 0, val_long);
+ print_decimal_chars (stream, valaddr, len, false, byte_order);
break;
-
- case 'o':
- if (val_long)
- print_longest (stream, 'o', 1, val_long);
- else
- fprintf_filtered (stream, "0");
+ case 0:
+ if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ {
+ print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type),
+ byte_order);
+ break;
+ }
+ /* FALLTHROUGH */
+ case 'f':
+ print_floating (valaddr, type, stream);
break;
- case 'a':
- {
- CORE_ADDR addr = unpack_pointer (type, valaddr);
-
- print_address (gdbarch, addr, stream);
- }
+ case 't':
+ print_binary_chars (stream, valaddr, len, byte_order, size > 0);
+ break;
+ case 'x':
+ print_hex_chars (stream, valaddr, len, byte_order, size > 0);
+ break;
+ case 'z':
+ print_hex_chars (stream, valaddr, len, byte_order, true);
break;
-
case 'c':
{
struct value_print_options opts = *options;
+ LONGEST val_long = unpack_long (type, valaddr);
+
opts.format = 0;
if (TYPE_UNSIGNED (type))
type = builtin_type (gdbarch)->builtin_true_unsigned_char;
}
break;
- case 'f':
- type = float_type_from_length (type);
- print_floating (valaddr, type, stream);
- break;
-
- case 0:
- internal_error (__FILE__, __LINE__,
- _("failed internal consistency check"));
-
- case 't':
- /* Binary; 't' stands for "two". */
+ case 'a':
{
- char bits[8 * (sizeof val_long) + 1];
- char buf[8 * (sizeof val_long) + 32];
- char *cp = bits;
- int width;
-
- if (!size)
- width = 8 * (sizeof val_long);
- else
- switch (size)
- {
- case 'b':
- width = 8;
- break;
- case 'h':
- width = 16;
- break;
- case 'w':
- width = 32;
- break;
- case 'g':
- width = 64;
- break;
- default:
- error (_("Undefined output size \"%c\"."), size);
- }
+ CORE_ADDR addr = unpack_pointer (type, valaddr);
- bits[width] = '\0';
- while (width-- > 0)
- {
- bits[width] = (val_long & 1) ? '1' : '0';
- val_long >>= 1;
- }
- if (!size)
- {
- while (*cp && *cp == '0')
- cp++;
- if (*cp == '\0')
- cp--;
- }
- strncpy (buf, cp, sizeof (bits));
- fputs_filtered (buf, stream);
+ print_address (gdbarch, addr, stream);
}
break;
- case 'z':
- print_hex_chars (stream, valaddr, len, byte_order);
- break;
-
default:
- error (_("Undefined output format \"%c\"."), options->format);
+ error (_("Undefined output format \"%c\"."), format);
}
}
int
print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
struct ui_file *stream,
- int do_demangle, char *leadin)
+ int do_demangle, const char *leadin)
{
char *name = NULL;
char *filename = NULL;
/* The vector PCS is used to store instruction addresses within
a pc range. */
CORE_ADDR loop_start, loop_end, p;
- VEC (CORE_ADDR) *pcs = NULL;
+ std::vector<CORE_ADDR> pcs;
struct symtab_and_line sal;
- struct cleanup *cleanup = make_cleanup (VEC_cleanup (CORE_ADDR), &pcs);
*inst_read = 0;
loop_start = loop_end = addr;
instructions from INST_COUNT, and go to the next iteration. */
do
{
- VEC_truncate (CORE_ADDR, pcs, 0);
+ pcs.clear ();
sal = find_pc_sect_line (loop_start, NULL, 1);
if (sal.line <= 0)
{
LOOP_START to LOOP_END. */
for (p = loop_start; p < loop_end;)
{
- VEC_safe_push (CORE_ADDR, pcs, p);
+ pcs.push_back (p);
p += gdb_insn_length (gdbarch, p);
}
- inst_count -= VEC_length (CORE_ADDR, pcs);
- *inst_read += VEC_length (CORE_ADDR, pcs);
+ inst_count -= pcs.size ();
+ *inst_read += pcs.size ();
}
while (inst_count > 0);
The case when the length of PCS is 0 means that we reached an area for
which line info is not available. In such case, we return LOOP_START,
which was the lowest instruction address that had line info. */
- p = VEC_length (CORE_ADDR, pcs) > 0
- ? VEC_index (CORE_ADDR, pcs, -inst_count)
- : loop_start;
+ p = pcs.size () > 0 ? pcs[-inst_count] : loop_start;
/* INST_READ includes all instruction addresses in a pc range. Need to
exclude the beginning part up to the address we're returning. That
if (inst_count < 0)
*inst_read += inst_count;
- do_cleanups (cleanup);
return p;
}
int *strings_counted)
{
const int chunk_size = 0x20;
- gdb_byte *buffer = NULL;
- struct cleanup *cleanup = NULL;
int read_error = 0;
int chars_read = 0;
int chars_to_read = chunk_size;
CORE_ADDR string_start_addr = addr;
gdb_assert (char_size == 1 || char_size == 2 || char_size == 4);
- buffer = (gdb_byte *) xmalloc (chars_to_read * char_size);
- cleanup = make_cleanup (xfree, buffer);
+ gdb::byte_vector buffer (chars_to_read * char_size);
while (count > 0 && read_error == 0)
{
int i;
addr -= chars_to_read * char_size;
- chars_read = read_memory_backward (gdbarch, addr, buffer,
+ chars_read = read_memory_backward (gdbarch, addr, buffer.data (),
chars_to_read * char_size);
chars_read /= char_size;
read_error = (chars_read == chars_to_read) ? 0 : 1;
{
int offset = (chars_to_read - i - 1) * char_size;
- if (integer_is_zero (buffer + offset, char_size)
+ if (integer_is_zero (&buffer[offset], char_size)
|| chars_counted == options->print_max)
{
/* Found '\0' or reached print_max. As OFFSET is the offset to
string_start_addr -= chars_counted * char_size;
}
- do_cleanups (cleanup);
return string_start_addr;
}
}
static void
-print_command (char *exp, int from_tty)
+print_command (const char *exp, int from_tty)
{
print_command_1 (exp, 1);
}
/* Same as print, except it doesn't print void results. */
static void
-call_command (char *exp, int from_tty)
+call_command (const char *exp, int from_tty)
{
print_command_1 (exp, 0);
}
/* Implementation of the "output" command. */
static void
-output_command (char *exp, int from_tty)
+output_command (const char *exp, int from_tty)
{
output_command_const (exp, from_tty);
}
}
static void
-set_command (char *exp, int from_tty)
+set_command (const char *exp, int from_tty)
{
expression_up expr = parse_expression (exp);
}
static void
-sym_info (char *arg, int from_tty)
+info_symbol_command (const char *arg, int from_tty)
{
struct minimal_symbol *msymbol;
struct objfile *objfile;
= lookup_minimal_symbol_by_pc_section (sect_addr, osect).minsym))
{
const char *obj_name, *mapped, *sec_name, *msym_name;
- char *loc_string;
+ const char *loc_string;
struct cleanup *old_chain;
matches = 1;
/* Don't print the offset if it is zero.
We assume there's no need to handle i18n of "sym + offset". */
+ std::string string_holder;
if (offset)
- loc_string = xstrprintf ("%s + %u", msym_name, offset);
+ {
+ string_holder = string_printf ("%s + %u", msym_name, offset);
+ loc_string = string_holder.c_str ();
+ }
else
- loc_string = xstrprintf ("%s", msym_name);
-
- /* Use a cleanup to free loc_string in case the user quits
- a pagination request inside printf_filtered. */
- old_chain = make_cleanup (xfree, loc_string);
+ loc_string = msym_name;
gdb_assert (osect->objfile && objfile_name (osect->objfile));
obj_name = objfile_name (osect->objfile);
else
printf_filtered (_("%s in section %s\n"),
loc_string, sec_name);
-
- do_cleanups (old_chain);
}
}
if (matches == 0)
}
static void
-address_info (char *exp, int from_tty)
+info_address_command (const char *exp, int from_tty)
{
struct gdbarch *gdbarch;
int regno;
\f
static void
-x_command (char *exp, int from_tty)
+x_command (const char *exp, int from_tty)
{
struct format_data fmt;
- struct cleanup *old_chain;
struct value *val;
fmt.format = last_format ? last_format : 'x';
repeated with Newline. But don't clobber a user-defined
command's definition. */
if (from_tty)
- *exp = 0;
+ set_repeat_arguments ("");
val = evaluate_expression (expr.get ());
- if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+ if (TYPE_IS_REFERENCE (value_type (val)))
val = coerce_ref (val);
/* In rvalue contexts, such as this, functions are coerced into
pointers to functions. This makes "x/i main" work. */
Specify the expression. */
static void
-display_command (char *arg, int from_tty)
+display_command (const char *arg, int from_tty)
{
struct format_data fmt;
struct display *newobj;
ARGS. DATA is passed unmodified to FUNCTION. */
static void
-map_display_numbers (char *args,
+map_display_numbers (const char *args,
void (*function) (struct display *,
void *),
void *data)
/* "undisplay" command. */
static void
-undisplay_command (char *args, int from_tty)
+undisplay_command (const char *args, int from_tty)
{
if (args == NULL)
{
}
static void
-display_info (char *ignore, int from_tty)
+info_display_command (const char *ignore, int from_tty)
{
struct display *d;
commands. ENABLE decides what to do. */
static void
-enable_disable_display_command (char *args, int from_tty, int enable)
+enable_disable_display_command (const char *args, int from_tty, int enable)
{
if (args == NULL)
{
/* The "enable display" command. */
static void
-enable_display_command (char *args, int from_tty)
+enable_display_command (const char *args, int from_tty)
{
enable_disable_display_command (args, from_tty, 1);
}
/* The "disable display" command. */
static void
-disable_display_command (char *args, int from_tty)
+disable_display_command (const char *args, int from_tty)
{
enable_disable_display_command (args, from_tty, 0);
}
"wchar_t", NULL, 0);
int wcwidth = TYPE_LENGTH (wctype);
gdb_byte *buf = (gdb_byte *) alloca (wcwidth);
- struct obstack output;
- struct cleanup *inner_cleanup;
tem = value_as_address (value);
read_memory (tem, str, j);
memset (&str[j], 0, wcwidth);
- obstack_init (&output);
- inner_cleanup = make_cleanup_obstack_free (&output);
+ auto_obstack output;
convert_between_encodings (target_wide_charset (gdbarch),
host_charset (),
obstack_grow_str0 (&output, "");
fprintf_filtered (stream, format, obstack_base (&output));
- do_cleanups (inner_cleanup);
}
/* Subroutine of ui_printf to simplify it.
- Print VALUE, a decimal floating point value, to STREAM using FORMAT. */
+ Print VALUE, a floating point value, to STREAM using FORMAT. */
static void
-printf_decfloat (struct ui_file *stream, const char *format,
- struct value *value)
+printf_floating (struct ui_file *stream, const char *format,
+ struct value *value, enum argclass argclass)
{
- const gdb_byte *param_ptr = value_contents (value);
-
-#if defined (PRINTF_HAS_DECFLOAT)
- /* If we have native support for Decimal floating
- printing, handle it here. */
- fprintf_filtered (stream, format, param_ptr);
-#else
- /* As a workaround until vasprintf has native support for DFP
- we convert the DFP values to string and print them using
- the %s format specifier. */
- const char *p;
-
/* Parameter data. */
struct type *param_type = value_type (value);
struct gdbarch *gdbarch = get_type_arch (param_type);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- /* DFP output data. */
- struct value *dfp_value = NULL;
- gdb_byte *dfp_ptr;
- int dfp_len = 16;
- gdb_byte dec[16];
- struct type *dfp_type = NULL;
- char decstr[MAX_DECIMAL_STRING];
-
- /* Points to the end of the string so that we can go back
- and check for DFP length modifiers. */
- p = format + strlen (format);
-
- /* Look for the float/double format specifier. */
- while (*p != 'f' && *p != 'e' && *p != 'E'
- && *p != 'g' && *p != 'G')
- p--;
-
- /* Search for the '%' char and extract the size and type of
- the output decimal value based on its modifiers
- (%Hf, %Df, %DDf). */
- while (*--p != '%')
+ /* Determine target type corresponding to the format string. */
+ struct type *fmt_type;
+ switch (argclass)
{
- if (*p == 'H')
- {
- dfp_len = 4;
- dfp_type = builtin_type (gdbarch)->builtin_decfloat;
- }
- else if (*p == 'D' && *(p - 1) == 'D')
- {
- dfp_len = 16;
- dfp_type = builtin_type (gdbarch)->builtin_declong;
- p--;
- }
- else
- {
- dfp_len = 8;
- dfp_type = builtin_type (gdbarch)->builtin_decdouble;
- }
+ case double_arg:
+ fmt_type = builtin_type (gdbarch)->builtin_double;
+ break;
+ case long_double_arg:
+ fmt_type = builtin_type (gdbarch)->builtin_long_double;
+ break;
+ case dec32float_arg:
+ fmt_type = builtin_type (gdbarch)->builtin_decfloat;
+ break;
+ case dec64float_arg:
+ fmt_type = builtin_type (gdbarch)->builtin_decdouble;
+ break;
+ case dec128float_arg:
+ fmt_type = builtin_type (gdbarch)->builtin_declong;
+ break;
+ default:
+ gdb_assert_not_reached ("unexpected argument class");
}
- /* Conversion between different DFP types. */
- if (TYPE_CODE (param_type) == TYPE_CODE_DECFLOAT)
- decimal_convert (param_ptr, TYPE_LENGTH (param_type),
- byte_order, dec, dfp_len, byte_order);
- else
- /* If this is a non-trivial conversion, just output 0.
- A correct converted value can be displayed by explicitly
- casting to a DFP type. */
- decimal_from_string (dec, dfp_len, byte_order, "0");
+ /* To match the traditional GDB behavior, the conversion is
+ done differently depending on the type of the parameter:
- dfp_value = value_from_decfloat (dfp_type, dec);
+ - if the parameter has floating-point type, it's value
+ is converted to the target type;
- dfp_ptr = (gdb_byte *) value_contents (dfp_value);
+ - otherwise, if the parameter has a type that is of the
+ same size as a built-in floating-point type, the value
+ bytes are interpreted as if they were of that type, and
+ then converted to the target type (this is not done for
+ decimal floating-point argument classes);
- decimal_to_string (dfp_ptr, dfp_len, byte_order, decstr);
+ - otherwise, if the source value has an integer value,
+ it's value is converted to the target type;
- /* Print the DFP value. */
- fprintf_filtered (stream, "%s", decstr);
-#endif
+ - otherwise, an error is raised.
+
+ In either case, the result of the conversion is a byte buffer
+ formatted in the target format for the target type. */
+
+ if (TYPE_CODE (fmt_type) == TYPE_CODE_FLT)
+ {
+ param_type = float_type_from_length (param_type);
+ if (param_type != value_type (value))
+ value = value_from_contents (param_type, value_contents (value));
+ }
+
+ value = value_cast (fmt_type, value);
+
+ /* Convert the value to a string and print it. */
+ std::string str
+ = target_float_to_string (value_contents (value), fmt_type, format);
+ fputs_filtered (str.c_str (), stream);
}
/* Subroutine of ui_printf to simplify it.
if (s == 0)
error_no_arg (_("format-control string and values to print"));
- s = skip_spaces_const (s);
+ s = skip_spaces (s);
/* A format string should follow, enveloped in double quotes. */
if (*s++ != '"')
if (*s++ != '"')
error (_("Bad format string, non-terminated '\"'."));
- s = skip_spaces_const (s);
+ s = skip_spaces (s);
if (*s != ',' && *s != 0)
error (_("Invalid argument syntax"));
if (*s == ',')
s++;
- s = skip_spaces_const (s);
+ s = skip_spaces (s);
{
int nargs = 0;
struct type *wctype = lookup_typename (current_language, gdbarch,
"wchar_t", NULL, 0);
struct type *valtype;
- struct obstack output;
- struct cleanup *inner_cleanup;
const gdb_byte *bytes;
valtype = value_type (val_args[i]);
bytes = value_contents (val_args[i]);
- obstack_init (&output);
- inner_cleanup = make_cleanup_obstack_free (&output);
+ auto_obstack output;
convert_between_encodings (target_wide_charset (gdbarch),
host_charset (),
fprintf_filtered (stream, current_substring,
obstack_base (&output));
- do_cleanups (inner_cleanup);
}
break;
- case double_arg:
- {
- struct type *type = value_type (val_args[i]);
- DOUBLEST val;
- int inv;
-
- /* If format string wants a float, unchecked-convert the value
- to floating point of the same size. */
- type = float_type_from_length (type);
- val = unpack_double (type, value_contents (val_args[i]), &inv);
- if (inv)
- error (_("Invalid floating value found in program."));
-
- fprintf_filtered (stream, current_substring, (double) val);
- break;
- }
- case long_double_arg:
-#ifdef HAVE_LONG_DOUBLE
- {
- struct type *type = value_type (val_args[i]);
- DOUBLEST val;
- int inv;
-
- /* If format string wants a float, unchecked-convert the value
- to floating point of the same size. */
- type = float_type_from_length (type);
- val = unpack_double (type, value_contents (val_args[i]), &inv);
- if (inv)
- error (_("Invalid floating value found in program."));
-
- fprintf_filtered (stream, current_substring,
- (long double) val);
- break;
- }
-#else
- error (_("long double not supported in printf"));
-#endif
case long_long_arg:
#ifdef PRINTF_HAS_LONG_LONG
{
fprintf_filtered (stream, current_substring, val);
break;
}
- /* Handles decimal floating values. */
- case decfloat_arg:
- printf_decfloat (stream, current_substring, val_args[i]);
+ /* Handles floating-point values. */
+ case double_arg:
+ case long_double_arg:
+ case dec32float_arg:
+ case dec64float_arg:
+ case dec128float_arg:
+ printf_floating (stream, current_substring, val_args[i],
+ fpieces[fr].argclass);
break;
case ptr_arg:
printf_pointer (stream, current_substring, val_args[i]);
/* Implement the "printf" command. */
static void
-printf_command (char *arg, int from_tty)
+printf_command (const char *arg, int from_tty)
{
ui_printf (arg, gdb_stdout);
gdb_flush (gdb_stdout);
/* Implement the "eval" command. */
static void
-eval_command (char *arg, int from_tty)
+eval_command (const char *arg, int from_tty)
{
- struct ui_file *ui_out = mem_fileopen ();
- struct cleanup *cleanups = make_cleanup_ui_file_delete (ui_out);
-
- ui_printf (arg, ui_out);
-
- std::string expanded = ui_file_as_string (ui_out);
+ string_file stb;
- expanded = insert_user_defined_cmd_args (expanded.c_str ());
+ ui_printf (arg, &stb);
- execute_command (&expanded[0], from_tty);
+ std::string expanded = insert_user_defined_cmd_args (stb.c_str ());
- do_cleanups (cleanups);
+ execute_command (expanded.c_str (), from_tty);
}
void
observer_attach_free_objfile (clear_dangling_display_expressions);
- add_info ("address", address_info,
+ add_info ("address", info_address_command,
_("Describe where symbol SYM is stored."));
- add_info ("symbol", sym_info, _("\
+ add_info ("symbol", info_symbol_command, _("\
Describe what symbol is at location ADDR.\n\
Only for symbols with fixed locations (global or static scope)."));
_("Print line number and file of definition of variable."));
#endif
- add_info ("display", display_info, _("\
+ add_info ("display", info_display_command, _("\
Expressions to display when program stops, with code numbers."));
add_cmd ("undisplay", class_vars, undisplay_command, _("\