/* Print values for GNU debugger GDB.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008 Free Software Foundation, Inc.
This file is part of GDB.
#include "tui/tui.h" /* For tui_active et.al. */
#endif
+#if defined(__MINGW32__)
+# define USE_PRINTF_I64 1
+# define PRINTF_HAS_LONG_LONG
+#else
+# define USE_PRINTF_I64 0
+#endif
+
extern int asm_demangle; /* Whether to demangle syms in asm printouts */
extern int addressprint; /* Whether to print hex addresses in HLL " */
}
if (format == 0 || format == 's'
+ || TYPE_CODE (type) == TYPE_CODE_REF
|| TYPE_CODE (type) == TYPE_CODE_ARRAY
|| TYPE_CODE (type) == TYPE_CODE_STRING
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
{
LONGEST val_long = 0;
unsigned int len = TYPE_LENGTH (type);
+ enum bfd_endian byte_order = gdbarch_byte_order (current_gdbarch);
/* If we get here with a string format, try again without it. Go
all the way back to the language printers, which may call us
again. */
if (format == 's')
{
- val_print (type, valaddr, 0, 0, stream, 0, 0, 0, Val_pretty_default);
+ val_print (type, valaddr, 0, 0, stream, 0, 0, 0, Val_pretty_default,
+ current_language);
return;
}
switch (format)
{
case 'o':
- print_octal_chars (stream, valaddr, len);
+ print_octal_chars (stream, valaddr, len, byte_order);
return;
case 'u':
case 'd':
- print_decimal_chars (stream, valaddr, len);
+ print_decimal_chars (stream, valaddr, len, byte_order);
return;
case 't':
- print_binary_chars (stream, valaddr, len);
+ print_binary_chars (stream, valaddr, len, byte_order);
return;
case 'x':
- print_hex_chars (stream, valaddr, len);
+ print_hex_chars (stream, valaddr, len, byte_order);
return;
case 'c':
- print_char_chars (stream, valaddr, len);
+ print_char_chars (stream, valaddr, len, byte_order);
return;
default:
break;
return 0;
}
-/* Print address ADDR on STREAM. USE_LOCAL means the same thing as for
- print_longest. */
-void
-deprecated_print_address_numeric (CORE_ADDR addr, int use_local,
- struct ui_file *stream)
-{
- if (use_local)
- fputs_filtered (paddress (addr), stream);
- else
- {
- int addr_bit = gdbarch_addr_bit (current_gdbarch);
-
- if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
- addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
- print_longest (stream, 'x', 0, (ULONGEST) addr);
- }
-}
/* Print address ADDR symbolically on STREAM.
First print it as a number. Then perhaps print
void
print_address (CORE_ADDR addr, struct ui_file *stream)
{
- deprecated_print_address_numeric (addr, 1, stream);
+ fputs_filtered (paddress (addr), stream);
print_address_symbolic (addr, stream, asm_demangle, " ");
}
}
else if (addressprint)
{
- deprecated_print_address_numeric (addr, 1, stream);
+ fputs_filtered (paddress (addr), stream);
print_address_symbolic (addr, stream, do_demangle, " ");
}
else
struct symbol *sym;
struct minimal_symbol *msymbol;
long val;
- long basereg;
asection *section;
CORE_ADDR load_addr;
int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero
error (_("Argument required."));
sym = lookup_symbol (exp, get_selected_block (0), VAR_DOMAIN,
- &is_a_field_of_this, (struct symtab **) NULL);
+ &is_a_field_of_this);
if (sym == NULL)
{
if (is_a_field_of_this)
fprintf_symbol_filtered (gdb_stdout, exp,
current_language->la_language, DMGL_ANSI);
printf_filtered ("\" is at ");
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
printf_filtered (" in a file compiled without debugging");
section = SYMBOL_BFD_SECTION (msymbol);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (",\n -- loaded at ");
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
printf_filtered (" in overlay section %s", section->name);
}
printf_filtered (".\n");
current_language->la_language, DMGL_ANSI);
printf_filtered ("\" is ");
val = SYMBOL_VALUE (sym);
- basereg = SYMBOL_BASEREG (sym);
section = SYMBOL_BFD_SECTION (sym);
switch (SYMBOL_CLASS (sym))
case LOC_LABEL:
printf_filtered ("a label at address ");
- deprecated_print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
- 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr = SYMBOL_VALUE_ADDRESS (sym)),
+ gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (",\n -- loaded at ");
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
printf_filtered (" in overlay section %s", section->name);
}
break;
case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
/* FIXME: cagney/2004-01-26: It should be possible to
unconditionally call the SYMBOL_OPS method when available.
Unfortunately DWARF 2 stores the frame-base (instead of the
break;
case LOC_REGISTER:
- printf_filtered (_("a variable in register %s"),
+ if (SYMBOL_IS_ARGUMENT (sym))
+ printf_filtered (_("an argument in register %s"),
+ gdbarch_register_name (current_gdbarch, val));
+ else
+ printf_filtered (_("a variable in register %s"),
gdbarch_register_name (current_gdbarch, val));
break;
case LOC_STATIC:
printf_filtered (_("static storage at address "));
- deprecated_print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
- 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr = SYMBOL_VALUE_ADDRESS (sym)),
+ gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (_(",\n -- loaded at "));
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
printf_filtered (_(" in overlay section %s"), section->name);
}
break;
- case LOC_INDIRECT:
- printf_filtered (_("external global (indirect addressing), at address *("));
- deprecated_print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
- 1, gdb_stdout);
- printf_filtered (")");
- if (section_is_overlay (section))
- {
- load_addr = overlay_unmapped_address (load_addr, section);
- printf_filtered (_(",\n -- loaded at "));
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
- printf_filtered (_(" in overlay section %s"), section->name);
- }
- break;
-
- case LOC_REGPARM:
- printf_filtered (_("an argument in register %s"),
- gdbarch_register_name (current_gdbarch, val));
- break;
-
case LOC_REGPARM_ADDR:
printf_filtered (_("address of an argument in register %s"),
gdbarch_register_name (current_gdbarch, val));
printf_filtered (_("an argument at offset %ld"), val);
break;
- case LOC_LOCAL_ARG:
- printf_filtered (_("an argument at frame offset %ld"), val);
- break;
-
case LOC_LOCAL:
printf_filtered (_("a local variable at frame offset %ld"), val);
break;
printf_filtered (_("a reference argument at offset %ld"), val);
break;
- case LOC_BASEREG:
- printf_filtered (_("a variable at offset %ld from register %s"),
- val, gdbarch_register_name (current_gdbarch, basereg));
- break;
-
- case LOC_BASEREG_ARG:
- printf_filtered (_("an argument at offset %ld from register %s"),
- val, gdbarch_register_name (current_gdbarch, basereg));
- break;
-
case LOC_TYPEDEF:
printf_filtered (_("a typedef"));
break;
case LOC_BLOCK:
printf_filtered (_("a function at address "));
load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (_(",\n -- loaded at "));
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
printf_filtered (_(" in overlay section %s"), section->name);
}
break;
section = SYMBOL_BFD_SECTION (msym);
printf_filtered (_("static storage at address "));
load_addr = SYMBOL_VALUE_ADDRESS (msym);
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (_(",\n -- loaded at "));
- deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+ fputs_filtered (paddress (load_addr), gdb_stdout);
printf_filtered (_(" in overlay section %s"), section->name);
}
}
}
break;
- case LOC_HP_THREAD_LOCAL_STATIC:
- printf_filtered (_("\
-a thread-local variable at offset %ld from the thread base register %s"),
- val, gdbarch_register_name (current_gdbarch, basereg));
- break;
-
case LOC_OPTIMIZED_OUT:
printf_filtered (_("optimized out"));
break;
{
int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0;
int seen_space = 0, seen_plus = 0;
- int seen_big_l = 0, seen_h = 0;
+ int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
+ int seen_big_d = 0, seen_double_big_d = 0;
int bad = 0;
/* Check the validity of the format specifier, and work
seen_big_l = 1;
f++;
}
+ /* Decimal32 modifier. */
+ else if (*f == 'H')
+ {
+ seen_big_h = 1;
+ f++;
+ }
+ /* Decimal64 and Decimal128 modifiers. */
+ else if (*f == 'D')
+ {
+ f++;
+
+ /* Check for a Decimal128. */
+ if (*f == 'D')
+ {
+ f++;
+ seen_double_big_d = 1;
+ }
+ else
+ seen_big_d = 1;
+ }
switch (*f)
{
bad = 1;
break;
- /* DFP Decimal32 types. */
- case 'H':
- this_argclass = decfloat_arg;
-
-#ifndef PRINTF_HAS_DECFLOAT
- if (lcount || seen_h || seen_big_l)
- bad = 1;
- if (seen_prec || seen_zero || seen_space || seen_plus)
- bad = 1;
-#endif
- break;
-
- /* DFP Decimal64 and Decimal128 types. */
- case 'D':
- this_argclass = decfloat_arg;
-
-#ifndef PRINTF_HAS_DECFLOAT
- if (lcount || seen_h || seen_big_l)
- bad = 1;
- if (seen_prec || seen_zero || seen_space || seen_plus)
- bad = 1;
-#endif
- /* Check for a Decimal128. */
- if (*(f + 1) == 'D')
- f++;
-
- break;
-
case 'c':
this_argclass = int_arg;
if (lcount || seen_h || seen_big_l)
case 'g':
case 'E':
case 'G':
- if (seen_big_l)
+ if (seen_big_h || seen_big_d || seen_double_big_d)
+ this_argclass = decfloat_arg;
+ else if (seen_big_l)
this_argclass = long_double_arg;
else
this_argclass = double_arg;
*f);
f++;
- strncpy (current_substring, last_arg, f - last_arg);
- current_substring += f - last_arg;
+
+ if (lcount > 1 && USE_PRINTF_I64)
+ {
+ /* Windows' printf does support long long, but not the usual way.
+ Convert %lld to %I64d. */
+ int length_before_ll = f - last_arg - 1 - lcount;
+ strncpy (current_substring, last_arg, length_before_ll);
+ strcpy (current_substring + length_before_ll, "I64");
+ current_substring[length_before_ll + 3] =
+ last_arg[length_before_ll + lcount];
+ current_substring += length_before_ll + 4;
+ }
+ else
+ {
+ strncpy (current_substring, last_arg, f - last_arg);
+ current_substring += f - last_arg;
+ }
*current_substring++ = '\0';
last_arg = f;
argclass[nargs_wanted++] = this_argclass;
break;
}
- /* Handles decimal floating point values. */
- case decfloat_arg:
+ /* Handles decimal floating values. */
+ case decfloat_arg:
{
- char *eos;
- char decstr[MAX_DECIMAL_STRING];
- unsigned int dfp_len = TYPE_LENGTH (value_type (val_args[i]));
- unsigned char *dfp_value_ptr = (unsigned char *) value_contents_all (val_args[i])
- + value_offset (val_args[i]);
-
+ const gdb_byte *param_ptr = value_contents (val_args[i]);
#if defined (PRINTF_HAS_DECFLOAT)
- printf_filtered (current_substring, dfp_value_ptr);
+ /* If we have native support for Decimal floating
+ printing, handle it here. */
+ printf_filtered (current_substring, param_ptr);
#else
- if (TYPE_CODE (value_type (val_args[i])) != TYPE_CODE_DECFLOAT)
- error (_("Cannot convert parameter to decfloat."));
/* 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. */
- decimal_to_string (dfp_value_ptr, dfp_len, decstr);
+ we convert the DFP values to string and print them using
+ the %s format specifier. */
+
+ char *eos, *sos;
+ int nnull_chars = 0;
+
+ /* Parameter data. */
+ struct type *param_type = value_type (val_args[i]);
+ unsigned int param_len = TYPE_LENGTH (param_type);
+
+ /* 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 format specifiers. */
+ and check for DFP length modifiers. */
eos = current_substring + strlen (current_substring);
- /* Replace %H, %D and %DD with %s's. */
- while (*--eos != '%')
- if (*eos == 'D' && *(eos - 1) == 'D')
- {
- *(eos - 1) = 's';
-
- /* If we've found a %DD format specifier we need to go
- through the whole string pulling back one character
- since this format specifier has two chars. */
- while (eos < last_arg)
- {
- *eos = *(eos + 1);
- eos++;
- }
- }
- else if (*eos == 'D' || *eos == 'H')
- *eos = 's';
+ /* Look for the float/double format specifier. */
+ while (*eos != 'f' && *eos != 'e' && *eos != 'E'
+ && *eos != 'g' && *eos != 'G')
+ eos--;
+
+ sos = eos;
+
+ /* Search for the '%' char and extract the size and type of
+ the output decimal value based on its modifiers
+ (%Hf, %Df, %DDf). */
+ while (*--sos != '%')
+ {
+ if (*sos == 'H')
+ {
+ dfp_len = 4;
+ dfp_type = builtin_type (current_gdbarch)->builtin_decfloat;
+ }
+ else if (*sos == 'D' && *(sos - 1) == 'D')
+ {
+ dfp_len = 16;
+ dfp_type = builtin_type (current_gdbarch)->builtin_declong;
+ sos--;
+ }
+ else
+ {
+ dfp_len = 8;
+ dfp_type = builtin_type (current_gdbarch)->builtin_decdouble;
+ }
+ }
+
+ /* Replace %Hf, %Df and %DDf with %s's. */
+ *++sos = 's';
+
+ /* Go through the whole format string and pull the correct
+ number of chars back to compensate for the change in the
+ format specifier. */
+ while (nnull_chars < nargs - i)
+ {
+ if (*eos == '\0')
+ nnull_chars++;
+
+ *++sos = *++eos;
+ }
+
+ /* Conversion between different DFP types. */
+ if (TYPE_CODE (param_type) == TYPE_CODE_DECFLOAT)
+ decimal_convert (param_ptr, param_len, dec, dfp_len);
+ 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, "0");
+
+ dfp_value = value_from_decfloat (dfp_type, dec);
+
+ dfp_ptr = (gdb_byte *) value_contents (dfp_value);
+
+ decimal_to_string (dfp_ptr, dfp_len, decstr);
/* Print the DFP value. */
printf_filtered (current_substring, decstr);
+
break;
#endif
}
The argument is the function name and arguments, in the notation of the\n\
current working language. The result is printed and saved in the value\n\
history, if it is not void."));
- set_cmd_completer (c, location_completer);
+ set_cmd_completer (c, expression_completer);
add_cmd ("variable", class_vars, set_command, _("\
Evaluate expression EXP and assign result to variable VAR, using assignment\n\
\n\
EXP may be preceded with /FMT, where FMT is a format letter\n\
but no count or size letter (see \"x\" command)."));
- set_cmd_completer (c, location_completer);
+ set_cmd_completer (c, expression_completer);
add_com_alias ("p", "print", class_vars, 1);
c = add_com ("inspect", class_vars, inspect_command, _("\
Same as \"print\" command, except that if you are running in the epoch\n\
environment, the value is printed in its own window."));
- set_cmd_completer (c, location_completer);
+ set_cmd_completer (c, expression_completer);
add_setshow_uinteger_cmd ("max-symbolic-offset", no_class,
&max_symbolic_offset, _("\