#include "exceptions.h"
#include "observer.h"
#include "solist.h"
-#include "solib.h"
#include "parser-defs.h"
#include "charset.h"
#include "arch-utils.h"
/* Characters default to one byte. */
val.size = osize ? 'b' : osize;
break;
+ case 's':
+ /* Display strings with byte size chars unless explicitly specified. */
+ val.size = '\0';
+ break;
+
default:
/* The default is the size most recently specified. */
val.size = osize;
case 's':
{
struct type *elttype = value_type (val);
+
next_address = (value_address (val)
+ val_print_string (elttype,
value_address (val), -1,
- stream, options));
+ stream, options) * len);
}
return;
case 'a':
{
CORE_ADDR addr = unpack_pointer (type, valaddr);
+
print_address (gdbarch, addr, stream);
}
break;
case 'c':
{
struct value_print_options opts = *options;
- opts.format = 0;
+ opts.format = 0;
if (TYPE_UNSIGNED (type))
type = builtin_type (gdbarch)->builtin_true_unsigned_char;
else
struct ui_file *stream, int do_demangle)
{
struct value_print_options opts;
+
get_user_print_options (&opts);
if (addr == 0)
{
next_gdbarch = gdbarch;
next_address = addr;
- /* String or instruction format implies fetch single bytes
- regardless of the specified size. */
- if (format == 's' || format == 'i')
+ /* Instruction format implies fetch single bytes
+ regardless of the specified size.
+ The case of strings is handled in decode_format, only explicit
+ size operator are not changed to 'b'. */
+ if (format == 'i')
size = 'b';
if (size == 'a')
else if (size == 'g')
val_type = builtin_type (next_gdbarch)->builtin_int64;
+ if (format == 's')
+ {
+ struct type *char_type = NULL;
+
+ /* 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;
+ else if (size == 'w')
+ char_type = builtin_type (next_gdbarch)->builtin_char32;
+ if (char_type)
+ val_type = char_type;
+ else
+ {
+ if (size != '\0' && size != 'b')
+ warning (_("Unable to display strings with size '%c', using 'b' \
+instead."), size);
+ size = 'b';
+ val_type = builtin_type (next_gdbarch)->builtin_int8;
+ }
+ }
+
maxelts = 8;
if (size == 'w')
maxelts = 4;
if (exp && *exp)
{
- struct type *type;
expr = parse_expression (exp);
old_chain = make_cleanup (free_current_contents, &expr);
cleanup = 1;
struct expression *expr = parse_expression (exp);
struct cleanup *old_chain =
make_cleanup (free_current_contents, &expr);
+
evaluate_expression (expr);
do_cleanups (old_chain);
}
struct minimal_symbol *msymbol;
long val;
struct obj_section *section;
- CORE_ADDR load_addr;
+ CORE_ADDR load_addr, context_pc = 0;
int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero
if exp is a field of `this'. */
if (exp == 0)
error (_("Argument required."));
- sym = lookup_symbol (exp, get_selected_block (0), VAR_DOMAIN,
+ sym = lookup_symbol (exp, get_selected_block (&context_pc), VAR_DOMAIN,
&is_a_field_of_this);
if (sym == NULL)
{
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, gdb_stdout);
+ SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, context_pc, gdb_stdout);
break;
case LOC_REGISTER:
old_chain = make_cleanup (free_current_contents, &expr);
val = evaluate_expression (expr);
if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
- val = value_ind (val);
+ val = coerce_ref (val);
/* In rvalue contexts, such as this, functions are coerced into
pointers to functions. This makes "x/i main" work. */
if (/* last_format == 'i' && */
do_examine (fmt, next_gdbarch, next_address);
/* If the examine succeeds, we remember its size and format for next
- time. */
- last_size = fmt.size;
+ time. Set last_size to 'b' for strings. */
+ if (fmt.format == 's')
+ last_size = 'b';
+ else
+ last_size = fmt.size;
last_format = fmt.format;
/* Set a couple of internal variables if appropriate. */
if (d->exp == NULL)
{
volatile struct gdb_exception ex;
+
TRY_CATCH (ex, RETURN_MASK_ALL)
{
innermost_block = NULL;
}
}
-/* Return 1 if D uses SOLIB (and will become dangling when SOLIB
- is unloaded), otherwise return 0. */
-
-static int
-display_uses_solib_p (const struct display *d,
- const struct so_list *solib)
-{
- int endpos;
- struct expression *const exp = d->exp;
- const union exp_element *const elts = exp->elts;
-
- if (d->block != NULL
- && d->pspace == solib->pspace
- && solib_contains_address_p (solib, d->block->startaddr))
- return 1;
-
- for (endpos = exp->nelts; endpos > 0; )
- {
- int i, args, oplen = 0;
-
- exp->language_defn->la_exp_desc->operator_length (exp, endpos,
- &oplen, &args);
- gdb_assert (oplen > 0);
-
- i = endpos - oplen;
- if (elts[i].opcode == OP_VAR_VALUE)
- {
- const struct block *const block = elts[i + 1].block;
- const struct symbol *const symbol = elts[i + 2].symbol;
- const struct obj_section *const section =
- SYMBOL_OBJ_SECTION (symbol);
-
- if (block != NULL
- && solib_contains_address_p (solib,
- block->startaddr))
- return 1;
-
- if (section && section->objfile == solib->objfile)
- return 1;
- }
- endpos -= oplen;
- }
-
- return 0;
-}
-
/* display_chain items point to blocks and expressions. Some expressions in
turn may point to symbols.
Both symbols and blocks are obstack_alloc'd on objfile_stack, and are
static void
clear_dangling_display_expressions (struct so_list *solib)
{
+ struct objfile *objfile = solib->objfile;
struct display *d;
- struct objfile *objfile = NULL;
- for (d = display_chain; d; d = d->next)
+ /* With no symbol file we cannot have a block or expression from it. */
+ if (objfile == NULL)
+ return;
+ if (objfile->separate_debug_objfile_backlink)
+ objfile = objfile->separate_debug_objfile_backlink;
+ gdb_assert (objfile->pspace == solib->pspace);
+
+ for (d = display_chain; d != NULL; d = d->next)
{
- if (d->exp && display_uses_solib_p (d, solib))
- {
- xfree (d->exp);
- d->exp = NULL;
- d->block = NULL;
- }
+ if (d->pspace != solib->pspace)
+ continue;
+
+ if (lookup_objfile_from_block (d->block) == objfile
+ || (d->exp && exp_uses_objfile (d->exp, objfile)))
+ {
+ xfree (d->exp);
+ d->exp = NULL;
+ d->block = NULL;
+ }
}
}
\f
/* 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] =
{
/* Convert %ls or %lc to %s. */
int length_before_ls = f - last_arg - 2;
+
strncpy (current_substring, last_arg, length_before_ls);
strcpy (current_substring + length_before_ls, "s");
current_substring += length_before_ls + 2;
while (*s != '\0')
{
char *s1;
+
if (nargs == allocated_args)
val_args = (struct value **) xrealloc ((char *) val_args,
(allocated_args *= 2)
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)
obstack_init (&output);
inner_cleanup = make_cleanup_obstack_free (&output);
- convert_between_encodings (target_wide_charset (byte_order),
+ convert_between_encodings (target_wide_charset (gdbarch),
host_charset (),
str, j, wcwidth,
&output, translit_char);
{
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);
struct type *valtype;
obstack_init (&output);
inner_cleanup = make_cleanup_obstack_free (&output);
- convert_between_encodings (target_wide_charset (byte_order),
+ convert_between_encodings (target_wide_charset (gdbarch),
host_charset (),
bytes, TYPE_LENGTH (valtype),
TYPE_LENGTH (valtype),
#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
{
long long val = value_as_long (val_args[i]);
+
printf_filtered (current_substring, val);
break;
}
case int_arg:
{
int val = value_as_long (val_args[i]);
+
printf_filtered (current_substring, val);
break;
}
case long_arg:
{
long val = value_as_long (val_args[i]);
+
printf_filtered (current_substring, val);
break;
}
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. */
while (*p)
{
int is_percent = (*p == '%');
+
*fmt_p++ = *p++;
if (is_percent)
{
/* Skip to the next substring. */
current_substring += strlen (current_substring) + 1;
}
- /* Print the portion of the format string after the last argument. */
- puts_filtered (last_arg);
+ /* Print the portion of the format string after the last argument.
+ Note that this will not include any ordinary %-specs, but it
+ might include "%%". That is why we use printf_filtered and not
+ puts_filtered here. Also, we pass a dummy argument because
+ some platforms have modified GCC to include -Wformat-security
+ by default, which will warn here if there is no argument. */
+ printf_filtered (last_arg, 0);
}
do_cleanups (old_cleanups);
}