/* Print values for GNU debugger GDB.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "block.h"
#include "disasm.h"
#include "target-float.h"
-#include "observer.h"
+#include "observable.h"
#include "solist.h"
#include "parser-defs.h"
#include "charset.h"
#include "arch-utils.h"
#include "cli/cli-utils.h"
#include "cli/cli-script.h"
-#include "format.h"
+#include "cli/cli-style.h"
+#include "common/format.h"
#include "source.h"
#include "common/byte-vector.h"
-#ifdef TUI
-#include "tui/tui.h" /* For tui_active et al. */
-#endif
-
/* Last specified output format. */
static char last_format = 0;
static char last_size = 'w';
+/* Last specified count for the 'x' command. */
+
+static int last_count;
+
/* Default address to examine next, and associated architecture. */
static struct gdbarch *next_gdbarch;
/* Contents of last address examined.
This is not valid past the end of the `x' command! */
-static struct value *last_examine_value;
+static value_ref_ptr last_examine_value;
/* Largest offset between a symbolic value and an address, that will be
printed as `0x1234 <symbol+offset>'. */
break;
}
- while (*p == ' ' || *p == '\t')
- p++;
- *string_ptr = p;
+ *string_ptr = skip_spaces (p);
/* Set defaults for format and size if not specified. */
if (val.format == '?')
struct ui_file *stream,
int do_demangle, const char *leadin)
{
- char *name = NULL;
- char *filename = NULL;
+ std::string name, filename;
int unmapped = 0;
int offset = 0;
int line = 0;
- /* Throw away both name and filename. */
- struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &name);
- make_cleanup (free_current_contents, &filename);
-
if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset,
&filename, &line, &unmapped))
- {
- do_cleanups (cleanup_chain);
- return 0;
- }
+ return 0;
fputs_filtered (leadin, stream);
if (unmapped)
fputs_filtered ("<*", stream);
else
fputs_filtered ("<", stream);
- fputs_filtered (name, stream);
+ fputs_styled (name.c_str (), function_name_style.style (), 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 (print_symbol_filename && !filename.empty ())
{
+ fputs_filtered (line == -1 ? " in " : " at ", stream);
+ fputs_styled (filename.c_str (), file_name_style.style (), stream);
if (line != -1)
- fprintf_filtered (stream, " at %s:%d", filename, line);
- else
- fprintf_filtered (stream, " in %s", filename);
+ fprintf_filtered (stream, ":%d", line);
}
if (unmapped)
fputs_filtered ("*>", stream);
else
fputs_filtered (">", stream);
- do_cleanups (cleanup_chain);
return 1;
}
-/* 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. */
+/* See valprint.h. */
+
int
build_address_symbolic (struct gdbarch *gdbarch,
CORE_ADDR addr, /* IN */
int do_demangle, /* IN */
- char **name, /* OUT */
+ std::string *name, /* OUT */
int *offset, /* OUT */
- char **filename, /* OUT */
+ std::string *filename, /* OUT */
int *line, /* OUT */
int *unmapped) /* OUT */
{
pointer is <function+3>. This matches the ISA behavior. */
addr = gdbarch_addr_bits_remove (gdbarch, addr);
- name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
+ name_location = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (symbol));
if (do_demangle || asm_demangle)
name_temp = SYMBOL_PRINT_NAME (symbol);
else
*offset = addr - name_location;
- *name = xstrdup (name_temp);
+ *name = name_temp;
if (print_symbol_filename)
{
if (sal.symtab)
{
- *filename = xstrdup (symtab_to_filename_for_display (sal.symtab));
+ *filename = symtab_to_filename_for_display (sal.symtab);
*line = sal.line;
}
}
print_address (struct gdbarch *gdbarch,
CORE_ADDR addr, struct ui_file *stream)
{
- fputs_filtered (paddress (gdbarch, addr), stream);
+ fputs_styled (paddress (gdbarch, addr), address_style.style (), stream);
print_address_symbolic (gdbarch, addr, stream, asm_demangle, " ");
}
{
if (opts->addressprint)
{
- fputs_filtered (paddress (gdbarch, addr), stream);
+ fputs_styled (paddress (gdbarch, addr), address_style.style (), stream);
print_address_symbolic (gdbarch, addr, stream, do_demangle, " ");
}
else
object. */
last_examine_address = next_address;
- if (last_examine_value)
- value_free (last_examine_value);
-
/* The value to be displayed is not fetched greedily.
Instead, to avoid the possibility of a fetched value not
being used, its retrieval is delayed until the print code
the disassembler be modified so that LAST_EXAMINE_VALUE
is left with the byte sequence from the last complete
instruction fetched from memory? */
- last_examine_value = value_at_lazy (val_type, next_address);
-
- if (last_examine_value)
- release_value (last_examine_value);
+ last_examine_value
+ = release_value (value_at_lazy (val_type, next_address));
- print_formatted (last_examine_value, size, &opts, gdb_stdout);
+ print_formatted (last_examine_value.get (), size, &opts, gdb_stdout);
/* Display any branch delay slots following the final insn. */
if (format == 'i' && count == 1)
/* Implementation of the "output" command. */
-static void
-output_command (const char *exp, int from_tty)
-{
- output_command_const (exp, from_tty);
-}
-
-/* Like output_command, but takes a const string as argument. */
-
void
-output_command_const (const char *exp, int from_tty)
+output_command (const char *exp, int from_tty)
{
char format = 0;
struct value *val;
info_symbol_command (const char *arg, int from_tty)
{
struct minimal_symbol *msymbol;
- struct objfile *objfile;
struct obj_section *osect;
CORE_ADDR addr, sect_addr;
int matches = 0;
error_no_arg (_("address"));
addr = parse_and_eval_address (arg);
- ALL_OBJSECTIONS (objfile, osect)
- {
- /* Only process each object file once, even if there's a separate
- debug file. */
- if (objfile->separate_debug_objfile_backlink)
- continue;
-
- sect_addr = overlay_mapped_address (addr, osect);
-
- if (obj_section_addr (osect) <= sect_addr
- && sect_addr < obj_section_endaddr (osect)
- && (msymbol
- = lookup_minimal_symbol_by_pc_section (sect_addr, osect).minsym))
+ for (objfile *objfile : current_program_space->objfiles ())
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
{
- const char *obj_name, *mapped, *sec_name, *msym_name;
- const char *loc_string;
- struct cleanup *old_chain;
-
- matches = 1;
- offset = sect_addr - MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
- mapped = section_is_mapped (osect) ? _("mapped") : _("unmapped");
- sec_name = osect->the_bfd_section->name;
- msym_name = MSYMBOL_PRINT_NAME (msymbol);
-
- /* 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)
+ /* Only process each object file once, even if there's a separate
+ debug file. */
+ if (objfile->separate_debug_objfile_backlink)
+ continue;
+
+ sect_addr = overlay_mapped_address (addr, osect);
+
+ if (obj_section_addr (osect) <= sect_addr
+ && sect_addr < obj_section_endaddr (osect)
+ && (msymbol
+ = lookup_minimal_symbol_by_pc_section (sect_addr,
+ osect).minsym))
{
- string_holder = string_printf ("%s + %u", msym_name, offset);
- loc_string = string_holder.c_str ();
- }
- else
- loc_string = msym_name;
-
- gdb_assert (osect->objfile && objfile_name (osect->objfile));
- obj_name = objfile_name (osect->objfile);
-
- if (MULTI_OBJFILE_P ())
- if (pc_in_unmapped_range (addr, osect))
- if (section_is_overlay (osect))
- printf_filtered (_("%s in load address range of "
- "%s overlay section %s of %s\n"),
- loc_string, mapped, sec_name, obj_name);
- else
- printf_filtered (_("%s in load address range of "
- "section %s of %s\n"),
- loc_string, sec_name, obj_name);
- else
- if (section_is_overlay (osect))
- printf_filtered (_("%s in %s overlay section %s of %s\n"),
- loc_string, mapped, sec_name, obj_name);
- else
- printf_filtered (_("%s in section %s of %s\n"),
- loc_string, sec_name, obj_name);
- else
- if (pc_in_unmapped_range (addr, osect))
- if (section_is_overlay (osect))
- printf_filtered (_("%s in load address range of %s overlay "
- "section %s\n"),
- loc_string, mapped, sec_name);
+ const char *obj_name, *mapped, *sec_name, *msym_name;
+ const char *loc_string;
+
+ matches = 1;
+ offset = sect_addr - MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+ mapped = section_is_mapped (osect) ? _("mapped") : _("unmapped");
+ sec_name = osect->the_bfd_section->name;
+ msym_name = MSYMBOL_PRINT_NAME (msymbol);
+
+ /* 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)
+ {
+ string_holder = string_printf ("%s + %u", msym_name, offset);
+ loc_string = string_holder.c_str ();
+ }
else
- printf_filtered (_("%s in load address range of section %s\n"),
- loc_string, sec_name);
- else
- if (section_is_overlay (osect))
- printf_filtered (_("%s in %s overlay section %s\n"),
- loc_string, mapped, sec_name);
+ loc_string = msym_name;
+
+ gdb_assert (osect->objfile && objfile_name (osect->objfile));
+ obj_name = objfile_name (osect->objfile);
+
+ if (MULTI_OBJFILE_P ())
+ if (pc_in_unmapped_range (addr, osect))
+ if (section_is_overlay (osect))
+ printf_filtered (_("%s in load address range of "
+ "%s overlay section %s of %s\n"),
+ loc_string, mapped, sec_name, obj_name);
+ else
+ printf_filtered (_("%s in load address range of "
+ "section %s of %s\n"),
+ loc_string, sec_name, obj_name);
+ else
+ if (section_is_overlay (osect))
+ printf_filtered (_("%s in %s overlay section %s of %s\n"),
+ loc_string, mapped, sec_name, obj_name);
+ else
+ printf_filtered (_("%s in section %s of %s\n"),
+ loc_string, sec_name, obj_name);
else
- printf_filtered (_("%s in section %s\n"),
- loc_string, sec_name);
+ if (pc_in_unmapped_range (addr, osect))
+ if (section_is_overlay (osect))
+ printf_filtered (_("%s in load address range of %s overlay "
+ "section %s\n"),
+ loc_string, mapped, sec_name);
+ else
+ printf_filtered
+ (_("%s in load address range of section %s\n"),
+ loc_string, sec_name);
+ else
+ if (section_is_overlay (osect))
+ printf_filtered (_("%s in %s overlay section %s\n"),
+ loc_string, mapped, sec_name);
+ else
+ printf_filtered (_("%s in section %s\n"),
+ loc_string, sec_name);
+ }
}
- }
if (matches == 0)
printf_filtered (_("No symbol matches %s.\n"), arg);
}
fprintf_symbol_filtered (gdb_stdout, exp,
current_language->la_language, DMGL_ANSI);
printf_filtered ("\" is at ");
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr), address_style.style (),
+ gdb_stdout);
printf_filtered (" in a file compiled without debugging");
section = MSYMBOL_OBJ_SECTION (objfile, msymbol.minsym);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (",\n -- loaded at ");
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr),
+ address_style.style (),
+ gdb_stdout);
printf_filtered (" in overlay section %s",
section->the_bfd_section->name);
}
case LOC_LABEL:
printf_filtered ("a label at address ");
load_addr = SYMBOL_VALUE_ADDRESS (sym);
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr), address_style.style (),
+ gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (",\n -- loaded at ");
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr), address_style.style (),
+ gdb_stdout);
printf_filtered (" in overlay section %s",
section->the_bfd_section->name);
}
case LOC_STATIC:
printf_filtered (_("static storage at address "));
load_addr = SYMBOL_VALUE_ADDRESS (sym);
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr), address_style.style (),
+ gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (_(",\n -- loaded at "));
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr), address_style.style (),
+ gdb_stdout);
printf_filtered (_(" in overlay section %s"),
section->the_bfd_section->name);
}
case LOC_BLOCK:
printf_filtered (_("a function at address "));
- load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ load_addr = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym));
+ fputs_styled (paddress (gdbarch, load_addr), address_style.style (),
+ gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (_(",\n -- loaded at "));
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr), address_style.style (),
+ gdb_stdout);
printf_filtered (_(" in overlay section %s"),
section->the_bfd_section->name);
}
{
struct bound_minimal_symbol msym;
- msym = lookup_minimal_symbol_and_objfile (SYMBOL_LINKAGE_NAME (sym));
+ msym = lookup_bound_minimal_symbol (SYMBOL_LINKAGE_NAME (sym));
if (msym.minsym == NULL)
printf_filtered ("unresolved");
else
{
load_addr = BMSYMBOL_VALUE_ADDRESS (msym);
printf_filtered (_("static storage at address "));
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr),
+ address_style.style (), gdb_stdout);
if (section_is_overlay (section))
{
load_addr = overlay_unmapped_address (load_addr, section);
printf_filtered (_(",\n -- loaded at "));
- fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
+ fputs_styled (paddress (gdbarch, load_addr),
+ address_style.style (),
+ gdb_stdout);
printf_filtered (_(" in overlay section %s"),
section->the_bfd_section->name);
}
fmt.count = 1;
fmt.raw = 0;
+ /* If there is no expression and no format, use the most recent
+ count. */
+ if (exp == nullptr && last_count > 0)
+ fmt.count = last_count;
+
if (exp && *exp == '/')
{
const char *tmp = exp + 1;
exp = (char *) tmp;
}
+ last_count = fmt.count;
+
/* If we have an expression, evaluate it and use it as the address. */
if (exp != 0 && *exp != 0)
last_format = fmt.format;
/* Set a couple of internal variables if appropriate. */
- if (last_examine_value)
+ if (last_examine_value != nullptr)
{
/* Make last address examined available to the user as $_. Use
the correct pointer type. */
struct type *pointer_type
- = lookup_pointer_type (value_type (last_examine_value));
+ = lookup_pointer_type (value_type (last_examine_value.get ()));
set_internalvar (lookup_internalvar ("_"),
value_from_pointer (pointer_type,
last_examine_address));
as $__. If the last value has not been fetched from memory
then don't fetch it now; instead mark it by voiding the $__
variable. */
- if (value_lazy (last_examine_value))
+ if (value_lazy (last_examine_value.get ()))
clear_internalvar (lookup_internalvar ("__"));
else
- set_internalvar (lookup_internalvar ("__"), last_examine_value);
+ set_internalvar (lookup_internalvar ("__"), last_examine_value.get ());
}
}
\f
fmt.raw = 0;
}
- innermost_block = NULL;
+ innermost_block.reset ();
expression_up expr = parse_expression (exp);
newobj = new display ();
newobj->exp_string = xstrdup (exp);
newobj->exp = std::move (expr);
- newobj->block = innermost_block;
+ newobj->block = innermost_block.block ();
newobj->pspace = current_program_space;
newobj->number = ++display_number;
newobj->format = fmt;
TRY
{
- innermost_block = NULL;
+ innermost_block.reset ();
d->exp = parse_expression (d->exp_string);
- d->block = innermost_block;
+ d->block = innermost_block.block ();
}
CATCH (ex, RETURN_MASK_ALL)
{
if (!name)
name = SYMBOL_PRINT_NAME (var);
- fprintf_filtered (stream, "%s%s = ", n_spaces (2 * indent), name);
+ fputs_filtered (n_spaces (2 * indent), stream);
+ fputs_styled (name, variable_name_style.style (), stream);
+ fputs_filtered (" = ", stream);
+
TRY
{
struct value *val;
int j;
tem = value_as_address (value);
+ if (tem == 0)
+ {
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+ fprintf_filtered (stream, format, "(null)");
+ DIAGNOSTIC_POP
+ return;
+ }
/* This is a %s argument. Find the length of the string. */
for (j = 0;; j++)
read_memory (tem, str, j);
str[j] = 0;
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, format, (char *) str);
+ DIAGNOSTIC_POP
}
/* Subroutine of ui_printf to simplify it.
gdb_byte *buf = (gdb_byte *) alloca (wcwidth);
tem = value_as_address (value);
+ if (tem == 0)
+ {
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+ fprintf_filtered (stream, format, "(null)");
+ DIAGNOSTIC_POP
+ return;
+ }
/* This is a %s argument. Find the length of the string. */
for (j = 0;; j += wcwidth)
&output, translit_char);
obstack_grow_str0 (&output, "");
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, format, obstack_base (&output));
+ DIAGNOSTIC_POP
}
/* Subroutine of ui_printf to simplify it.
/* 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);
/* Determine target type corresponding to the format string. */
struct type *fmt_type;
if (val != 0)
*fmt_p++ = '#';
- /* Copy any width. */
- while (*p >= '0' && *p < '9')
+ /* Copy any width or flags. Only the "-" flag is valid for pointers
+ -- see the format_pieces constructor. */
+ while (*p == '-' || (*p >= '0' && *p < '9'))
*fmt_p++ = *p++;
gdb_assert (*p == 'p' && *(p + 1) == '\0');
*fmt_p++ = 'l';
*fmt_p++ = 'x';
*fmt_p++ = '\0';
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, fmt, val);
+ DIAGNOSTIC_POP
}
else
{
*fmt_p++ = 's';
*fmt_p++ = '\0';
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, fmt, "(nil)");
+ DIAGNOSTIC_POP
}
}
&output, translit_char);
obstack_grow_str0 (&output, "");
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, current_substring,
obstack_base (&output));
+ DIAGNOSTIC_POP
}
break;
case long_long_arg:
{
long long val = value_as_long (val_args[i]);
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, current_substring, val);
+ DIAGNOSTIC_POP
break;
}
#else
{
int val = value_as_long (val_args[i]);
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, current_substring, val);
+ DIAGNOSTIC_POP
break;
}
case long_arg:
{
long val = value_as_long (val_args[i]);
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, current_substring, val);
+ DIAGNOSTIC_POP
break;
}
/* Handles floating-point values. */
have modified GCC to include -Wformat-security by
default, which will warn here if there is no
argument. */
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
fprintf_filtered (stream, current_substring, 0);
+ DIAGNOSTIC_POP
break;
default:
internal_error (__FILE__, __LINE__,
printf_command (const char *arg, int from_tty)
{
ui_printf (arg, gdb_stdout);
+ reset_terminal_style (gdb_stdout);
+ wrap_here ("");
gdb_flush (gdb_stdout);
}
current_display_number = -1;
- observer_attach_free_objfile (clear_dangling_display_expressions);
+ gdb::observers::free_objfile.attach (clear_dangling_display_expressions);
add_info ("address", info_address_command,
_("Describe where symbol SYM is stored."));
Do \"info display\" to see current list of code numbers."), &deletelist);
add_com ("printf", class_vars, printf_command, _("\
-printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
-This is useful for formatted output in user-defined commands."));
+Formatted printing, like the C \"printf\" function.\n\
+Usage: printf \"format string\", arg1, arg2, arg3, ..., argn\n\
+This supports most C printf format specifications, like %s, %d, etc."));
add_com ("output", class_vars, output_command, _("\
Like \"print\" but don't put in value history and don't print newline.\n\
variable in the program being debugged. EXP is any valid expression.\n\
This may usually be abbreviated to simply \"set\"."),
&setlist);
+ add_alias_cmd ("var", "variable", class_vars, 0, &setlist);
c = add_com ("print", class_vars, print_command, _("\
Print value of expression EXP.\n\