mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-03 15:42:52 +00:00
* value.h (allocate_value_lazy): New function declaration.
(value_free): Remove macro, make it a function. * value.c (value): Move actual content outside of the memory space of the struct; add a pointer to this actual content. (allocate_value_lazy, allocate_value_contents): New function. (allocate_value): Reimplement using these two new functions. (value_contents_raw, value_contents_all_raw): If no memory has been allocated yet for the actual content, allocate it. (value_contents_all): Resync with struct value's changes. (value_free): New function. (value_copy, value_primitive_field): Use new function allocate_value_lazy to allocate lazy values. (value_change_enclosing_type): Resync with struct value's changes. As the value is not reallocated, remove the special handling for the value chain (now obsolete). * valops.c (value_at_lazy): Use new function allocate_value_lazy. (value_fetch_lazy): Allocate value content. Use allocate_value_lazy to allocate lazy values. (value_slice): Use allocate_value_lazy to allocate lazy values.
This commit is contained in:
parent
508e676df1
commit
3e3d7139ee
@ -1,3 +1,25 @@
|
||||
2008-11-26 Jerome Guitton <guitton@adacore.com>
|
||||
|
||||
* value.h (allocate_value_lazy): New function declaration.
|
||||
(value_free): Remove macro, make it a function.
|
||||
* value.c (value): Move actual content outside of the memory space
|
||||
of the struct; add a pointer to this actual content.
|
||||
(allocate_value_lazy, allocate_value_contents): New function.
|
||||
(allocate_value): Reimplement using these two new functions.
|
||||
(value_contents_raw, value_contents_all_raw): If no memory
|
||||
has been allocated yet for the actual content, allocate it.
|
||||
(value_contents_all): Resync with struct value's changes.
|
||||
(value_free): New function.
|
||||
(value_copy, value_primitive_field): Use new function
|
||||
allocate_value_lazy to allocate lazy values.
|
||||
(value_change_enclosing_type): Resync with struct value's changes.
|
||||
As the value is not reallocated, remove the special handling for
|
||||
the value chain (now obsolete).
|
||||
* valops.c (value_at_lazy): Use new function allocate_value_lazy.
|
||||
(value_fetch_lazy): Allocate value content. Use allocate_value_lazy
|
||||
to allocate lazy values.
|
||||
(value_slice): Use allocate_value_lazy to allocate lazy values.
|
||||
|
||||
2008-11-25 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Fix automatic restoration of breakpoints memory for ia64.
|
||||
|
35
gdb/valops.c
35
gdb/valops.c
@ -608,11 +608,10 @@ value_at_lazy (struct type *type, CORE_ADDR addr)
|
||||
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
|
||||
error (_("Attempt to dereference a generic pointer."));
|
||||
|
||||
val = allocate_value (type);
|
||||
val = allocate_value_lazy (type);
|
||||
|
||||
VALUE_LVAL (val) = lval_memory;
|
||||
VALUE_ADDRESS (val) = addr;
|
||||
set_value_lazy (val, 1);
|
||||
|
||||
return val;
|
||||
}
|
||||
@ -634,6 +633,8 @@ value_at_lazy (struct type *type, CORE_ADDR addr)
|
||||
int
|
||||
value_fetch_lazy (struct value *val)
|
||||
{
|
||||
gdb_assert (value_lazy (val));
|
||||
allocate_value_contents (val);
|
||||
if (VALUE_LVAL (val) == lval_memory)
|
||||
{
|
||||
CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
|
||||
@ -1535,7 +1536,7 @@ search_struct_field (char *name, struct value *arg1, int offset,
|
||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||
{
|
||||
int boffset;
|
||||
struct value *v2 = allocate_value (basetype);
|
||||
struct value *v2;
|
||||
|
||||
boffset = baseclass_offset (type, i,
|
||||
value_contents (arg1) + offset,
|
||||
@ -1553,6 +1554,7 @@ search_struct_field (char *name, struct value *arg1, int offset,
|
||||
{
|
||||
CORE_ADDR base_addr;
|
||||
|
||||
v2 = allocate_value (basetype);
|
||||
base_addr =
|
||||
VALUE_ADDRESS (arg1) + value_offset (arg1) + boffset;
|
||||
if (target_read_memory (base_addr,
|
||||
@ -1564,16 +1566,19 @@ search_struct_field (char *name, struct value *arg1, int offset,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
|
||||
v2 = allocate_value_lazy (basetype);
|
||||
else
|
||||
{
|
||||
v2 = allocate_value (basetype);
|
||||
memcpy (value_contents_raw (v2),
|
||||
value_contents_raw (arg1) + boffset,
|
||||
TYPE_LENGTH (basetype));
|
||||
}
|
||||
VALUE_LVAL (v2) = VALUE_LVAL (arg1);
|
||||
VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
|
||||
VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
|
||||
set_value_offset (v2, value_offset (arg1) + boffset);
|
||||
if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
|
||||
set_value_lazy (v2, 1);
|
||||
else
|
||||
memcpy (value_contents_raw (v2),
|
||||
value_contents_raw (arg1) + boffset,
|
||||
TYPE_LENGTH (basetype));
|
||||
}
|
||||
|
||||
if (found_baseclass)
|
||||
@ -2969,13 +2974,15 @@ value_slice (struct value *array, int lowbound, int length)
|
||||
slice_range_type);
|
||||
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
|
||||
|
||||
slice = allocate_value (slice_type);
|
||||
if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
|
||||
set_value_lazy (slice, 1);
|
||||
slice = allocate_value_lazy (slice_type);
|
||||
else
|
||||
memcpy (value_contents_writeable (slice),
|
||||
value_contents (array) + offset,
|
||||
TYPE_LENGTH (slice_type));
|
||||
{
|
||||
slice = allocate_value (slice_type);
|
||||
memcpy (value_contents_writeable (slice),
|
||||
value_contents (array) + offset,
|
||||
TYPE_LENGTH (slice_type));
|
||||
}
|
||||
|
||||
if (VALUE_LVAL (array) == lval_internalvar)
|
||||
VALUE_LVAL (slice) = lval_internalvar_component;
|
||||
|
133
gdb/value.c
133
gdb/value.c
@ -163,21 +163,9 @@ struct value
|
||||
/* If value is a variable, is it initialized or not. */
|
||||
int initialized;
|
||||
|
||||
/* Actual contents of the value. For use of this value; setting it
|
||||
uses the stuff above. Not valid if lazy is nonzero. Target
|
||||
byte-order. We force it to be aligned properly for any possible
|
||||
value. Note that a value therefore extends beyond what is
|
||||
declared here. */
|
||||
union
|
||||
{
|
||||
gdb_byte contents[1];
|
||||
DOUBLEST force_doublest_align;
|
||||
LONGEST force_longest_align;
|
||||
CORE_ADDR force_core_addr_align;
|
||||
void *force_pointer_align;
|
||||
} aligner;
|
||||
/* Do not add any new members here -- contents above will trash
|
||||
them. */
|
||||
/* Actual contents of the value. Target byte-order. NULL or not
|
||||
valid if lazy is nonzero. */
|
||||
gdb_byte *contents;
|
||||
};
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
@ -213,15 +201,18 @@ static int value_history_count; /* Abs number of last entry stored */
|
||||
|
||||
static struct value *all_values;
|
||||
|
||||
/* Allocate a value that has the correct length for type TYPE. */
|
||||
/* Allocate a lazy value for type TYPE. Its actual content is
|
||||
"lazily" allocated too: the content field of the return value is
|
||||
NULL; it will be allocated when it is fetched from the target. */
|
||||
|
||||
struct value *
|
||||
allocate_value (struct type *type)
|
||||
allocate_value_lazy (struct type *type)
|
||||
{
|
||||
struct value *val;
|
||||
struct type *atype = check_typedef (type);
|
||||
|
||||
val = (struct value *) xzalloc (sizeof (struct value) + TYPE_LENGTH (atype));
|
||||
val = (struct value *) xzalloc (sizeof (struct value));
|
||||
val->contents = NULL;
|
||||
val->next = all_values;
|
||||
all_values = val;
|
||||
val->type = type;
|
||||
@ -233,7 +224,7 @@ allocate_value (struct type *type)
|
||||
val->bitpos = 0;
|
||||
val->bitsize = 0;
|
||||
VALUE_REGNUM (val) = -1;
|
||||
val->lazy = 0;
|
||||
val->lazy = 1;
|
||||
val->optimized_out = 0;
|
||||
val->embedded_offset = 0;
|
||||
val->pointed_to_offset = 0;
|
||||
@ -242,6 +233,26 @@ allocate_value (struct type *type)
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Allocate the contents of VAL if it has not been allocated yet. */
|
||||
|
||||
void
|
||||
allocate_value_contents (struct value *val)
|
||||
{
|
||||
if (!val->contents)
|
||||
val->contents = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type));
|
||||
}
|
||||
|
||||
/* Allocate a value and its contents for type TYPE. */
|
||||
|
||||
struct value *
|
||||
allocate_value (struct type *type)
|
||||
{
|
||||
struct value *val = allocate_value_lazy (type);
|
||||
allocate_value_contents (val);
|
||||
val->lazy = 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Allocate a value that has the correct length
|
||||
for COUNT repetitions of type TYPE. */
|
||||
|
||||
@ -340,13 +351,15 @@ set_value_bitsize (struct value *value, int bit)
|
||||
gdb_byte *
|
||||
value_contents_raw (struct value *value)
|
||||
{
|
||||
return value->aligner.contents + value->embedded_offset;
|
||||
allocate_value_contents (value);
|
||||
return value->contents + value->embedded_offset;
|
||||
}
|
||||
|
||||
gdb_byte *
|
||||
value_contents_all_raw (struct value *value)
|
||||
{
|
||||
return value->aligner.contents;
|
||||
allocate_value_contents (value);
|
||||
return value->contents;
|
||||
}
|
||||
|
||||
struct type *
|
||||
@ -360,7 +373,7 @@ value_contents_all (struct value *value)
|
||||
{
|
||||
if (value->lazy)
|
||||
value_fetch_lazy (value);
|
||||
return value->aligner.contents;
|
||||
return value->contents;
|
||||
}
|
||||
|
||||
int
|
||||
@ -495,6 +508,14 @@ value_mark (void)
|
||||
return all_values;
|
||||
}
|
||||
|
||||
void
|
||||
value_free (struct value *val)
|
||||
{
|
||||
if (val)
|
||||
xfree (val->contents);
|
||||
xfree (val);
|
||||
}
|
||||
|
||||
/* Free all values allocated since MARK was obtained by value_mark
|
||||
(except for those released). */
|
||||
void
|
||||
@ -579,7 +600,12 @@ struct value *
|
||||
value_copy (struct value *arg)
|
||||
{
|
||||
struct type *encl_type = value_enclosing_type (arg);
|
||||
struct value *val = allocate_value (encl_type);
|
||||
struct value *val;
|
||||
|
||||
if (value_lazy (arg))
|
||||
val = allocate_value_lazy (encl_type);
|
||||
else
|
||||
val = allocate_value (encl_type);
|
||||
val->type = arg->type;
|
||||
VALUE_LVAL (val) = VALUE_LVAL (arg);
|
||||
val->location = arg->location;
|
||||
@ -1319,39 +1345,12 @@ value_static_field (struct type *type, int fieldno)
|
||||
struct value *
|
||||
value_change_enclosing_type (struct value *val, struct type *new_encl_type)
|
||||
{
|
||||
if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (value_enclosing_type (val)))
|
||||
{
|
||||
val->enclosing_type = new_encl_type;
|
||||
return val;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct value *new_val;
|
||||
struct value *prev;
|
||||
|
||||
new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type));
|
||||
if (TYPE_LENGTH (new_encl_type) > TYPE_LENGTH (value_enclosing_type (val)))
|
||||
val->contents =
|
||||
(gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
|
||||
|
||||
new_val->enclosing_type = new_encl_type;
|
||||
|
||||
/* We have to make sure this ends up in the same place in the value
|
||||
chain as the original copy, so it's clean-up behavior is the same.
|
||||
If the value has been released, this is a waste of time, but there
|
||||
is no way to tell that in advance, so... */
|
||||
|
||||
if (val != all_values)
|
||||
{
|
||||
for (prev = all_values; prev != NULL; prev = prev->next)
|
||||
{
|
||||
if (prev->next == val)
|
||||
{
|
||||
prev->next = new_val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new_val;
|
||||
}
|
||||
val->enclosing_type = new_encl_type;
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Given a value ARG1 (offset by OFFSET bytes)
|
||||
@ -1388,18 +1387,20 @@ 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. */
|
||||
v = allocate_value (value_enclosing_type (arg1));
|
||||
v->type = type;
|
||||
|
||||
/* Lazy register values with offsets are not supported. */
|
||||
if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
|
||||
value_fetch_lazy (arg1);
|
||||
|
||||
if (value_lazy (arg1))
|
||||
set_value_lazy (v, 1);
|
||||
v = allocate_value_lazy (value_enclosing_type (arg1));
|
||||
else
|
||||
memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
|
||||
TYPE_LENGTH (value_enclosing_type (arg1)));
|
||||
{
|
||||
v = allocate_value (value_enclosing_type (arg1));
|
||||
memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
|
||||
TYPE_LENGTH (value_enclosing_type (arg1)));
|
||||
}
|
||||
v->type = type;
|
||||
v->offset = value_offset (arg1);
|
||||
v->embedded_offset = (offset + value_embedded_offset (arg1)
|
||||
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8);
|
||||
@ -1408,18 +1409,20 @@ value_primitive_field (struct value *arg1, int offset,
|
||||
{
|
||||
/* Plain old data member */
|
||||
offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
|
||||
v = allocate_value (type);
|
||||
|
||||
/* Lazy register values with offsets are not supported. */
|
||||
if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
|
||||
value_fetch_lazy (arg1);
|
||||
|
||||
if (value_lazy (arg1))
|
||||
set_value_lazy (v, 1);
|
||||
v = allocate_value_lazy (type);
|
||||
else
|
||||
memcpy (value_contents_raw (v),
|
||||
value_contents_raw (arg1) + offset,
|
||||
TYPE_LENGTH (type));
|
||||
{
|
||||
v = allocate_value (type);
|
||||
memcpy (value_contents_raw (v),
|
||||
value_contents_raw (arg1) + offset,
|
||||
TYPE_LENGTH (type));
|
||||
}
|
||||
v->offset = (value_offset (arg1) + offset
|
||||
+ value_embedded_offset (arg1));
|
||||
}
|
||||
|
@ -318,6 +318,8 @@ extern struct value *locate_var_value (struct symbol *var,
|
||||
struct frame_info *frame);
|
||||
|
||||
extern struct value *allocate_value (struct type *type);
|
||||
extern struct value *allocate_value_lazy (struct type *type);
|
||||
extern void allocate_value_contents (struct value *value);
|
||||
|
||||
extern struct value *allocate_repeat_value (struct type *type, int count);
|
||||
|
||||
@ -504,7 +506,7 @@ extern int unop_user_defined_p (enum exp_opcode op, struct value *arg1);
|
||||
|
||||
extern int destructor_name_p (const char *name, const struct type *type);
|
||||
|
||||
#define value_free(val) xfree (val)
|
||||
extern void value_free (struct value *val);
|
||||
|
||||
extern void free_all_values (void);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user