diff options
author | Pedro Alves <palves@redhat.com> | 2017-11-07 12:49:41 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2017-11-07 12:49:41 +0000 |
commit | 598364c2a4bb8fd086763a0eecedfaa581e4b214 (patch) | |
tree | 8e0afe08a36c148a2c4b3e3604e9322d74b851b5 | |
parent | 5e772ff776670f9606b26d2aeda2c618a1410447 (diff) | |
download | binutils-gdb-598364c2a4bb8fd086763a0eecedfaa581e4b214.tar.gz |
x_command
-rw-r--r-- | gdb/printcmd.c | 172 | ||||
-rw-r--r-- | gdb/top.h | 4 |
2 files changed, 100 insertions, 76 deletions
diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 017c7bee07a..da04285b04d 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -49,37 +49,44 @@ #include "format.h" #include "source.h" #include "common/byte-vector.h" +#include "top.h" #ifdef TUI #include "tui/tui.h" /* For tui_active et al. */ #endif -/* Last specified output format. */ +struct current_printcmd_info +{ + /* Last specified output format. */ + char last_format = 0; -static char last_format = 0; + /* Last specified examination size. 'b', 'h', 'w' or `q'. */ + char last_size = 'w'; -/* Last specified examination size. 'b', 'h', 'w' or `q'. */ + /* Default address to examine next, and associated architecture. */ + struct gdbarch *next_gdbarch; + CORE_ADDR next_address; -static char last_size = 'w'; + /* Last address examined. */ + CORE_ADDR last_examine_address; -/* Default address to examine next, and associated architecture. */ + /* Contents of last address examined. This is not valid past the + end of the `x' command! */ + struct value *last_examine_value; +}; -static struct gdbarch *next_gdbarch; -static CORE_ADDR next_address; +static current_printcmd_info & +get_current_printcmd_info () +{ + if (current_ui->curr_printcmd_info == NULL) + current_ui->curr_printcmd_info = new current_printcmd_info (); + return *current_ui->curr_printcmd_info; +} /* Number of delay instructions following current disassembled insn. */ static int branch_delay_insns; -/* Last address examined. */ - -static CORE_ADDR last_examine_address; - -/* Contents of last address examined. - This is not valid past the end of the `x' command! */ - -static struct value *last_examine_value; - /* Largest offset between a symbolic value and an address, that will be printed as `0x1234 <symbol+offset>'. */ @@ -279,8 +286,10 @@ print_formatted (struct value *val, int size, struct type *type = check_typedef (value_type (val)); int len = TYPE_LENGTH (type); + current_printcmd_info &ci = get_current_printcmd_info (); + if (VALUE_LVAL (val) == lval_memory) - next_address = value_address (val) + len; + ci.next_address = value_address (val) + len; if (size) { @@ -290,20 +299,20 @@ print_formatted (struct value *val, int size, { struct type *elttype = value_type (val); - next_address = (value_address (val) - + val_print_string (elttype, NULL, - value_address (val), -1, - stream, options) * len); + ci.next_address = (value_address (val) + + val_print_string (elttype, NULL, + value_address (val), -1, + stream, options) * len); } return; case 'i': /* We often wrap here if there are long symbolic names. */ wrap_here (" "); - next_address = (value_address (val) - + gdb_print_insn (get_type_arch (type), - value_address (val), stream, - &branch_delay_insns)); + ci.next_address = (value_address (val) + + gdb_print_insn (get_type_arch (type), + value_address (val), stream, + &branch_delay_insns)); return; } } @@ -500,10 +509,13 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr) { struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; - next_gdbarch = gdbarch; - next_address = addr; + current_printcmd_info &ci = get_current_printcmd_info (); + + ci.next_gdbarch = gdbarch; + ci.next_address = addr; - /* Make address available to the user as $_. */ + /* Make address available to the user as $_. FIXME: should instead + be a computed val, so that it works Per-UI. */ set_internalvar (lookup_internalvar ("_"), value_from_pointer (ptr_type, addr)); } @@ -976,8 +988,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) format = fmt.format; size = fmt.size; count = fmt.count; - next_gdbarch = gdbarch; - next_address = addr; + + current_printcmd_info &ci = get_current_printcmd_info (); + + ci.next_gdbarch = gdbarch; + ci.next_address = addr; /* Instruction format implies fetch single bytes regardless of the specified size. @@ -989,11 +1004,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) if (size == 'a') { /* Pick the appropriate size for an address. */ - if (gdbarch_ptr_bit (next_gdbarch) == 64) + if (gdbarch_ptr_bit (ci.next_gdbarch) == 64) size = 'g'; - else if (gdbarch_ptr_bit (next_gdbarch) == 32) + else if (gdbarch_ptr_bit (ci.next_gdbarch) == 32) size = 'w'; - else if (gdbarch_ptr_bit (next_gdbarch) == 16) + else if (gdbarch_ptr_bit (ci.next_gdbarch) == 16) size = 'h'; else /* Bad value for gdbarch_ptr_bit. */ @@ -1002,13 +1017,13 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) } if (size == 'b') - val_type = builtin_type (next_gdbarch)->builtin_int8; + val_type = builtin_type (ci.next_gdbarch)->builtin_int8; else if (size == 'h') - val_type = builtin_type (next_gdbarch)->builtin_int16; + val_type = builtin_type (ci.next_gdbarch)->builtin_int16; else if (size == 'w') - val_type = builtin_type (next_gdbarch)->builtin_int32; + val_type = builtin_type (ci.next_gdbarch)->builtin_int32; else if (size == 'g') - val_type = builtin_type (next_gdbarch)->builtin_int64; + val_type = builtin_type (ci.next_gdbarch)->builtin_int64; if (format == 's') { @@ -1017,9 +1032,9 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) /* Search for "char16_t" or "char32_t" types or fall back to 8-bit char if type is not found. */ if (size == 'h') - char_type = builtin_type (next_gdbarch)->builtin_char16; + char_type = builtin_type (ci.next_gdbarch)->builtin_char16; else if (size == 'w') - char_type = builtin_type (next_gdbarch)->builtin_char32; + char_type = builtin_type (ci.next_gdbarch)->builtin_char32; if (char_type) val_type = char_type; else @@ -1028,7 +1043,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) warning (_("Unable to display strings with " "size '%c', using 'b' instead."), size); size = 'b'; - val_type = builtin_type (next_gdbarch)->builtin_int8; + val_type = builtin_type (ci.next_gdbarch)->builtin_int8; } } @@ -1051,26 +1066,26 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) count = -count; if (format == 'i') { - next_address = find_instruction_backward (gdbarch, addr, count, - &count); + ci.next_address = find_instruction_backward (gdbarch, addr, count, + &count); } else if (format == 's') { - next_address = find_string_backward (gdbarch, addr, count, - TYPE_LENGTH (val_type), - &opts, &count); + ci.next_address = find_string_backward (gdbarch, addr, count, + TYPE_LENGTH (val_type), + &opts, &count); } else { - next_address = addr - count * TYPE_LENGTH (val_type); + ci.next_address = addr - count * TYPE_LENGTH (val_type); } /* The following call to print_formatted updates next_address in every iteration. In backward case, we store the start address here and update next_address with it before exiting the function. */ addr_rewound = (format == 's' - ? next_address - TYPE_LENGTH (val_type) - : next_address); + ? ci.next_address - TYPE_LENGTH (val_type) + : ci.next_address); need_to_update_next_address = 1; } @@ -1081,8 +1096,8 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) { QUIT; if (format == 'i') - fputs_filtered (pc_prefix (next_address), gdb_stdout); - print_address (next_gdbarch, next_address, gdb_stdout); + fputs_filtered (pc_prefix (ci.next_address), gdb_stdout); + print_address (ci.next_gdbarch, ci.next_address, gdb_stdout); printf_filtered (":"); for (i = maxelts; i > 0 && count > 0; @@ -1091,10 +1106,10 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) printf_filtered ("\t"); /* Note that print_formatted sets next_address for the next object. */ - last_examine_address = next_address; + ci.last_examine_address = ci.next_address; - if (last_examine_value) - value_free (last_examine_value); + if (ci.last_examine_value) + value_free (ci.last_examine_value); /* The value to be displayed is not fetched greedily. Instead, to avoid the possibility of a fetched value not @@ -1105,12 +1120,12 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) 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); + ci.last_examine_value = value_at_lazy (val_type, ci.next_address); - if (last_examine_value) - release_value (last_examine_value); + if (ci.last_examine_value) + release_value (ci.last_examine_value); - print_formatted (last_examine_value, size, &opts, gdb_stdout); + print_formatted (ci.last_examine_value, size, &opts, gdb_stdout); /* Display any branch delay slots following the final insn. */ if (format == 'i' && count == 1) @@ -1121,7 +1136,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) } if (need_to_update_next_address) - next_address = addr_rewound; + ci.next_address = addr_rewound; } static void @@ -1149,9 +1164,12 @@ print_command_parse_format (const char **expp, const char *cmdname, if (exp && *exp == '/') { exp++; - *fmtp = decode_format (&exp, last_format, 0); + + current_printcmd_info &ci = get_current_printcmd_info (); + + *fmtp = decode_format (&exp, ci.last_format, 0); validate_format (*fmtp, cmdname); - last_format = fmtp->format; + ci.last_format = fmtp->format; } else { @@ -1624,8 +1642,10 @@ x_command (char *exp, int from_tty) struct format_data fmt; struct value *val; - fmt.format = last_format ? last_format : 'x'; - fmt.size = last_size; + current_printcmd_info &ci = get_current_printcmd_info (); + + fmt.format = ci.last_format ? ci.last_format : 'x'; + fmt.size = ci.last_size; fmt.count = 1; fmt.raw = 0; @@ -1633,7 +1653,7 @@ x_command (char *exp, int from_tty) { const char *tmp = exp + 1; - fmt = decode_format (&tmp, last_format, last_size); + fmt = decode_format (&tmp, ci.last_format, ci.last_size); exp = (char *) tmp; } @@ -1655,45 +1675,45 @@ x_command (char *exp, int from_tty) if (/* last_format == 'i' && */ TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC && VALUE_LVAL (val) == lval_memory) - next_address = value_address (val); + ci.next_address = value_address (val); else - next_address = value_as_address (val); + ci.next_address = value_as_address (val); - next_gdbarch = expr->gdbarch; + ci.next_gdbarch = expr->gdbarch; } - if (!next_gdbarch) + if (!ci.next_gdbarch) error_no_arg (_("starting display address")); - do_examine (fmt, next_gdbarch, next_address); + do_examine (fmt, ci.next_gdbarch, ci.next_address); /* If the examine succeeds, we remember its size and format for next time. Set last_size to 'b' for strings. */ if (fmt.format == 's') - last_size = 'b'; + ci.last_size = 'b'; else - last_size = fmt.size; - last_format = fmt.format; + ci.last_size = fmt.size; + ci.last_format = fmt.format; /* Set a couple of internal variables if appropriate. */ - if (last_examine_value) + if (ci.last_examine_value) { /* 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 (ci.last_examine_value)); set_internalvar (lookup_internalvar ("_"), value_from_pointer (pointer_type, - last_examine_address)); + ci.last_examine_address)); /* Make contents of last address examined available to the user 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 (ci.last_examine_value)) clear_internalvar (lookup_internalvar ("__")); else - set_internalvar (lookup_internalvar ("__"), last_examine_value); + set_internalvar (lookup_internalvar ("__"), ci.last_examine_value); } } diff --git a/gdb/top.h b/gdb/top.h index abf5421fb78..7827a5346b7 100644 --- a/gdb/top.h +++ b/gdb/top.h @@ -134,8 +134,12 @@ struct ui /* See enum prompt_state's description. */ enum prompt_state prompt_state; + /* Per-UI info for source.c. Initialized on demand. */ struct current_source_info *curr_source_info = NULL; + /* Per-UI info for printcmd.c. Initialized on demand. */ + struct current_printcmd_info *curr_printcmd_info = NULL; + /* The fields below that start with "m_" are "private". They're meant to be accessed through wrapper macros that make them look like globals. */ |