| Index: gdb/value.c
|
| diff --git a/gdb/value.c b/gdb/value.c
|
| index 218d4d5cbadf035deac53abf00cd8fe40233fb3c..a64e7e117ee64b83905146a0a4250b6650ad549d 100644
|
| --- a/gdb/value.c
|
| +++ b/gdb/value.c
|
| @@ -1,6 +1,6 @@
|
| /* Low level packing and unpacking of values for GDB, the GNU Debugger.
|
|
|
| - Copyright (C) 1986-2000, 2002-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -19,7 +19,7 @@
|
|
|
| #include "defs.h"
|
| #include "arch-utils.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include "symtab.h"
|
| #include "gdbtypes.h"
|
| #include "value.h"
|
| @@ -42,6 +42,7 @@
|
| #include <ctype.h>
|
| #include "tracepoint.h"
|
| #include "cp-abi.h"
|
| +#include "user-regs.h"
|
|
|
| /* Prototypes for exported functions. */
|
|
|
| @@ -196,8 +197,13 @@ struct value
|
| reset, be sure to consider this use as well! */
|
| unsigned int lazy : 1;
|
|
|
| - /* If nonzero, this is the value of a variable which does not
|
| - actually exist in the program. */
|
| + /* If nonzero, this is the value of a variable that does not
|
| + actually exist in the program. If nonzero, and LVAL is
|
| + lval_register, this is a register ($pc, $sp, etc., never a
|
| + program variable) that has not been saved in the frame. All
|
| + optimized-out values are treated pretty much the same, except
|
| + registers have a different string representation and related
|
| + error strings. */
|
| unsigned int optimized_out : 1;
|
|
|
| /* If value is a variable, is it initialized or not. */
|
| @@ -352,6 +358,26 @@ value_entirely_available (struct value *value)
|
| return 0;
|
| }
|
|
|
| +int
|
| +value_entirely_unavailable (struct value *value)
|
| +{
|
| + /* We can only tell whether the whole value is available when we try
|
| + to read it. */
|
| + if (value->lazy)
|
| + value_fetch_lazy (value);
|
| +
|
| + if (VEC_length (range_s, value->unavailable) == 1)
|
| + {
|
| + struct range *t = VEC_index (range_s, value->unavailable, 0);
|
| +
|
| + if (t->offset == 0
|
| + && t->length == TYPE_LENGTH (value_enclosing_type (value)))
|
| + return 1;
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| void
|
| mark_value_bytes_unavailable (struct value *value, int offset, int length)
|
| {
|
| @@ -543,9 +569,7 @@ value_available_contents_eq (const struct value *val1, int offset1,
|
| {
|
| int idx1 = 0, idx2 = 0;
|
|
|
| - /* This routine is used by printing routines, where we should
|
| - already have read the value. Note that we only know whether a
|
| - value chunk is available if we've tried to read it. */
|
| + /* See function description in value.h. */
|
| gdb_assert (!val1->lazy && !val2->lazy);
|
|
|
| while (length > 0)
|
| @@ -688,7 +712,7 @@ allocate_value_lazy (struct type *type)
|
|
|
| /* Allocate the contents of VAL if it has not been allocated yet. */
|
|
|
| -void
|
| +static void
|
| allocate_value_contents (struct value *val)
|
| {
|
| if (!val->contents)
|
| @@ -744,7 +768,7 @@ allocate_optimized_out_value (struct type *type)
|
| struct value *retval = allocate_value_lazy (type);
|
|
|
| set_value_optimized_out (retval, 1);
|
| -
|
| + set_value_lazy (retval, 0);
|
| return retval;
|
| }
|
|
|
| @@ -811,7 +835,12 @@ value_parent (struct value *value)
|
| void
|
| set_value_parent (struct value *value, struct value *parent)
|
| {
|
| + struct value *old = value->parent;
|
| +
|
| value->parent = parent;
|
| + if (parent != NULL)
|
| + value_incref (parent);
|
| + value_free (old);
|
| }
|
|
|
| gdb_byte *
|
| @@ -878,11 +907,22 @@ value_actual_type (struct value *value, int resolve_simple_types,
|
| return result;
|
| }
|
|
|
| +void
|
| +error_value_optimized_out (void)
|
| +{
|
| + error (_("value has been optimized out"));
|
| +}
|
| +
|
| static void
|
| require_not_optimized_out (const struct value *value)
|
| {
|
| if (value->optimized_out)
|
| - error (_("value has been optimized out"));
|
| + {
|
| + if (value->lval == lval_register)
|
| + error (_("register has not been saved in frame"));
|
| + else
|
| + error_value_optimized_out ();
|
| + }
|
| }
|
|
|
| static void
|
| @@ -1037,20 +1077,30 @@ value_contents_equal (struct value *val1, struct value *val2)
|
| {
|
| struct type *type1;
|
| struct type *type2;
|
| - int len;
|
|
|
| type1 = check_typedef (value_type (val1));
|
| type2 = check_typedef (value_type (val2));
|
| - len = TYPE_LENGTH (type1);
|
| - if (len != TYPE_LENGTH (type2))
|
| + if (TYPE_LENGTH (type1) != TYPE_LENGTH (type2))
|
| return 0;
|
|
|
| - return (memcmp (value_contents (val1), value_contents (val2), len) == 0);
|
| + return (memcmp (value_contents (val1), value_contents (val2),
|
| + TYPE_LENGTH (type1)) == 0);
|
| }
|
|
|
| int
|
| value_optimized_out (struct value *value)
|
| {
|
| + /* We can only know if a value is optimized out once we have tried to
|
| + fetch it. */
|
| + if (!value->optimized_out && value->lazy)
|
| + value_fetch_lazy (value);
|
| +
|
| + return value->optimized_out;
|
| +}
|
| +
|
| +int
|
| +value_optimized_out_const (const struct value *value)
|
| +{
|
| return value->optimized_out;
|
| }
|
|
|
| @@ -1199,11 +1249,6 @@ deprecated_value_modifiable (struct value *value)
|
| {
|
| return value->modifiable;
|
| }
|
| -void
|
| -deprecated_set_value_modifiable (struct value *value, int modifiable)
|
| -{
|
| - value->modifiable = modifiable;
|
| -}
|
|
|
| /* Return a mark in the value chain. All values allocated after the
|
| mark is obtained (except for those released) are subject to being freed
|
| @@ -1404,9 +1449,7 @@ value_copy (struct value *arg)
|
|
|
| }
|
| val->unavailable = VEC_copy (range_s, arg->unavailable);
|
| - val->parent = arg->parent;
|
| - if (val->parent)
|
| - value_incref (val->parent);
|
| + set_value_parent (val, arg->parent);
|
| if (VALUE_LVAL (val) == lval_computed)
|
| {
|
| const struct lval_funcs *funcs = val->location.computed.funcs;
|
| @@ -2136,7 +2179,7 @@ function_command (char *command, int from_tty)
|
| static void
|
| function_destroyer (struct cmd_list_element *self, void *ignore)
|
| {
|
| - xfree (self->name);
|
| + xfree ((char *) self->name);
|
| xfree (self->doc);
|
| }
|
|
|
| @@ -2259,11 +2302,17 @@ show_convenience (char *ignore, int from_tty)
|
| printf_filtered (("\n"));
|
| }
|
| if (!varseen)
|
| - printf_unfiltered (_("No debugger convenience variables now defined.\n"
|
| - "Convenience variables have "
|
| - "names starting with \"$\";\n"
|
| - "use \"set\" as in \"set "
|
| - "$foo = 5\" to define them.\n"));
|
| + {
|
| + /* This text does not mention convenience functions on purpose.
|
| + The user can't create them except via Python, and if Python support
|
| + is installed this message will never be printed ($_streq will
|
| + exist). */
|
| + printf_unfiltered (_("No debugger convenience variables now defined.\n"
|
| + "Convenience variables have "
|
| + "names starting with \"$\";\n"
|
| + "use \"set\" as in \"set "
|
| + "$foo = 5\" to define them.\n"));
|
| + }
|
| }
|
|
|
| /* Extract a value as a C number (either long or double).
|
| @@ -2541,8 +2590,7 @@ unpack_pointer (struct type *type, const gdb_byte *valaddr)
|
|
|
|
|
| /* Get the value of the FIELDNO'th field (which must be static) of
|
| - TYPE. Return NULL if the field doesn't exist or has been
|
| - optimized out. */
|
| + TYPE. */
|
|
|
| struct value *
|
| value_static_field (struct type *type, int fieldno)
|
| @@ -2569,7 +2617,7 @@ value_static_field (struct type *type, int fieldno)
|
| NULL, NULL);
|
|
|
| if (!msym)
|
| - return NULL;
|
| + return allocate_optimized_out_value (type);
|
| else
|
| {
|
| retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno),
|
| @@ -2626,9 +2674,7 @@ value_primitive_field (struct value *arg1, int offset,
|
| description correctly. */
|
| check_typedef (type);
|
|
|
| - if (value_optimized_out (arg1))
|
| - v = allocate_optimized_out_value (type);
|
| - else if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
|
| + if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
|
| {
|
| /* Handle packed fields.
|
|
|
| @@ -2642,20 +2688,24 @@ value_primitive_field (struct value *arg1, int offset,
|
| int bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno);
|
| int container_bitsize = TYPE_LENGTH (type) * 8;
|
|
|
| - v = allocate_value_lazy (type);
|
| - v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
|
| - if ((bitpos % container_bitsize) + v->bitsize <= container_bitsize
|
| - && TYPE_LENGTH (type) <= (int) sizeof (LONGEST))
|
| - v->bitpos = bitpos % container_bitsize;
|
| + if (arg1->optimized_out)
|
| + v = allocate_optimized_out_value (type);
|
| else
|
| - v->bitpos = bitpos % 8;
|
| - v->offset = (value_embedded_offset (arg1)
|
| - + offset
|
| - + (bitpos - v->bitpos) / 8);
|
| - v->parent = arg1;
|
| - value_incref (v->parent);
|
| - if (!value_lazy (arg1))
|
| - value_fetch_lazy (v);
|
| + {
|
| + v = allocate_value_lazy (type);
|
| + v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
|
| + if ((bitpos % container_bitsize) + v->bitsize <= container_bitsize
|
| + && TYPE_LENGTH (type) <= (int) sizeof (LONGEST))
|
| + v->bitpos = bitpos % container_bitsize;
|
| + else
|
| + v->bitpos = bitpos % 8;
|
| + v->offset = (value_embedded_offset (arg1)
|
| + + offset
|
| + + (bitpos - v->bitpos) / 8);
|
| + set_value_parent (v, arg1);
|
| + if (!value_lazy (arg1))
|
| + value_fetch_lazy (v);
|
| + }
|
| }
|
| else if (fieldno < TYPE_N_BASECLASSES (arg_type))
|
| {
|
| @@ -2668,29 +2718,37 @@ value_primitive_field (struct value *arg1, int offset,
|
| if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
|
| value_fetch_lazy (arg1);
|
|
|
| - /* We special case virtual inheritance here because this
|
| - requires access to the contents, which we would rather avoid
|
| - for references to ordinary fields of unavailable values. */
|
| - if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno))
|
| - boffset = baseclass_offset (arg_type, fieldno,
|
| - value_contents (arg1),
|
| - value_embedded_offset (arg1),
|
| - value_address (arg1),
|
| - arg1);
|
| - else
|
| - boffset = TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
|
| -
|
| - if (value_lazy (arg1))
|
| - v = allocate_value_lazy (value_enclosing_type (arg1));
|
| + /* The optimized_out flag is only set correctly once a lazy value is
|
| + loaded, having just loaded some lazy values we should check the
|
| + optimized out case now. */
|
| + if (arg1->optimized_out)
|
| + v = allocate_optimized_out_value (type);
|
| else
|
| {
|
| - v = allocate_value (value_enclosing_type (arg1));
|
| - value_contents_copy_raw (v, 0, arg1, 0,
|
| - TYPE_LENGTH (value_enclosing_type (arg1)));
|
| + /* We special case virtual inheritance here because this
|
| + requires access to the contents, which we would rather avoid
|
| + for references to ordinary fields of unavailable values. */
|
| + if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno))
|
| + boffset = baseclass_offset (arg_type, fieldno,
|
| + value_contents (arg1),
|
| + value_embedded_offset (arg1),
|
| + value_address (arg1),
|
| + arg1);
|
| + else
|
| + boffset = TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
|
| +
|
| + if (value_lazy (arg1))
|
| + v = allocate_value_lazy (value_enclosing_type (arg1));
|
| + else
|
| + {
|
| + v = allocate_value (value_enclosing_type (arg1));
|
| + value_contents_copy_raw (v, 0, arg1, 0,
|
| + TYPE_LENGTH (value_enclosing_type (arg1)));
|
| + }
|
| + v->type = type;
|
| + v->offset = value_offset (arg1);
|
| + v->embedded_offset = offset + value_embedded_offset (arg1) + boffset;
|
| }
|
| - v->type = type;
|
| - v->offset = value_offset (arg1);
|
| - v->embedded_offset = offset + value_embedded_offset (arg1) + boffset;
|
| }
|
| else
|
| {
|
| @@ -2701,7 +2759,12 @@ value_primitive_field (struct value *arg1, int offset,
|
| if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
|
| value_fetch_lazy (arg1);
|
|
|
| - if (value_lazy (arg1))
|
| + /* The optimized_out flag is only set correctly once a lazy value is
|
| + loaded, having just loaded some lazy values we should check for
|
| + the optimized out case now. */
|
| + if (arg1->optimized_out)
|
| + v = allocate_optimized_out_value (type);
|
| + else if (value_lazy (arg1))
|
| v = allocate_value_lazy (type);
|
| else
|
| {
|
| @@ -2745,18 +2808,18 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
|
| struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
|
| const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
|
| struct symbol *sym;
|
| - struct minimal_symbol *msym;
|
| + struct bound_minimal_symbol msym;
|
|
|
| sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0);
|
| if (sym != NULL)
|
| {
|
| - msym = NULL;
|
| + memset (&msym, 0, sizeof (msym));
|
| }
|
| else
|
| {
|
| gdb_assert (sym == NULL);
|
| - msym = lookup_minimal_symbol (physname, NULL, NULL);
|
| - if (msym == NULL)
|
| + msym = lookup_bound_minimal_symbol (physname);
|
| + if (msym.minsym == NULL)
|
| return NULL;
|
| }
|
|
|
| @@ -2769,12 +2832,12 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
|
| {
|
| /* The minimal symbol might point to a function descriptor;
|
| resolve it to the actual code address instead. */
|
| - struct objfile *objfile = msymbol_objfile (msym);
|
| + struct objfile *objfile = msym.objfile;
|
| struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
|
|
| set_value_address (v,
|
| gdbarch_convert_from_func_ptr_addr
|
| - (gdbarch, SYMBOL_VALUE_ADDRESS (msym), ¤t_target));
|
| + (gdbarch, SYMBOL_VALUE_ADDRESS (msym.minsym), ¤t_target));
|
| }
|
|
|
| if (arg1p)
|
| @@ -3140,10 +3203,7 @@ value_from_contents_and_address (struct type *type,
|
| if (valaddr == NULL)
|
| v = allocate_value_lazy (type);
|
| else
|
| - {
|
| - v = allocate_value (type);
|
| - memcpy (value_contents_raw (v), valaddr, TYPE_LENGTH (type));
|
| - }
|
| + v = value_from_contents (type, valaddr);
|
| set_value_address (v, address);
|
| VALUE_LVAL (v) = lval_memory;
|
| return v;
|
| @@ -3323,6 +3383,23 @@ coerce_array (struct value *arg)
|
| }
|
|
|
|
|
| +/* Return the return value convention that will be used for the
|
| + specified type. */
|
| +
|
| +enum return_value_convention
|
| +struct_return_convention (struct gdbarch *gdbarch,
|
| + struct value *function, struct type *value_type)
|
| +{
|
| + enum type_code code = TYPE_CODE (value_type);
|
| +
|
| + if (code == TYPE_CODE_ERROR)
|
| + error (_("Function return type unknown."));
|
| +
|
| + /* Probe the architecture for the return-value convention. */
|
| + return gdbarch_return_value (gdbarch, function, value_type,
|
| + NULL, NULL, NULL);
|
| +}
|
| +
|
| /* Return true if the function returning the specified type is using
|
| the convention of returning structures in memory (passing in the
|
| address as a hidden first parameter). */
|
| @@ -3331,19 +3408,12 @@ int
|
| using_struct_return (struct gdbarch *gdbarch,
|
| struct value *function, struct type *value_type)
|
| {
|
| - enum type_code code = TYPE_CODE (value_type);
|
| -
|
| - if (code == TYPE_CODE_ERROR)
|
| - error (_("Function return type unknown."));
|
| -
|
| - if (code == TYPE_CODE_VOID)
|
| + if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
|
| /* A void return value is never in memory. See also corresponding
|
| code in "print_return_value". */
|
| return 0;
|
|
|
| - /* Probe the architecture for the return-value convention. */
|
| - return (gdbarch_return_value (gdbarch, function, value_type,
|
| - NULL, NULL, NULL)
|
| + return (struct_return_convention (gdbarch, function, value_type)
|
| != RETURN_VALUE_REGISTER_CONVENTION);
|
| }
|
|
|
| @@ -3363,18 +3433,227 @@ value_initialized (struct value *val)
|
| return val->initialized;
|
| }
|
|
|
| +/* Called only from the value_contents and value_contents_all()
|
| + macros, if the current data for a variable needs to be loaded into
|
| + value_contents(VAL). Fetches the data from the user's process, and
|
| + clears the lazy flag to indicate that the data in the buffer is
|
| + valid.
|
| +
|
| + If the value is zero-length, we avoid calling read_memory, which
|
| + would abort. We mark the value as fetched anyway -- all 0 bytes of
|
| + it.
|
| +
|
| + This function returns a value because it is used in the
|
| + value_contents macro as part of an expression, where a void would
|
| + not work. The value is ignored. */
|
| +
|
| +int
|
| +value_fetch_lazy (struct value *val)
|
| +{
|
| + gdb_assert (value_lazy (val));
|
| + allocate_value_contents (val);
|
| + if (value_bitsize (val))
|
| + {
|
| + /* To read a lazy bitfield, read the entire enclosing value. This
|
| + prevents reading the same block of (possibly volatile) memory once
|
| + per bitfield. It would be even better to read only the containing
|
| + word, but we have no way to record that just specific bits of a
|
| + value have been fetched. */
|
| + struct type *type = check_typedef (value_type (val));
|
| + enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
|
| + struct value *parent = value_parent (val);
|
| + LONGEST offset = value_offset (val);
|
| + LONGEST num;
|
| +
|
| + if (value_lazy (parent))
|
| + value_fetch_lazy (parent);
|
| +
|
| + if (!value_bits_valid (parent,
|
| + TARGET_CHAR_BIT * offset + value_bitpos (val),
|
| + value_bitsize (val)))
|
| + set_value_optimized_out (val, 1);
|
| + else if (!unpack_value_bits_as_long (value_type (val),
|
| + value_contents_for_printing (parent),
|
| + offset,
|
| + value_bitpos (val),
|
| + value_bitsize (val), parent, &num))
|
| + mark_value_bytes_unavailable (val,
|
| + value_embedded_offset (val),
|
| + TYPE_LENGTH (type));
|
| + else
|
| + store_signed_integer (value_contents_raw (val), TYPE_LENGTH (type),
|
| + byte_order, num);
|
| + }
|
| + else if (VALUE_LVAL (val) == lval_memory)
|
| + {
|
| + CORE_ADDR addr = value_address (val);
|
| + struct type *type = check_typedef (value_enclosing_type (val));
|
| +
|
| + if (TYPE_LENGTH (type))
|
| + read_value_memory (val, 0, value_stack (val),
|
| + addr, value_contents_all_raw (val),
|
| + TYPE_LENGTH (type));
|
| + }
|
| + else if (VALUE_LVAL (val) == lval_register)
|
| + {
|
| + struct frame_info *frame;
|
| + int regnum;
|
| + struct type *type = check_typedef (value_type (val));
|
| + struct value *new_val = val, *mark = value_mark ();
|
| +
|
| + /* Offsets are not supported here; lazy register values must
|
| + refer to the entire register. */
|
| + gdb_assert (value_offset (val) == 0);
|
| +
|
| + while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val))
|
| + {
|
| + struct frame_id frame_id = VALUE_FRAME_ID (new_val);
|
| +
|
| + frame = frame_find_by_id (frame_id);
|
| + regnum = VALUE_REGNUM (new_val);
|
| +
|
| + gdb_assert (frame != NULL);
|
| +
|
| + /* Convertible register routines are used for multi-register
|
| + values and for interpretation in different types
|
| + (e.g. float or int from a double register). Lazy
|
| + register values should have the register's natural type,
|
| + so they do not apply. */
|
| + gdb_assert (!gdbarch_convert_register_p (get_frame_arch (frame),
|
| + regnum, type));
|
| +
|
| + new_val = get_frame_register_value (frame, regnum);
|
| +
|
| + /* If we get another lazy lval_register value, it means the
|
| + register is found by reading it from the next frame.
|
| + get_frame_register_value should never return a value with
|
| + the frame id pointing to FRAME. If it does, it means we
|
| + either have two consecutive frames with the same frame id
|
| + in the frame chain, or some code is trying to unwind
|
| + behind get_prev_frame's back (e.g., a frame unwind
|
| + sniffer trying to unwind), bypassing its validations. In
|
| + any case, it should always be an internal error to end up
|
| + in this situation. */
|
| + if (VALUE_LVAL (new_val) == lval_register
|
| + && value_lazy (new_val)
|
| + && frame_id_eq (VALUE_FRAME_ID (new_val), frame_id))
|
| + internal_error (__FILE__, __LINE__,
|
| + _("infinite loop while fetching a register"));
|
| + }
|
| +
|
| + /* If it's still lazy (for instance, a saved register on the
|
| + stack), fetch it. */
|
| + if (value_lazy (new_val))
|
| + value_fetch_lazy (new_val);
|
| +
|
| + /* If the register was not saved, mark it optimized out. */
|
| + if (value_optimized_out (new_val))
|
| + set_value_optimized_out (val, 1);
|
| + else
|
| + {
|
| + set_value_lazy (val, 0);
|
| + value_contents_copy (val, value_embedded_offset (val),
|
| + new_val, value_embedded_offset (new_val),
|
| + TYPE_LENGTH (type));
|
| + }
|
| +
|
| + if (frame_debug)
|
| + {
|
| + struct gdbarch *gdbarch;
|
| + frame = frame_find_by_id (VALUE_FRAME_ID (val));
|
| + regnum = VALUE_REGNUM (val);
|
| + gdbarch = get_frame_arch (frame);
|
| +
|
| + fprintf_unfiltered (gdb_stdlog,
|
| + "{ value_fetch_lazy "
|
| + "(frame=%d,regnum=%d(%s),...) ",
|
| + frame_relative_level (frame), regnum,
|
| + user_reg_map_regnum_to_name (gdbarch, regnum));
|
| +
|
| + fprintf_unfiltered (gdb_stdlog, "->");
|
| + if (value_optimized_out (new_val))
|
| + {
|
| + fprintf_unfiltered (gdb_stdlog, " ");
|
| + val_print_optimized_out (new_val, gdb_stdlog);
|
| + }
|
| + else
|
| + {
|
| + int i;
|
| + const gdb_byte *buf = value_contents (new_val);
|
| +
|
| + if (VALUE_LVAL (new_val) == lval_register)
|
| + fprintf_unfiltered (gdb_stdlog, " register=%d",
|
| + VALUE_REGNUM (new_val));
|
| + else if (VALUE_LVAL (new_val) == lval_memory)
|
| + fprintf_unfiltered (gdb_stdlog, " address=%s",
|
| + paddress (gdbarch,
|
| + value_address (new_val)));
|
| + else
|
| + fprintf_unfiltered (gdb_stdlog, " computed");
|
| +
|
| + fprintf_unfiltered (gdb_stdlog, " bytes=");
|
| + fprintf_unfiltered (gdb_stdlog, "[");
|
| + for (i = 0; i < register_size (gdbarch, regnum); i++)
|
| + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
|
| + fprintf_unfiltered (gdb_stdlog, "]");
|
| + }
|
| +
|
| + fprintf_unfiltered (gdb_stdlog, " }\n");
|
| + }
|
| +
|
| + /* Dispose of the intermediate values. This prevents
|
| + watchpoints from trying to watch the saved frame pointer. */
|
| + value_free_to_mark (mark);
|
| + }
|
| + else if (VALUE_LVAL (val) == lval_computed
|
| + && value_computed_funcs (val)->read != NULL)
|
| + value_computed_funcs (val)->read (val);
|
| + /* Don't call value_optimized_out on val, doing so would result in a
|
| + recursive call back to value_fetch_lazy, instead check the
|
| + optimized_out flag directly. */
|
| + else if (val->optimized_out)
|
| + /* Keep it optimized out. */;
|
| + else
|
| + internal_error (__FILE__, __LINE__, _("Unexpected lazy value type."));
|
| +
|
| + set_value_lazy (val, 0);
|
| + return 0;
|
| +}
|
| +
|
| +/* Implementation of the convenience function $_isvoid. */
|
| +
|
| +static struct value *
|
| +isvoid_internal_fn (struct gdbarch *gdbarch,
|
| + const struct language_defn *language,
|
| + void *cookie, int argc, struct value **argv)
|
| +{
|
| + int ret;
|
| +
|
| + if (argc != 1)
|
| + error (_("You must provide one argument for $_isvoid."));
|
| +
|
| + ret = TYPE_CODE (value_type (argv[0])) == TYPE_CODE_VOID;
|
| +
|
| + return value_from_longest (builtin_type (gdbarch)->builtin_int, ret);
|
| +}
|
| +
|
| void
|
| _initialize_values (void)
|
| {
|
| add_cmd ("convenience", no_class, show_convenience, _("\
|
| -Debugger convenience (\"$foo\") variables.\n\
|
| -These variables are created when you assign them values;\n\
|
| -thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\
|
| +Debugger convenience (\"$foo\") variables and functions.\n\
|
| +Convenience variables are created when you assign them values;\n\
|
| +thus, \"set $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\
|
| \n\
|
| A few convenience variables are given values automatically:\n\
|
| \"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
|
| -\"$__\" holds the contents of the last address examined with \"x\"."),
|
| - &showlist);
|
| +\"$__\" holds the contents of the last address examined with \"x\"."
|
| +#ifdef HAVE_PYTHON
|
| +"\n\n\
|
| +Convenience functions are defined via the Python API."
|
| +#endif
|
| + ), &showlist);
|
| + add_alias_cmd ("conv", "convenience", no_class, 1, &showlist);
|
|
|
| add_cmd ("values", no_set_class, show_values, _("\
|
| Elements of value history around item number IDX (or last ten)."),
|
| @@ -3390,4 +3669,10 @@ VARIABLE is already initialized."));
|
| add_prefix_cmd ("function", no_class, function_command, _("\
|
| Placeholder command for showing help on convenience functions."),
|
| &functionlist, "function ", 0, &cmdlist);
|
| +
|
| + add_internal_function ("_isvoid", _("\
|
| +Check whether an expression is void.\n\
|
| +Usage: $_isvoid (expression)\n\
|
| +Return 1 if the expression is void, zero otherwise."),
|
| + isvoid_internal_fn, NULL);
|
| }
|
|
|