X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fprintcmd.c;h=df44ff474a8c4ce1941ad80141c0c40336014246;hb=5aa03310cef09e8c41aaa05152d9570dfe62ba81;hp=a576d8861216d8e39118fce3a499dd698837f9ad;hpb=5a18e3023970ba2542ebdcbab920acbeabd672ce;p=platform%2Fupstream%2Fbinutils.git diff --git a/gdb/printcmd.c b/gdb/printcmd.c index a576d88..df44ff4 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1,6 +1,6 @@ /* Print values for GNU debugger GDB. - Copyright (C) 1986-2013 Free Software Foundation, Inc. + Copyright (C) 1986-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -18,7 +18,6 @@ along with this program. If not, see . */ #include "defs.h" -#include "gdb_string.h" #include "frame.h" #include "symtab.h" #include "gdbtypes.h" @@ -37,12 +36,9 @@ #include "objfiles.h" /* ditto */ #include "completer.h" /* for completion functions */ #include "ui-out.h" -#include "gdb_assert.h" #include "block.h" #include "disasm.h" #include "dfp.h" -#include "valprint.h" -#include "exceptions.h" #include "observer.h" #include "solist.h" #include "parser-defs.h" @@ -50,6 +46,7 @@ #include "arch-utils.h" #include "cli/cli-utils.h" #include "format.h" +#include "source.h" #ifdef TUI #include "tui/tui.h" /* For tui_active et al. */ @@ -190,10 +187,10 @@ static void do_one_display (struct display *); past the specification and past all whitespace following it. */ static struct format_data -decode_format (char **string_ptr, int oformat, int osize) +decode_format (const char **string_ptr, int oformat, int osize) { struct format_data val; - char *p = *string_ptr; + const char *p = *string_ptr; val.format = '?'; val.size = '?'; @@ -532,6 +529,10 @@ print_scalar_formatted (const void *valaddr, struct type *type, } break; + case 'z': + print_hex_chars (stream, valaddr, len, byte_order); + break; + default: error (_("Undefined output format \"%c\"."), options->format); } @@ -627,7 +628,7 @@ build_address_symbolic (struct gdbarch *gdbarch, int *line, /* OUT */ int *unmapped) /* OUT */ { - struct minimal_symbol *msymbol; + struct bound_minimal_symbol msymbol; struct symbol *symbol; CORE_ADDR name_location = 0; struct obj_section *section = NULL; @@ -676,29 +677,40 @@ build_address_symbolic (struct gdbarch *gdbarch, name_temp = SYMBOL_LINKAGE_NAME (symbol); } - if (msymbol != NULL - && MSYMBOL_HAS_SIZE (msymbol) - && MSYMBOL_SIZE (msymbol) == 0 - && MSYMBOL_TYPE (msymbol) != mst_text - && MSYMBOL_TYPE (msymbol) != mst_text_gnu_ifunc - && MSYMBOL_TYPE (msymbol) != mst_file_text) - msymbol = NULL; + if (msymbol.minsym != NULL + && MSYMBOL_HAS_SIZE (msymbol.minsym) + && MSYMBOL_SIZE (msymbol.minsym) == 0 + && MSYMBOL_TYPE (msymbol.minsym) != mst_text + && MSYMBOL_TYPE (msymbol.minsym) != mst_text_gnu_ifunc + && MSYMBOL_TYPE (msymbol.minsym) != mst_file_text) + msymbol.minsym = NULL; - if (msymbol != NULL) + if (msymbol.minsym != NULL) { - if (SYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL) + if (BMSYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL) { + /* If this is a function (i.e. a code address), strip out any + non-address bits. For instance, display a pointer to the + first instruction of a Thumb function as ; the + second instruction will be , even though the + pointer is . This matches the ISA behavior. */ + if (MSYMBOL_TYPE (msymbol.minsym) == mst_text + || MSYMBOL_TYPE (msymbol.minsym) == mst_text_gnu_ifunc + || MSYMBOL_TYPE (msymbol.minsym) == mst_file_text + || MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline) + addr = gdbarch_addr_bits_remove (gdbarch, addr); + /* The msymbol is closer to the address than the symbol; use the msymbol instead. */ symbol = 0; - name_location = SYMBOL_VALUE_ADDRESS (msymbol); + name_location = BMSYMBOL_VALUE_ADDRESS (msymbol); if (do_demangle || asm_demangle) - name_temp = SYMBOL_PRINT_NAME (msymbol); + name_temp = MSYMBOL_PRINT_NAME (msymbol.minsym); else - name_temp = SYMBOL_LINKAGE_NAME (msymbol); + name_temp = MSYMBOL_LINKAGE_NAME (msymbol.minsym); } } - if (symbol == NULL && msymbol == NULL) + if (symbol == NULL && msymbol.minsym == NULL) return 1; /* If the nearest symbol is too far away, don't print anything symbolic. */ @@ -724,7 +736,7 @@ build_address_symbolic (struct gdbarch *gdbarch, if (sal.symtab) { - *filename = xstrdup (sal.symtab->filename); + *filename = xstrdup (symtab_to_filename_for_display (sal.symtab)); *line = sal.line; } } @@ -932,14 +944,13 @@ validate_format (struct format_data fmt, char *cmdname) first argument ("/x myvar" for example, to print myvar in hex). */ static void -print_command_1 (char *exp, int voidprint) +print_command_1 (const char *exp, int voidprint) { struct expression *expr; - struct cleanup *old_chain = 0; + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); char format = 0; struct value *val; struct format_data fmt; - int cleanup = 0; if (exp && *exp == '/') { @@ -959,8 +970,7 @@ print_command_1 (char *exp, int voidprint) if (exp && *exp) { expr = parse_expression (exp); - old_chain = make_cleanup (free_current_contents, &expr); - cleanup = 1; + make_cleanup (free_current_contents, &expr); val = evaluate_expression (expr); } else @@ -972,16 +982,11 @@ print_command_1 (char *exp, int voidprint) struct value_print_options opts; int histindex = record_latest_value (val); - if (histindex >= 0) - annotate_value_history_begin (histindex, value_type (val)); - else - annotate_value_begin (value_type (val)); + annotate_value_history_begin (histindex, value_type (val)); - if (histindex >= 0) - printf_filtered ("$%d = ", histindex); + printf_filtered ("$%d = ", histindex); - if (histindex >= 0) - annotate_value_history_value (); + annotate_value_history_value (); get_formatted_print_options (&opts, format); opts.raw = fmt.raw; @@ -989,14 +994,10 @@ print_command_1 (char *exp, int voidprint) print_formatted (val, fmt.size, &opts, gdb_stdout); printf_filtered ("\n"); - if (histindex >= 0) - annotate_value_history_end (); - else - annotate_value_end (); + annotate_value_history_end (); } - if (cleanup) - do_cleanups (old_chain); + do_cleanups (old_chain); } static void @@ -1012,9 +1013,19 @@ call_command (char *exp, int from_tty) print_command_1 (exp, 0); } -void +/* Implementation of the "output" command. */ + +static void output_command (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) +{ struct expression *expr; struct cleanup *old_chain; char format = 0; @@ -1104,17 +1115,18 @@ sym_info (char *arg, int from_tty) if (obj_section_addr (osect) <= sect_addr && sect_addr < obj_section_endaddr (osect) - && (msymbol = lookup_minimal_symbol_by_pc_section (sect_addr, osect))) + && (msymbol + = lookup_minimal_symbol_by_pc_section (sect_addr, osect).minsym)) { const char *obj_name, *mapped, *sec_name, *msym_name; char *loc_string; struct cleanup *old_chain; matches = 1; - offset = sect_addr - SYMBOL_VALUE_ADDRESS (msymbol); + offset = sect_addr - MSYMBOL_VALUE_ADDRESS (objfile, msymbol); mapped = section_is_mapped (osect) ? _("mapped") : _("unmapped"); sec_name = osect->the_bfd_section->name; - msym_name = SYMBOL_PRINT_NAME (msymbol); + 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". */ @@ -1127,8 +1139,8 @@ sym_info (char *arg, int from_tty) a pagination request inside printf_filtered. */ old_chain = make_cleanup (xfree, loc_string); - gdb_assert (osect->objfile && osect->objfile->name); - obj_name = osect->objfile->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)) @@ -1177,7 +1189,7 @@ address_info (char *exp, int from_tty) struct gdbarch *gdbarch; int regno; struct symbol *sym; - struct minimal_symbol *msymbol; + struct bound_minimal_symbol msymbol; long val; struct obj_section *section; CORE_ADDR load_addr, context_pc = 0; @@ -1203,12 +1215,14 @@ address_info (char *exp, int from_tty) return; } - msymbol = lookup_minimal_symbol (exp, NULL, NULL); + msymbol = lookup_bound_minimal_symbol (exp); - if (msymbol != NULL) + if (msymbol.minsym != NULL) { - gdbarch = get_objfile_arch (msymbol_objfile (msymbol)); - load_addr = SYMBOL_VALUE_ADDRESS (msymbol); + struct objfile *objfile = msymbol.objfile; + + gdbarch = get_objfile_arch (objfile); + load_addr = BMSYMBOL_VALUE_ADDRESS (msymbol); printf_filtered ("Symbol \""); fprintf_symbol_filtered (gdb_stdout, exp, @@ -1216,7 +1230,7 @@ address_info (char *exp, int from_tty) printf_filtered ("\" is at "); fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout); printf_filtered (" in a file compiled without debugging"); - section = SYMBOL_OBJ_SECTION (msymbol); + section = MSYMBOL_OBJ_SECTION (objfile, msymbol.minsym); if (section_is_overlay (section)) { load_addr = overlay_unmapped_address (load_addr, section); @@ -1237,9 +1251,17 @@ address_info (char *exp, int from_tty) current_language->la_language, DMGL_ANSI); printf_filtered ("\" is "); val = SYMBOL_VALUE (sym); - section = SYMBOL_OBJ_SECTION (sym); + section = SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym); gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile); + if (SYMBOL_COMPUTED_OPS (sym) != NULL) + { + SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, context_pc, + gdb_stdout); + printf_filtered (".\n"); + return; + } + switch (SYMBOL_CLASS (sym)) { case LOC_CONST: @@ -1262,14 +1284,7 @@ address_info (char *exp, int from_tty) break; case LOC_COMPUTED: - /* FIXME: cagney/2004-01-26: It should be possible to - unconditionally call the SYMBOL_COMPUTED_OPS method when available. - Unfortunately DWARF 2 stores the frame-base (instead of the - function) location in a function's symbol. Oops! For the - moment enable this when/where applicable. */ - SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, context_pc, - gdb_stdout); - break; + gdb_assert_not_reached (_("LOC_COMPUTED variable missing a method")); case LOC_REGISTER: /* GDBARCH is the architecture associated with the objfile the symbol @@ -1341,22 +1356,22 @@ address_info (char *exp, int from_tty) case LOC_UNRESOLVED: { - struct minimal_symbol *msym; + struct bound_minimal_symbol msym; - msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (sym), NULL, NULL); - if (msym == NULL) + msym = lookup_minimal_symbol_and_objfile (SYMBOL_LINKAGE_NAME (sym)); + if (msym.minsym == NULL) printf_filtered ("unresolved"); else { - section = SYMBOL_OBJ_SECTION (msym); - load_addr = SYMBOL_VALUE_ADDRESS (msym); + section = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym); + load_addr = BMSYMBOL_VALUE_ADDRESS (msym); if (section && (section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) printf_filtered (_("a thread-local variable at offset %s " "in the thread-local storage for `%s'"), paddress (gdbarch, load_addr), - section->objfile->name); + objfile_name (section->objfile)); else { printf_filtered (_("static storage at address ")); @@ -1401,8 +1416,10 @@ x_command (char *exp, int from_tty) if (exp && *exp == '/') { - exp++; - fmt = decode_format (&exp, last_format, last_size); + const char *tmp = exp + 1; + + fmt = decode_format (&tmp, last_format, last_size); + exp = (char *) tmp; } /* If we have an expression, evaluate it and use it as the address. */ @@ -1472,12 +1489,13 @@ x_command (char *exp, int from_tty) Specify the expression. */ static void -display_command (char *exp, int from_tty) +display_command (char *arg, int from_tty) { struct format_data fmt; struct expression *expr; struct display *new; int display_it = 1; + const char *exp = arg; #if defined(TUI) /* NOTE: cagney/2003-02-13 The `tui_active' was previously @@ -1526,7 +1544,7 @@ display_command (char *exp, int from_tty) new->enabled_p = 1; display_chain = new; - if (from_tty && target_has_execution) + if (from_tty) do_one_display (new); dont_repeat (); @@ -1597,7 +1615,7 @@ map_display_numbers (char *args, while (!state.finished) { - char *p = state.string; + const char *p = state.string; num = get_number_or_range (&state); if (num == 0) @@ -1910,21 +1928,24 @@ disable_display_command (char *args, int from_tty) an item by re-parsing .exp_string field in the new execution context. */ static void -clear_dangling_display_expressions (struct so_list *solib) +clear_dangling_display_expressions (struct objfile *objfile) { - struct objfile *objfile = solib->objfile; struct display *d; + struct program_space *pspace; /* With no symbol file we cannot have a block or expression from it. */ if (objfile == NULL) return; + pspace = objfile->pspace; if (objfile->separate_debug_objfile_backlink) - objfile = objfile->separate_debug_objfile_backlink; - gdb_assert (objfile->pspace == solib->pspace); + { + objfile = objfile->separate_debug_objfile_backlink; + gdb_assert (objfile->pspace == pspace); + } for (d = display_chain; d != NULL; d = d->next) { - if (d->pspace != solib->pspace) + if (d->pspace != pspace) continue; if (lookup_objfile_from_block (d->block) == objfile @@ -1977,13 +1998,247 @@ print_variable_and_value (const char *name, struct symbol *var, fprintf_filtered (stream, "\n"); } +/* Subroutine of ui_printf to simplify it. + Print VALUE to STREAM using FORMAT. + VALUE is a C-style string on the target. */ + +static void +printf_c_string (struct ui_file *stream, const char *format, + struct value *value) +{ + gdb_byte *str; + CORE_ADDR tem; + int j; + + tem = value_as_address (value); + + /* This is a %s argument. Find the length of the string. */ + for (j = 0;; j++) + { + gdb_byte c; + + QUIT; + read_memory (tem + j, &c, 1); + if (c == 0) + break; + } + + /* Copy the string contents into a string inside GDB. */ + str = (gdb_byte *) alloca (j + 1); + if (j != 0) + read_memory (tem, str, j); + str[j] = 0; + + fprintf_filtered (stream, format, (char *) str); +} + +/* Subroutine of ui_printf to simplify it. + Print VALUE to STREAM using FORMAT. + VALUE is a wide C-style string on the target. */ + +static void +printf_wide_c_string (struct ui_file *stream, const char *format, + struct value *value) +{ + gdb_byte *str; + CORE_ADDR tem; + int j; + struct gdbarch *gdbarch = get_type_arch (value_type (value)); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + struct type *wctype = lookup_typename (current_language, gdbarch, + "wchar_t", NULL, 0); + int wcwidth = TYPE_LENGTH (wctype); + gdb_byte *buf = alloca (wcwidth); + struct obstack output; + struct cleanup *inner_cleanup; + + tem = value_as_address (value); + + /* This is a %s argument. Find the length of the string. */ + for (j = 0;; j += wcwidth) + { + QUIT; + read_memory (tem + j, buf, wcwidth); + if (extract_unsigned_integer (buf, wcwidth, byte_order) == 0) + break; + } + + /* Copy the string contents into a string inside GDB. */ + str = (gdb_byte *) alloca (j + wcwidth); + if (j != 0) + read_memory (tem, str, j); + memset (&str[j], 0, wcwidth); + + obstack_init (&output); + inner_cleanup = make_cleanup_obstack_free (&output); + + convert_between_encodings (target_wide_charset (gdbarch), + host_charset (), + str, j, wcwidth, + &output, translit_char); + 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. */ + +static void +printf_decfloat (struct ui_file *stream, const char *format, + struct value *value) +{ + 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 != '%') + { + 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; + } + } + + /* 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"); + + dfp_value = value_from_decfloat (dfp_type, dec); + + dfp_ptr = (gdb_byte *) value_contents (dfp_value); + + decimal_to_string (dfp_ptr, dfp_len, byte_order, decstr); + + /* Print the DFP value. */ + fprintf_filtered (stream, "%s", decstr); +#endif +} + +/* Subroutine of ui_printf to simplify it. + Print VALUE, a target pointer, to STREAM using FORMAT. */ + +static void +printf_pointer (struct ui_file *stream, const char *format, + struct value *value) +{ + /* We avoid the host's %p because pointers are too + likely to be the wrong size. The only interesting + modifier for %p is a width; extract that, and then + handle %p as glibc would: %#x or a literal "(nil)". */ + + const char *p; + char *fmt, *fmt_p; +#ifdef PRINTF_HAS_LONG_LONG + long long val = value_as_long (value); +#else + long val = value_as_long (value); +#endif + + fmt = alloca (strlen (format) + 5); + + /* Copy up to the leading %. */ + p = format; + fmt_p = fmt; + while (*p) + { + int is_percent = (*p == '%'); + + *fmt_p++ = *p++; + if (is_percent) + { + if (*p == '%') + *fmt_p++ = *p++; + else + break; + } + } + + if (val != 0) + *fmt_p++ = '#'; + + /* Copy any width. */ + while (*p >= '0' && *p < '9') + *fmt_p++ = *p++; + + gdb_assert (*p == 'p' && *(p + 1) == '\0'); + if (val != 0) + { +#ifdef PRINTF_HAS_LONG_LONG + *fmt_p++ = 'l'; +#endif + *fmt_p++ = 'l'; + *fmt_p++ = 'x'; + *fmt_p++ = '\0'; + fprintf_filtered (stream, fmt, val); + } + else + { + *fmt_p++ = 's'; + *fmt_p++ = '\0'; + fprintf_filtered (stream, fmt, "(nil)"); + } +} + /* printf "printf format string" ARG to STREAM. */ static void -ui_printf (char *arg, struct ui_file *stream) +ui_printf (const char *arg, struct ui_file *stream) { struct format_piece *fpieces; - char *s = arg; + const char *s = arg; struct value **val_args; int allocated_args = 20; struct cleanup *old_cleanups; @@ -1994,7 +2249,7 @@ ui_printf (char *arg, struct ui_file *stream) if (s == 0) error_no_arg (_("format-control string and values to print")); - s = skip_spaces (s); + s = skip_spaces_const (s); /* A format string should follow, enveloped in double quotes. */ if (*s++ != '"') @@ -2007,14 +2262,14 @@ ui_printf (char *arg, struct ui_file *stream) if (*s++ != '"') error (_("Bad format string, non-terminated '\"'.")); - s = skip_spaces (s); + s = skip_spaces_const (s); if (*s != ',' && *s != 0) error (_("Invalid argument syntax")); if (*s == ',') s++; - s = skip_spaces (s); + s = skip_spaces_const (s); { int nargs = 0; @@ -2032,7 +2287,7 @@ ui_printf (char *arg, struct ui_file *stream) while (*s != '\0') { - char *s1; + const char *s1; if (nargs == allocated_args) val_args = (struct value **) xrealloc ((char *) val_args, @@ -2058,78 +2313,10 @@ ui_printf (char *arg, struct ui_file *stream) switch (fpieces[fr].argclass) { case string_arg: - { - gdb_byte *str; - CORE_ADDR tem; - int j; - - tem = value_as_address (val_args[i]); - - /* This is a %s argument. Find the length of the string. */ - for (j = 0;; j++) - { - gdb_byte c; - - QUIT; - read_memory (tem + j, &c, 1); - if (c == 0) - break; - } - - /* Copy the string contents into a string inside GDB. */ - str = (gdb_byte *) alloca (j + 1); - if (j != 0) - read_memory (tem, str, j); - str[j] = 0; - - fprintf_filtered (stream, current_substring, (char *) str); - } + printf_c_string (stream, current_substring, val_args[i]); break; case wide_string_arg: - { - gdb_byte *str; - CORE_ADDR tem; - int j; - struct gdbarch *gdbarch - = get_type_arch (value_type (val_args[i])); - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - struct type *wctype = lookup_typename (current_language, gdbarch, - "wchar_t", NULL, 0); - int wcwidth = TYPE_LENGTH (wctype); - gdb_byte *buf = alloca (wcwidth); - struct obstack output; - struct cleanup *inner_cleanup; - - tem = value_as_address (val_args[i]); - - /* This is a %s argument. Find the length of the string. */ - for (j = 0;; j += wcwidth) - { - QUIT; - read_memory (tem + j, buf, wcwidth); - if (extract_unsigned_integer (buf, wcwidth, byte_order) == 0) - break; - } - - /* Copy the string contents into a string inside GDB. */ - str = (gdb_byte *) alloca (j + wcwidth); - if (j != 0) - read_memory (tem, str, j); - memset (&str[j], 0, wcwidth); - - obstack_init (&output); - inner_cleanup = make_cleanup_obstack_free (&output); - - convert_between_encodings (target_wide_charset (gdbarch), - host_charset (), - str, j, wcwidth, - &output, translit_char); - obstack_grow_str0 (&output, ""); - - fprintf_filtered (stream, current_substring, - obstack_base (&output)); - do_cleanups (inner_cleanup); - } + printf_wide_c_string (stream, current_substring, val_args[i]); break; case wide_char_arg: { @@ -2226,169 +2413,13 @@ ui_printf (char *arg, struct ui_file *stream) fprintf_filtered (stream, current_substring, val); break; } - /* Handles decimal floating values. */ - case decfloat_arg: - { - const gdb_byte *param_ptr = value_contents (val_args[i]); - -#if defined (PRINTF_HAS_DECFLOAT) - /* If we have native support for Decimal floating - printing, handle it here. */ - fprintf_filtered (stream, current_substring, 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. */ - - char *eos, *sos; - int nnull_chars = 0; - - /* Parameter data. */ - struct type *param_type = value_type (val_args[i]); - 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. */ - eos = current_substring + strlen (current_substring); - - /* 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 (gdbarch)->builtin_decfloat; - } - else if (*sos == 'D' && *(sos - 1) == 'D') - { - dfp_len = 16; - dfp_type = builtin_type (gdbarch)->builtin_declong; - sos--; - } - else - { - dfp_len = 8; - dfp_type = builtin_type (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, 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"); - - dfp_value = value_from_decfloat (dfp_type, dec); - - dfp_ptr = (gdb_byte *) value_contents (dfp_value); - - decimal_to_string (dfp_ptr, dfp_len, byte_order, decstr); - - /* Print the DFP value. */ - fprintf_filtered (stream, current_substring, decstr); - - break; -#endif - } - + case decfloat_arg: + printf_decfloat (stream, current_substring, val_args[i]); + break; case ptr_arg: - { - /* We avoid the host's %p because pointers are too - likely to be the wrong size. The only interesting - modifier for %p is a width; extract that, and then - handle %p as glibc would: %#x or a literal "(nil)". */ - - char *p, *fmt, *fmt_p; -#ifdef PRINTF_HAS_LONG_LONG - long long val = value_as_long (val_args[i]); -#else - long val = value_as_long (val_args[i]); -#endif - - fmt = alloca (strlen (current_substring) + 5); - - /* Copy up to the leading %. */ - p = current_substring; - fmt_p = fmt; - while (*p) - { - int is_percent = (*p == '%'); - - *fmt_p++ = *p++; - if (is_percent) - { - if (*p == '%') - *fmt_p++ = *p++; - else - break; - } - } - - if (val != 0) - *fmt_p++ = '#'; - - /* Copy any width. */ - while (*p >= '0' && *p < '9') - *fmt_p++ = *p++; - - gdb_assert (*p == 'p' && *(p + 1) == '\0'); - if (val != 0) - { -#ifdef PRINTF_HAS_LONG_LONG - *fmt_p++ = 'l'; -#endif - *fmt_p++ = 'l'; - *fmt_p++ = 'x'; - *fmt_p++ = '\0'; - fprintf_filtered (stream, fmt, val); - } - else - { - *fmt_p++ = 's'; - *fmt_p++ = '\0'; - fprintf_filtered (stream, fmt, "(nil)"); - } - - break; - } + printf_pointer (stream, current_substring, val_args[i]); + break; case literal_piece: /* Print a portion of the format string that has no directives. Note that this will not include any @@ -2418,6 +2449,7 @@ static void printf_command (char *arg, int from_tty) { ui_printf (arg, gdb_stdout); + gdb_flush (gdb_stdout); } /* Implement the "eval" command. */ @@ -2446,7 +2478,7 @@ _initialize_printcmd (void) current_display_number = -1; - observer_attach_solib_unloaded (clear_dangling_display_expressions); + observer_attach_free_objfile (clear_dangling_display_expressions); add_info ("address", address_info, _("Describe where symbol SYM is stored.")); @@ -2460,7 +2492,8 @@ Examine memory: x/FMT ADDRESS.\n\ ADDRESS is an expression for the memory address to examine.\n\ FMT is a repeat count followed by a format letter and a size letter.\n\ Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\ - t(binary), f(float), a(address), i(instruction), c(char) and s(string).\n\ + t(binary), f(float), a(address), i(instruction), c(char), s(string)\n\ + and z(hex, zero padded on the left).\n\ Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\ The specified number of objects of the specified size are printed\n\ according to the format.\n\n\ @@ -2587,7 +2620,12 @@ but no count or size letter (see \"x\" command).")); add_setshow_uinteger_cmd ("max-symbolic-offset", no_class, &max_symbolic_offset, _("\ Set the largest offset that will be printed in form."), _("\ -Show the largest offset that will be printed in form."), NULL, +Show the largest offset that will be printed in form."), _("\ +Tell GDB to only display the symbolic form of an address if the\n\ +offset between the closest earlier symbol and the address is less than\n\ +the specified maximum offset. The default is \"unlimited\", which tells GDB\n\ +to always print the symbolic form of an address if any symbol precedes\n\ +it. Zero is equivalent to \"unlimited\"."), NULL, show_max_symbolic_offset, &setprintlist, &showprintlist);