X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvalue.c;h=781808016cde43778c4446b1ae4f0ff02f17b20d;hb=8c9b4171877df495a55b75365203258785da0041;hp=c30cedcd8cfcb2957c1b9d936e256abb58a2f617;hpb=0c7e6dd852f01b3ea38b98c39a2bb36280b02b55;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/value.c b/gdb/value.c index c30cedcd8c..781808016c 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-2018 Free Software Foundation, Inc. + Copyright (C) 1986-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -41,6 +41,9 @@ #include "user-regs.h" #include #include "completer.h" +#include "gdbsupport/selftest.h" +#include "gdbsupport/array-view.h" +#include "cli/cli-style.h" /* Definition of a user function. */ struct internal_function @@ -76,6 +79,12 @@ struct range { return offset < other.offset; } + + /* Returns true if THIS is equal to OTHER. */ + bool operator== (const range &other) const + { + return offset == other.offset && length == other.length; + } }; /* Returns true if the ranges defined by [offset1, offset1+len1) and @@ -172,7 +181,6 @@ struct value type (type_), enclosing_type (type_) { - location.address = 0; } ~value () @@ -186,8 +194,6 @@ struct value } else if (VALUE_LVAL (this) == lval_xcallable) delete location.xm_worker; - - xfree (contents); } DISABLE_COPY_AND_ASSIGN (value); @@ -256,7 +262,7 @@ struct value /* Closure for those functions to use. */ void *closure; } computed; - } location; + } location {}; /* Describes offset of a value within lval of a structure in target addressable memory units. Note also the member embedded_offset @@ -267,8 +273,8 @@ struct value LONGEST bitsize = 0; /* Only used for bitfields; position of start of field. For - gdbarch_bits_big_endian=0 targets, it is the position of the LSB. For - gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */ + little-endian targets, it is the position of the LSB. For + big-endian targets, it is the position of the MSB. */ LONGEST bitpos = 0; /* The number of references to this value. When a value is created, @@ -332,7 +338,7 @@ struct value /* Actual contents of the value. Target byte-order. NULL or not valid if lazy is nonzero. */ - gdb_byte *contents = nullptr; + gdb::unique_xmalloc_ptr contents; /* Unavailable ranges in CONTENTS. We mark unavailable ranges, rather than available, since the common and default case is for a @@ -875,8 +881,8 @@ value_contents_bits_eq (const struct value *val1, int offset1, } /* Compare the available/valid contents. */ - if (memcmp_with_bit_offsets (val1->contents, offset1, - val2->contents, offset2, l) != 0) + if (memcmp_with_bit_offsets (val1->contents.get (), offset1, + val2->contents.get (), offset2, l) != 0) return false; length -= h; @@ -1012,8 +1018,8 @@ allocate_value_contents (struct value *val) if (!val->contents) { check_type_length_before_alloc (val->enclosing_type); - val->contents - = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type)); + val->contents.reset + ((gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type))); } } @@ -1127,7 +1133,7 @@ value_parent (const struct value *value) void set_value_parent (struct value *value, struct value *parent) { - value->parent = value_ref_ptr (value_incref (parent)); + value->parent = value_ref_ptr::new_reference (parent); } gdb_byte * @@ -1137,14 +1143,14 @@ value_contents_raw (struct value *value) int unit_size = gdbarch_addressable_memory_unit_size (arch); allocate_value_contents (value); - return value->contents + value->embedded_offset * unit_size; + return value->contents.get () + value->embedded_offset * unit_size; } gdb_byte * value_contents_all_raw (struct value *value) { allocate_value_contents (value); - return value->contents; + return value->contents.get (); } struct type * @@ -1227,14 +1233,14 @@ value_contents_for_printing (struct value *value) { if (value->lazy) value_fetch_lazy (value); - return value->contents; + return value->contents.get (); } const gdb_byte * value_contents_for_printing_const (const struct value *value) { gdb_assert (!value->lazy); - return value->contents; + return value->contents.get (); } const gdb_byte * @@ -1400,15 +1406,14 @@ value_optimized_out (struct value *value) fetch it. */ if (value->optimized_out.empty () && value->lazy) { - TRY + try { value_fetch_lazy (value); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { /* Fall back to checking value->optimized_out. */ } - END_CATCH } return !value->optimized_out.empty (); @@ -1566,14 +1571,12 @@ value_mark (void) return all_values.back ().get (); } -/* Take a reference to VAL. VAL will not be deallocated until all - references are released. */ +/* See value.h. */ -struct value * +void value_incref (struct value *val) { val->reference_count++; - return val; } /* Release a reference to VAL, which was acquired with value_incref. @@ -1610,8 +1613,6 @@ value_free_to_mark (const struct value *mark) value_ref_ptr release_value (struct value *val) { - struct value *v; - if (val == nullptr) return value_ref_ptr (); @@ -1629,7 +1630,7 @@ release_value (struct value *val) /* We must always return an owned reference. Normally this happens because we transfer the reference from the value chain, but in this case the value was not on the chain. */ - return value_ref_ptr (value_incref (val)); + return value_ref_ptr::new_reference (val); } /* See value.h. */ @@ -1785,8 +1786,6 @@ set_value_component_location (struct value *component, int record_latest_value (struct value *val) { - int i; - /* We don't want this value to have anything to do with the inferior anymore. In particular, "set $1 = 50" should not affect the variable from which the value was taken, and fast watchpoints should be able to assume that @@ -1808,7 +1807,6 @@ record_latest_value (struct value *val) struct value * access_value_history (int num) { - int i; int absnum = num; if (absnum <= 0) @@ -1980,7 +1978,7 @@ init_if_undefined_command (const char* args, int from_tty) intvar = expr->elts[2].internalvar; /* Only evaluate the expression if the lvalue is void. - This may still fail if the expresssion is invalid. */ + This may still fail if the expression is invalid. */ if (intvar->kind == INTERNALVAR_VOID) evaluate_expression (expr.get ()); } @@ -2017,11 +2015,7 @@ complete_internalvar (completion_tracker &tracker, const char *name) for (var = internalvars; var; var = var->next) if (strncmp (var->name, name, len) == 0) - { - gdb::unique_xmalloc_ptr copy (xstrdup (var->name)); - - tracker.add_completion (std::move (copy)); - } + tracker.add_completion (make_unique_xstrdup (var->name)); } /* Create an internal variable with name NAME and with a void value. @@ -2032,7 +2026,7 @@ create_internalvar (const char *name) { struct internalvar *var = XNEW (struct internalvar); - var->name = concat (name, (char *)NULL); + var->name = xstrdup (name); var->kind = INTERNALVAR_VOID; var->next = internalvars; internalvars = var; @@ -2159,7 +2153,7 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var) on this value go back to affect the original internal variable. Do not do this for INTERNALVAR_MAKE_VALUE variables, as those have - no underlying modifyable state in the internal variable. + no underlying modifiable state in the internal variable. Likewise, if the variable's value is a computed lvalue, we want references to it to produce another computed lvalue, where @@ -2276,20 +2270,20 @@ set_internalvar (struct internalvar *var, struct value *val) default: new_kind = INTERNALVAR_VALUE; - new_data.value = value_copy (val); - new_data.value->modifiable = 1; + struct value *copy = value_copy (val); + copy->modifiable = 1; /* Force the value to be fetched from the target now, to avoid problems later when this internalvar is referenced and the target is gone or has changed. */ - if (value_lazy (new_data.value)) - value_fetch_lazy (new_data.value); + if (value_lazy (copy)) + value_fetch_lazy (copy); /* Release the value from the value chain to prevent it from being deleted by free_all_values. From here on this function should not call error () until new_data is installed into the var->u to avoid leaking memory. */ - release_value (new_data.value).release (); + new_data.value = release_value (copy).release (); /* Internal variables which are created from values with a dynamic location don't need the location property of the origin anymore. @@ -2427,33 +2421,43 @@ function_command (const char *command, int from_tty) /* Do nothing. */ } -/* Clean up if an internal function's command is destroyed. */ -static void -function_destroyer (struct cmd_list_element *self, void *ignore) +/* Helper function that does the work for add_internal_function. */ + +static struct cmd_list_element * +do_add_internal_function (const char *name, const char *doc, + internal_function_fn handler, void *cookie) { - xfree ((char *) self->name); - xfree ((char *) self->doc); + struct internal_function *ifn; + struct internalvar *var = lookup_internalvar (name); + + ifn = create_internal_function (name, handler, cookie); + set_internalvar_function (var, ifn); + + return add_cmd (name, no_class, function_command, doc, &functionlist); } -/* Add a new internal function. NAME is the name of the function; DOC - is a documentation string describing the function. HANDLER is - called when the function is invoked. COOKIE is an arbitrary - pointer which is passed to HANDLER and is intended for "user - data". */ +/* See value.h. */ + void add_internal_function (const char *name, const char *doc, internal_function_fn handler, void *cookie) { - struct cmd_list_element *cmd; - struct internal_function *ifn; - struct internalvar *var = lookup_internalvar (name); + do_add_internal_function (name, doc, handler, cookie); +} - ifn = create_internal_function (name, handler, cookie); - set_internalvar_function (var, ifn); +/* See value.h. */ - cmd = add_cmd (xstrdup (name), no_class, function_command, (char *) doc, - &functionlist); - cmd->destroyer = function_destroyer; +void +add_internal_function (gdb::unique_xmalloc_ptr &&name, + gdb::unique_xmalloc_ptr &&doc, + internal_function_fn handler, void *cookie) +{ + struct cmd_list_element *cmd + = do_add_internal_function (name.get (), doc.get (), handler, cookie); + doc.release (); + cmd->doc_allocated = 1; + name.release (); + cmd->name_allocated = 1; } /* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to @@ -2503,7 +2507,6 @@ preserve_values (struct objfile *objfile) { htab_t copied_types; struct internalvar *var; - int i; /* Create the hash table. We allocate on the objfile's obstack, since it is soon to be deleted. */ @@ -2538,18 +2541,18 @@ show_convenience (const char *ignore, int from_tty) } printf_filtered (("$%s = "), var->name); - TRY + try { struct value *val; val = value_of_internalvar (gdbarch, var); value_print (val, gdb_stdout, &opts); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { - fprintf_filtered (gdb_stdout, _(""), ex.message); + fprintf_styled (gdb_stdout, metadata_style.style (), + _(""), ex.what ()); } - END_CATCH printf_filtered (("\n")); } @@ -2586,24 +2589,23 @@ value_from_xmethod (xmethod_worker_up &&worker) /* Return the type of the result of TYPE_CODE_XMETHOD value METHOD. */ struct type * -result_type_of_xmethod (struct value *method, int argc, struct value **argv) +result_type_of_xmethod (struct value *method, gdb::array_view argv) { gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD - && method->lval == lval_xcallable && argc > 0); + && method->lval == lval_xcallable && !argv.empty ()); - return method->location.xm_worker->get_result_type - (argv[0], argv + 1, argc - 1); + return method->location.xm_worker->get_result_type (argv[0], argv.slice (1)); } /* Call the xmethod corresponding to the TYPE_CODE_XMETHOD value METHOD. */ struct value * -call_xmethod (struct value *method, int argc, struct value **argv) +call_xmethod (struct value *method, gdb::array_view argv) { gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD - && method->lval == lval_xcallable && argc > 0); + && method->lval == lval_xcallable && !argv.empty ()); - return method->location.xm_worker->invoke (argv[0], argv + 1, argc - 1); + return method->location.xm_worker->invoke (argv[0], argv.slice (1)); } /* Extract a value as a C number (either long or double). @@ -2745,7 +2747,7 @@ value_as_address (struct value *val) LONGEST unpack_long (struct type *type, const gdb_byte *valaddr) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (type); enum type_code code = TYPE_CODE (type); int len = TYPE_LENGTH (type); int nosign = TYPE_UNSIGNED (type); @@ -2761,10 +2763,16 @@ unpack_long (struct type *type, const gdb_byte *valaddr) case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: case TYPE_CODE_MEMBERPTR: - if (nosign) - return extract_unsigned_integer (valaddr, len, byte_order); - else - return extract_signed_integer (valaddr, len, byte_order); + { + LONGEST result; + if (nosign) + result = extract_unsigned_integer (valaddr, len, byte_order); + else + result = extract_signed_integer (valaddr, len, byte_order); + if (code == TYPE_CODE_RANGE) + result += TYPE_RANGE_DATA (type)->bias; + return result; + } case TYPE_CODE_FLT: case TYPE_CODE_DECFLOAT: @@ -2780,7 +2788,6 @@ unpack_long (struct type *type, const gdb_byte *valaddr) default: error (_("Value can't be converted to integer.")); } - return 0; /* Placate lint. */ } /* Unpack raw data (copied from debugee, target byte order) at VALADDR @@ -2877,7 +2884,8 @@ set_value_enclosing_type (struct value *val, struct type *new_encl_type) { check_type_length_before_alloc (new_encl_type); val->contents - = (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type)); + .reset ((gdb_byte *) xrealloc (val->contents.release (), + TYPE_LENGTH (new_encl_type))); } val->enclosing_type = new_encl_type; @@ -3053,7 +3061,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f, VALUE_LVAL (v) = lval_memory; if (sym) { - set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (sym))); + set_value_address (v, BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym))); } else { @@ -3064,7 +3072,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f, set_value_address (v, gdbarch_convert_from_func_ptr_addr - (gdbarch, BMSYMBOL_VALUE_ADDRESS (msym), ¤t_target)); + (gdbarch, BMSYMBOL_VALUE_ADDRESS (msym), current_top_target ())); } if (arg1p) @@ -3102,7 +3110,7 @@ static LONGEST unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr, LONGEST bitpos, LONGEST bitsize) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (field_type)); + enum bfd_endian byte_order = type_byte_order (field_type); ULONGEST val; ULONGEST valmask; int lsbcount; @@ -3127,7 +3135,7 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr, /* Extract bits. See comment above. */ - if (gdbarch_bits_big_endian (get_type_arch (field_type))) + if (byte_order == BFD_ENDIAN_BIG) lsbcount = (bytes_read * 8 - bitpos % 8 - bitsize); else lsbcount = (bitpos % 8); @@ -3211,7 +3219,7 @@ unpack_value_bitfield (struct value *dest_val, int dst_bit_offset; struct type *field_type = value_type (dest_val); - byte_order = gdbarch_byte_order (get_type_arch (field_type)); + byte_order = type_byte_order (field_type); /* First, unpack and sign extend the bitfield as if it was wholly valid. Optimized out/unavailable bits are read as zero, but @@ -3271,7 +3279,7 @@ void modify_field (struct type *type, gdb_byte *addr, LONGEST fieldval, LONGEST bitpos, LONGEST bitsize) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (type); ULONGEST oword; ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize); LONGEST bytesize; @@ -3303,7 +3311,7 @@ modify_field (struct type *type, gdb_byte *addr, oword = extract_unsigned_integer (addr, bytesize, byte_order); /* Shifting for bit field depends on endianness of the target machine. */ - if (gdbarch_bits_big_endian (get_type_arch (type))) + if (byte_order == BFD_ENDIAN_BIG) bitpos = bytesize * 8 - bitpos - bitsize; oword &= ~(mask << bitpos); @@ -3317,7 +3325,7 @@ modify_field (struct type *type, gdb_byte *addr, void pack_long (gdb_byte *buf, struct type *type, LONGEST num) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (type); LONGEST len; type = check_typedef (type); @@ -3325,12 +3333,14 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num) switch (TYPE_CODE (type)) { + case TYPE_CODE_RANGE: + num -= TYPE_RANGE_DATA (type)->bias; + /* Fall through. */ case TYPE_CODE_INT: case TYPE_CODE_CHAR: case TYPE_CODE_ENUM: case TYPE_CODE_FLAGS: case TYPE_CODE_BOOL: - case TYPE_CODE_RANGE: case TYPE_CODE_MEMBERPTR: store_signed_integer (buf, len, byte_order, num); break; @@ -3363,7 +3373,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) type = check_typedef (type); len = TYPE_LENGTH (type); - byte_order = gdbarch_byte_order (get_type_arch (type)); + byte_order = type_byte_order (type); switch (TYPE_CODE (type)) { @@ -3434,6 +3444,19 @@ value_from_pointer (struct type *type, CORE_ADDR addr) return val; } +/* Create and return a value object of TYPE containing the value D. The + TYPE must be of TYPE_CODE_FLT, and must be large enough to hold D once + it is converted to target format. */ + +struct value * +value_from_host_double (struct type *type, double d) +{ + struct value *value = allocate_value (type); + gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + target_float_from_host_double (value_contents_raw (value), + value_type (value), d); + return value; +} /* Create a value of type TYPE whose contents come from VALADDR, if it is non-null, and whose memory address (in the inferior) is @@ -3716,6 +3739,164 @@ value_initialized (const struct value *val) return val->initialized; } +/* Helper for value_fetch_lazy when the value is a bitfield. */ + +static void +value_fetch_lazy_bitfield (struct value *val) +{ + gdb_assert (value_bitsize (val) != 0); + + /* 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 value *parent = value_parent (val); + + if (value_lazy (parent)) + value_fetch_lazy (parent); + + unpack_value_bitfield (val, value_bitpos (val), value_bitsize (val), + value_contents_for_printing (parent), + value_offset (val), parent); +} + +/* Helper for value_fetch_lazy when the value is in memory. */ + +static void +value_fetch_lazy_memory (struct value *val) +{ + gdb_assert (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_units (type)); +} + +/* Helper for value_fetch_lazy when the value is in a register. */ + +static void +value_fetch_lazy_register (struct value *val) +{ + struct frame_info *next_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 next_frame_id = VALUE_NEXT_FRAME_ID (new_val); + + next_frame = frame_find_by_id (next_frame_id); + regnum = VALUE_REGNUM (new_val); + + gdb_assert (next_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 (next_frame), + regnum, type)); + + /* FRAME was obtained, above, via VALUE_NEXT_FRAME_ID. + Since a "->next" operation was performed when setting + this field, we do not need to perform a "next" operation + again when unwinding the register. That's why + frame_unwind_register_value() is called here instead of + get_frame_register_value(). */ + new_val = frame_unwind_register_value (next_frame, regnum); + + /* If we get another lazy lval_register value, it means the + register is found by reading it from NEXT_FRAME's next frame. + frame_unwind_register_value should never return a value with + the frame id pointing to NEXT_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_NEXT_FRAME_ID (new_val), next_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); + + /* Copy the contents and the unavailability/optimized-out + meta-data from NEW_VAL to VAL. */ + set_value_lazy (val, 0); + value_contents_copy (val, value_embedded_offset (val), + new_val, value_embedded_offset (new_val), + type_length_units (type)); + + if (frame_debug) + { + struct gdbarch *gdbarch; + struct frame_info *frame; + /* VALUE_FRAME_ID is used here, instead of VALUE_NEXT_FRAME_ID, + so that the frame level will be shown correctly. */ + 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); +} + /* Load the actual content of a lazy value. Fetch the data from the user's process and clear the lazy flag to indicate that the data in the buffer is valid. @@ -3735,149 +3916,11 @@ value_fetch_lazy (struct value *val) gdb_assert (val->optimized_out.empty ()); gdb_assert (val->unavailable.empty ()); 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)); - struct value *parent = value_parent (val); - - if (value_lazy (parent)) - value_fetch_lazy (parent); - - unpack_value_bitfield (val, - value_bitpos (val), value_bitsize (val), - value_contents_for_printing (parent), - value_offset (val), parent); - } + value_fetch_lazy_bitfield (val); 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_units (type)); - } + value_fetch_lazy_memory (val); else if (VALUE_LVAL (val) == lval_register) - { - struct frame_info *next_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 next_frame_id = VALUE_NEXT_FRAME_ID (new_val); - - next_frame = frame_find_by_id (next_frame_id); - regnum = VALUE_REGNUM (new_val); - - gdb_assert (next_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 (next_frame), - regnum, type)); - - /* FRAME was obtained, above, via VALUE_NEXT_FRAME_ID. - Since a "->next" operation was performed when setting - this field, we do not need to perform a "next" operation - again when unwinding the register. That's why - frame_unwind_register_value() is called here instead of - get_frame_register_value(). */ - new_val = frame_unwind_register_value (next_frame, regnum); - - /* If we get another lazy lval_register value, it means the - register is found by reading it from NEXT_FRAME's next frame. - frame_unwind_register_value should never return a value with - the frame id pointing to NEXT_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_NEXT_FRAME_ID (new_val), next_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); - - /* Copy the contents and the unavailability/optimized-out - meta-data from NEW_VAL to VAL. */ - set_value_lazy (val, 0); - value_contents_copy (val, value_embedded_offset (val), - new_val, value_embedded_offset (new_val), - type_length_units (type)); - - if (frame_debug) - { - struct gdbarch *gdbarch; - struct frame_info *frame; - /* VALUE_FRAME_ID is used here, instead of VALUE_NEXT_FRAME_ID, - so that the frame level will be shown correctly. */ - 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); - } + value_fetch_lazy_register (val); else if (VALUE_LVAL (val) == lval_computed && value_computed_funcs (val)->read != NULL) value_computed_funcs (val)->read (val); @@ -3904,6 +3947,186 @@ isvoid_internal_fn (struct gdbarch *gdbarch, return value_from_longest (builtin_type (gdbarch)->builtin_int, ret); } +/* Implementation of the convenience function $_creal. Extracts the + real part from a complex number. */ + +static struct value * +creal_internal_fn (struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, int argc, struct value **argv) +{ + if (argc != 1) + error (_("You must provide one argument for $_creal.")); + + value *cval = argv[0]; + type *ctype = check_typedef (value_type (cval)); + if (TYPE_CODE (ctype) != TYPE_CODE_COMPLEX) + error (_("expected a complex number")); + return value_from_component (cval, TYPE_TARGET_TYPE (ctype), 0); +} + +/* Implementation of the convenience function $_cimag. Extracts the + imaginary part from a complex number. */ + +static struct value * +cimag_internal_fn (struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, int argc, + struct value **argv) +{ + if (argc != 1) + error (_("You must provide one argument for $_cimag.")); + + value *cval = argv[0]; + type *ctype = check_typedef (value_type (cval)); + if (TYPE_CODE (ctype) != TYPE_CODE_COMPLEX) + error (_("expected a complex number")); + return value_from_component (cval, TYPE_TARGET_TYPE (ctype), + TYPE_LENGTH (TYPE_TARGET_TYPE (ctype))); +} + +#if GDB_SELF_TEST +namespace selftests +{ + +/* Test the ranges_contain function. */ + +static void +test_ranges_contain () +{ + std::vector ranges; + range r; + + /* [10, 14] */ + r.offset = 10; + r.length = 5; + ranges.push_back (r); + + /* [20, 24] */ + r.offset = 20; + r.length = 5; + ranges.push_back (r); + + /* [2, 6] */ + SELF_CHECK (!ranges_contain (ranges, 2, 5)); + /* [9, 13] */ + SELF_CHECK (ranges_contain (ranges, 9, 5)); + /* [10, 11] */ + SELF_CHECK (ranges_contain (ranges, 10, 2)); + /* [10, 14] */ + SELF_CHECK (ranges_contain (ranges, 10, 5)); + /* [13, 18] */ + SELF_CHECK (ranges_contain (ranges, 13, 6)); + /* [14, 18] */ + SELF_CHECK (ranges_contain (ranges, 14, 5)); + /* [15, 18] */ + SELF_CHECK (!ranges_contain (ranges, 15, 4)); + /* [16, 19] */ + SELF_CHECK (!ranges_contain (ranges, 16, 4)); + /* [16, 21] */ + SELF_CHECK (ranges_contain (ranges, 16, 6)); + /* [21, 21] */ + SELF_CHECK (ranges_contain (ranges, 21, 1)); + /* [21, 25] */ + SELF_CHECK (ranges_contain (ranges, 21, 5)); + /* [26, 28] */ + SELF_CHECK (!ranges_contain (ranges, 26, 3)); +} + +/* Check that RANGES contains the same ranges as EXPECTED. */ + +static bool +check_ranges_vector (gdb::array_view ranges, + gdb::array_view expected) +{ + return ranges == expected; +} + +/* Test the insert_into_bit_range_vector function. */ + +static void +test_insert_into_bit_range_vector () +{ + std::vector ranges; + + /* [10, 14] */ + { + insert_into_bit_range_vector (&ranges, 10, 5); + static const range expected[] = { + {10, 5} + }; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } + + /* [10, 14] */ + { + insert_into_bit_range_vector (&ranges, 11, 4); + static const range expected = {10, 5}; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } + + /* [10, 14] [20, 24] */ + { + insert_into_bit_range_vector (&ranges, 20, 5); + static const range expected[] = { + {10, 5}, + {20, 5}, + }; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } + + /* [10, 14] [17, 24] */ + { + insert_into_bit_range_vector (&ranges, 17, 5); + static const range expected[] = { + {10, 5}, + {17, 8}, + }; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } + + /* [2, 8] [10, 14] [17, 24] */ + { + insert_into_bit_range_vector (&ranges, 2, 7); + static const range expected[] = { + {2, 7}, + {10, 5}, + {17, 8}, + }; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } + + /* [2, 14] [17, 24] */ + { + insert_into_bit_range_vector (&ranges, 9, 1); + static const range expected[] = { + {2, 13}, + {17, 8}, + }; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } + + /* [2, 14] [17, 24] */ + { + insert_into_bit_range_vector (&ranges, 9, 1); + static const range expected[] = { + {2, 13}, + {17, 8}, + }; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } + + /* [2, 33] */ + { + insert_into_bit_range_vector (&ranges, 4, 30); + static const range expected = {2, 32}; + SELF_CHECK (check_ranges_vector (ranges, expected)); + } +} + +} /* namespace selftests */ +#endif /* GDB_SELF_TEST */ + void _initialize_values (void) { @@ -3943,6 +4166,20 @@ Usage: $_isvoid (expression)\n\ Return 1 if the expression is void, zero otherwise."), isvoid_internal_fn, NULL); + add_internal_function ("_creal", _("\ +Extract the real part of a complex number.\n\ +Usage: $_creal (expression)\n\ +Return the real part of a complex number, the type depends on the\n\ +type of a complex number."), + creal_internal_fn, NULL); + + add_internal_function ("_cimag", _("\ +Extract the imaginary part of a complex number.\n\ +Usage: $_cimag (expression)\n\ +Return the imaginary part of a complex number, the type depends on the\n\ +type of a complex number."), + cimag_internal_fn, NULL); + add_setshow_zuinteger_unlimited_cmd ("max-value-size", class_support, &max_value_size, _("\ Set maximum sized value gdb will load from the inferior."), _("\ @@ -3955,4 +4192,17 @@ prevents future values, larger than this size, from being allocated."), set_max_value_size, show_max_value_size, &setlist, &showlist); +#if GDB_SELF_TEST + selftests::register_test ("ranges_contain", selftests::test_ranges_contain); + selftests::register_test ("insert_into_bit_range_vector", + selftests::test_insert_into_bit_range_vector); +#endif +} + +/* See value.h. */ + +void +finalize_values () +{ + all_values.clear (); }