Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: gdb/value.c

Issue 11969036: Merge GDB 7.5.1 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/value.h ('k') | gdb/varobj.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/value.c
diff --git a/gdb/value.c b/gdb/value.c
index 2a210d75a53e8aca081b131d8164f5789c8bb14e..218d4d5cbadf035deac53abf00cd8fe40233fb3c 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -41,6 +41,7 @@
#include "python/python.h"
#include <ctype.h>
#include "tracepoint.h"
+#include "cp-abi.h"
/* Prototypes for exported functions. */
@@ -167,6 +168,9 @@ ranges_contain (VEC(range_s) *ranges, int offset, int length)
static struct cmd_list_element *functionlist;
+/* Note that the fields in this structure are arranged to save a bit
+ of memory. */
+
struct value
{
/* Type of value; either not an lval, or one of the various
@@ -174,7 +178,37 @@ struct value
enum lval_type lval;
/* Is it modifiable? Only relevant if lval != not_lval. */
- int modifiable;
+ unsigned int modifiable : 1;
+
+ /* If zero, contents of this value are in the contents field. If
+ nonzero, contents are in inferior. If the lval field is lval_memory,
+ the contents are in inferior memory at location.address plus offset.
+ The lval field may also be lval_register.
+
+ WARNING: This field is used by the code which handles watchpoints
+ (see breakpoint.c) to decide whether a particular value can be
+ watched by hardware watchpoints. If the lazy flag is set for
+ some member of a value chain, it is assumed that this member of
+ the chain doesn't need to be watched as part of watching the
+ value itself. This is how GDB avoids watching the entire struct
+ or array when the user wants to watch a single struct member or
+ array element. If you ever change the way lazy flag is set and
+ 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. */
+ unsigned int optimized_out : 1;
+
+ /* If value is a variable, is it initialized or not. */
+ unsigned int initialized : 1;
+
+ /* If value is from the stack. If this is set, read_stack will be
+ used instead of read_memory to enable extra caching. */
+ unsigned int stack : 1;
+
+ /* If the value has been released. */
+ unsigned int released : 1;
/* Location of value (if lval). */
union
@@ -215,6 +249,13 @@ struct value
gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */
int bitpos;
+ /* The number of references to this value. When a value is created,
+ the value chain holds a reference, so REFERENCE_COUNT is 1. If
+ release_value is called, this value is removed from the chain but
+ the caller of release_value now has a reference to this value.
+ The caller must arrange for a call to value_free later. */
+ int reference_count;
+
/* Only used for bitfields; the containing value. This allows a
single read from the target when displaying multiple
bitfields. */
@@ -280,33 +321,6 @@ struct value
/* Register number if the value is from a register. */
short regnum;
- /* If zero, contents of this value are in the contents field. If
- nonzero, contents are in inferior. If the lval field is lval_memory,
- the contents are in inferior memory at location.address plus offset.
- The lval field may also be lval_register.
-
- WARNING: This field is used by the code which handles watchpoints
- (see breakpoint.c) to decide whether a particular value can be
- watched by hardware watchpoints. If the lazy flag is set for
- some member of a value chain, it is assumed that this member of
- the chain doesn't need to be watched as part of watching the
- value itself. This is how GDB avoids watching the entire struct
- or array when the user wants to watch a single struct member or
- array element. If you ever change the way lazy flag is set and
- reset, be sure to consider this use as well! */
- char lazy;
-
- /* If nonzero, this is the value of a variable which does not
- actually exist in the program. */
- char optimized_out;
-
- /* If value is a variable, is it initialized or not. */
- int initialized;
-
- /* If value is from the stack. If this is set, read_stack will be
- used instead of read_memory to enable extra caching. */
- int stack;
-
/* Actual contents of the value. Target byte-order. NULL or not
valid if lazy is nonzero. */
gdb_byte *contents;
@@ -315,13 +329,6 @@ struct value
rather than available, since the common and default case is for a
value to be available. This is filled in at value read time. */
VEC(range_s) *unavailable;
-
- /* The number of references to this value. When a value is created,
- the value chain holds a reference, so REFERENCE_COUNT is 1. If
- release_value is called, this value is removed from the chain but
- the caller of release_value now has a reference to this value.
- The caller must arrange for a call to value_free later. */
- int reference_count;
};
int
@@ -799,6 +806,14 @@ value_parent (struct value *value)
return value->parent;
}
+/* See value.h. */
+
+void
+set_value_parent (struct value *value, struct value *parent)
+{
+ value->parent = parent;
+}
+
gdb_byte *
value_contents_raw (struct value *value)
{
@@ -819,6 +834,50 @@ value_enclosing_type (struct value *value)
return value->enclosing_type;
}
+/* Look at value.h for description. */
+
+struct type *
+value_actual_type (struct value *value, int resolve_simple_types,
+ int *real_type_found)
+{
+ struct value_print_options opts;
+ struct type *result;
+
+ get_user_print_options (&opts);
+
+ if (real_type_found)
+ *real_type_found = 0;
+ result = value_type (value);
+ if (opts.objectprint)
+ {
+ /* If result's target type is TYPE_CODE_STRUCT, proceed to
+ fetch its rtti type. */
+ if ((TYPE_CODE (result) == TYPE_CODE_PTR
+ || TYPE_CODE (result) == TYPE_CODE_REF)
+ && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
+ == TYPE_CODE_STRUCT)
+ {
+ struct type *real_type;
+
+ real_type = value_rtti_indirect_type (value, NULL, NULL, NULL);
+ if (real_type)
+ {
+ if (real_type_found)
+ *real_type_found = 1;
+ result = real_type;
+ }
+ }
+ else if (resolve_simple_types)
+ {
+ if (real_type_found)
+ *real_type_found = 1;
+ result = value_enclosing_type (value);
+ }
+ }
+
+ return result;
+}
+
static void
require_not_optimized_out (const struct value *value)
{
@@ -1094,7 +1153,10 @@ value_address (const struct value *value)
if (value->lval == lval_internalvar
|| value->lval == lval_internalvar_component)
return 0;
- return value->location.address + value->offset;
+ if (value->parent != NULL)
+ return value_address (value->parent) + value->offset;
+ else
+ return value->location.address + value->offset;
}
CORE_ADDR
@@ -1205,6 +1267,7 @@ value_free_to_mark (struct value *mark)
for (val = all_values; val && val != mark; val = next)
{
next = val->next;
+ val->released = 1;
value_free (val);
}
all_values = val;
@@ -1223,6 +1286,7 @@ free_all_values (void)
for (val = all_values; val; val = next)
{
next = val->next;
+ val->released = 1;
value_free (val);
}
@@ -1255,6 +1319,7 @@ release_value (struct value *val)
{
all_values = val->next;
val->next = NULL;
+ val->released = 1;
return;
}
@@ -1264,11 +1329,26 @@ release_value (struct value *val)
{
v->next = val->next;
val->next = NULL;
+ val->released = 1;
break;
}
}
}
+/* If the value is not already released, release it.
+ If the value is already released, increment its reference count.
+ That is, this function ensures that the value is released from the
+ value chain and that the caller owns a reference to it. */
+
+void
+release_value_or_incref (struct value *val)
+{
+ if (val->released)
+ value_incref (val);
+ else
+ release_value (val);
+}
+
/* Release all values up to mark */
struct value *
value_release_to_mark (struct value *mark)
@@ -1277,12 +1357,15 @@ value_release_to_mark (struct value *mark)
struct value *next;
for (val = next = all_values; next; next = next->next)
- if (next->next == mark)
- {
- all_values = next->next;
- next->next = NULL;
- return val;
- }
+ {
+ if (next->next == mark)
+ {
+ all_values = next->next;
+ next->next = NULL;
+ return val;
+ }
+ next->released = 1;
+ }
all_values = 0;
return val;
}
@@ -1549,7 +1632,14 @@ struct internalvar
struct value *value;
/* The call-back routine used with INTERNALVAR_MAKE_VALUE. */
- internalvar_make_value make_value;
+ struct
+ {
+ /* The functions to call. */
+ const struct internalvar_funcs *functions;
+
+ /* The function's user-data. */
+ void *data;
+ } make_value;
/* The internal function used with INTERNALVAR_FUNCTION. */
struct
@@ -1628,6 +1718,29 @@ lookup_only_internalvar (const char *name)
return NULL;
}
+/* Complete NAME by comparing it to the names of internal variables.
+ Returns a vector of newly allocated strings, or NULL if no matches
+ were found. */
+
+VEC (char_ptr) *
+complete_internalvar (const char *name)
+{
+ VEC (char_ptr) *result = NULL;
+ struct internalvar *var;
+ int len;
+
+ len = strlen (name);
+
+ for (var = internalvars; var; var = var->next)
+ if (strncmp (var->name, name, len) == 0)
+ {
+ char *r = xstrdup (var->name);
+
+ VEC_safe_push (char_ptr, result, r);
+ }
+
+ return result;
+}
/* Create an internal variable with name NAME and with a void value.
NAME should not normally include a dollar sign. */
@@ -1648,18 +1761,39 @@ create_internalvar (const char *name)
/* Create an internal variable with name NAME and register FUN as the
function that value_of_internalvar uses to create a value whenever
this variable is referenced. NAME should not normally include a
- dollar sign. */
+ dollar sign. DATA is passed uninterpreted to FUN when it is
+ called. CLEANUP, if not NULL, is called when the internal variable
+ is destroyed. It is passed DATA as its only argument. */
struct internalvar *
-create_internalvar_type_lazy (char *name, internalvar_make_value fun)
+create_internalvar_type_lazy (const char *name,
+ const struct internalvar_funcs *funcs,
+ void *data)
{
struct internalvar *var = create_internalvar (name);
var->kind = INTERNALVAR_MAKE_VALUE;
- var->u.make_value = fun;
+ var->u.make_value.functions = funcs;
+ var->u.make_value.data = data;
return var;
}
+/* See documentation in value.h. */
+
+int
+compile_internalvar_to_ax (struct internalvar *var,
+ struct agent_expr *expr,
+ struct axs_value *value)
+{
+ if (var->kind != INTERNALVAR_MAKE_VALUE
+ || var->u.make_value.functions->compile_to_ax == NULL)
+ return 0;
+
+ var->u.make_value.functions->compile_to_ax (var, expr, value,
+ var->u.make_value.data);
+ return 1;
+}
+
/* Look up an internal variable with name NAME. NAME should not
normally include a dollar sign.
@@ -1732,7 +1866,8 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
break;
case INTERNALVAR_MAKE_VALUE:
- val = (*var->u.make_value) (gdbarch, var);
+ val = (*var->u.make_value.functions->make_value) (gdbarch, var,
+ var->u.make_value.data);
break;
default:
@@ -1928,6 +2063,11 @@ clear_internalvar (struct internalvar *var)
xfree (var->u.string);
break;
+ case INTERNALVAR_MAKE_VALUE:
+ if (var->u.make_value.functions->destroy != NULL)
+ var->u.make_value.functions->destroy (var->u.make_value.data);
+ break;
+
default:
break;
}
@@ -2522,11 +2662,24 @@ value_primitive_field (struct value *arg1, int offset,
/* This field is actually a base subobject, so preserve the
entire object's contents for later references to virtual
bases, etc. */
+ int boffset;
/* Lazy register values with offsets are not supported. */
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));
else
@@ -2537,8 +2690,7 @@ value_primitive_field (struct value *arg1, int offset,
}
v->type = type;
v->offset = value_offset (arg1);
- v->embedded_offset = (offset + value_embedded_offset (arg1)
- + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8);
+ v->embedded_offset = offset + value_embedded_offset (arg1) + boffset;
}
else
{
@@ -2902,7 +3054,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
/* Pack NUM into BUF using a target format of TYPE. */
-void
+static void
pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
{
int len;
@@ -3107,11 +3259,30 @@ coerce_ref_if_computed (const struct value *arg)
return funcs->coerce_ref (arg);
}
+/* Look at value.h for description. */
+
+struct value *
+readjust_indirect_value_type (struct value *value, struct type *enc_type,
+ struct type *original_type,
+ struct value *original_value)
+{
+ /* Re-adjust type. */
+ deprecated_set_value_type (value, TYPE_TARGET_TYPE (original_type));
+
+ /* Add embedding info. */
+ set_value_enclosing_type (value, enc_type);
+ set_value_embedded_offset (value, value_pointed_to_offset (original_value));
+
+ /* We may be pointing to an object of some derived type. */
+ return value_full_object (value, NULL, 0, 0, 0);
+}
+
struct value *
coerce_ref (struct value *arg)
{
struct type *value_type_arg_tmp = check_typedef (value_type (arg));
struct value *retval;
+ struct type *enc_type;
retval = coerce_ref_if_computed (arg);
if (retval)
@@ -3120,9 +3291,14 @@ coerce_ref (struct value *arg)
if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
return arg;
- return value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp),
- unpack_pointer (value_type (arg),
- value_contents (arg)));
+ enc_type = check_typedef (value_enclosing_type (arg));
+ enc_type = TYPE_TARGET_TYPE (enc_type);
+
+ retval = value_at_lazy (enc_type,
+ unpack_pointer (value_type (arg),
+ value_contents (arg)));
+ return readjust_indirect_value_type (retval, enc_type,
+ value_type_arg_tmp, arg);
}
struct value *
@@ -3153,7 +3329,7 @@ coerce_array (struct value *arg)
int
using_struct_return (struct gdbarch *gdbarch,
- struct type *func_type, struct type *value_type)
+ struct value *function, struct type *value_type)
{
enum type_code code = TYPE_CODE (value_type);
@@ -3166,7 +3342,7 @@ using_struct_return (struct gdbarch *gdbarch,
return 0;
/* Probe the architecture for the return-value convention. */
- return (gdbarch_return_value (gdbarch, func_type, value_type,
+ return (gdbarch_return_value (gdbarch, function, value_type,
NULL, NULL, NULL)
!= RETURN_VALUE_REGISTER_CONVENTION);
}
« no previous file with comments | « gdb/value.h ('k') | gdb/varobj.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698