* value.h (unpack_bits_as_long): Delete declaration.
	(unpack_value_bits_as_long): Declare.
	(unpack_value_field_as_long): Declare.
	(value_field_bitfield): Declare.
	* value.c (unpack_bits_as_long): Rename to...
	(unpack_value_bits_as_long_1): ... this.  Add embedded_offset and
	value parameters.  Return the extracted result in a new output
	parameter.  If the value contents are unavailable, return false,
	otherwise return true.
	(unpack_value_bits_as_long): New.
	(unpack_field_as_long): Rename to...
	(unpack_value_field_as_long_1): ... this.  Add embedded_offset and
	Add embedded_offset and value parameters.  Return the extracted
	result in a new output parameter. If the value contents are
	unavailable, return false, otherwise return true.
	(unpack_value_field_as_long): New.
	(unpack_field_as_long_1): New.
	(unpack_field_as_long): Reimplement as wrapper around
	unpack_value_field_as_long_1.
	(value_field_bitfield): New function.
	* valops.c (value_fetch_lazy): When fetching a bitfield, use
	unpack_value_bits_as_long.  Mark the value as unavailable, if it
	is unavailable.
	* jv-valprint.c (java_print_value_fields): Use
	value_field_bitfield.
	* p-valprint.c (pascal_object_print_value_fields): Use
	value_field_bitfield.
	* cp-valprint.c (cp_print_value_fields): Use value_field_bitfield.
This commit is contained in:
Pedro Alves 2011-02-14 11:25:59 +00:00
parent 3158c6ed12
commit 5467c6c807
7 changed files with 186 additions and 43 deletions

View File

@ -1,3 +1,34 @@
2011-02-14 Pedro Alves <pedro@codesourcery.com>
* value.h (unpack_bits_as_long): Delete declaration.
(unpack_value_bits_as_long): Declare.
(unpack_value_field_as_long): Declare.
(value_field_bitfield): Declare.
* value.c (unpack_bits_as_long): Rename to...
(unpack_value_bits_as_long_1): ... this. Add embedded_offset and
value parameters. Return the extracted result in a new output
parameter. If the value contents are unavailable, return false,
otherwise return true.
(unpack_value_bits_as_long): New.
(unpack_field_as_long): Rename to...
(unpack_value_field_as_long_1): ... this. Add embedded_offset and
Add embedded_offset and value parameters. Return the extracted
result in a new output parameter. If the value contents are
unavailable, return false, otherwise return true.
(unpack_value_field_as_long): New.
(unpack_field_as_long_1): New.
(unpack_field_as_long): Reimplement as wrapper around
unpack_value_field_as_long_1.
(value_field_bitfield): New function.
* valops.c (value_fetch_lazy): When fetching a bitfield, use
unpack_value_bits_as_long. Mark the value as unavailable, if it
is unavailable.
* jv-valprint.c (java_print_value_fields): Use
value_field_bitfield.
* p-valprint.c (pascal_object_print_value_fields): Use
value_field_bitfield.
* cp-valprint.c (cp_print_value_fields): Use value_field_bitfield.
2011-02-14 Pedro Alves <pedro@codesourcery.com>
* value.c (get_internalvar_integer): Also return the int value of

View File

@ -323,9 +323,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
struct value_print_options opts = *options;
opts.deref_ref = 0;
v = value_from_longest
(TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr + offset, i));
v = value_field_bitfield (type, i, valaddr, offset, val);
common_val_print (v, stream, recurse + 1, &opts,
current_language);

View File

@ -416,9 +416,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr,
{
struct value_print_options opts;
v = value_from_longest
(TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr + offset, i));
v = value_field_bitfield (type, i, valaddr, offset, val);
opts = *options;
opts.deref_ref = 0;

View File

@ -810,9 +810,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
{
struct value_print_options opts = *options;
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type,
valaddr + offset, i));
v = value_field_bitfield (type, i, valaddr, offset, val);
opts.deref_ref = 0;
common_val_print (v, stream, recurse + 1, &opts,
@ -831,9 +829,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
v4.17 specific. */
struct value *v;
v = value_from_longest
(TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr + offset, i));
v = value_field_bitfield (type, i, valaddr, offset, val);
if (v == NULL)
val_print_optimized_out (stream);

View File

@ -989,11 +989,7 @@ value_fetch_lazy (struct value *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 = unpack_bits_as_long (value_type (val),
(value_contents_for_printing (parent)
+ offset),
value_bitpos (val),
value_bitsize (val));
LONGEST num;
int length = TYPE_LENGTH (type);
if (!value_bits_valid (val,
@ -1001,7 +997,17 @@ value_fetch_lazy (struct value *val)
value_bitsize (val)))
error (_("value has been optimized out"));
store_signed_integer (value_contents_raw (val), length, byte_order, num);
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),
length);
else
store_signed_integer (value_contents_raw (val), length,
byte_order, num);
}
else if (VALUE_LVAL (val) == lval_memory)
{

View File

@ -2532,30 +2532,24 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
}
/* Unpack a bitfield of the specified FIELD_TYPE, from the anonymous
object at VALADDR. The bitfield starts at BITPOS bits and contains
BITSIZE bits.
Extracting bits depends on endianness of the machine. Compute the
number of least significant bits to discard. For big endian machines,
we compute the total number of bits in the anonymous object, subtract
off the bit count from the MSB of the object to the MSB of the
bitfield, then the size of the bitfield, which leaves the LSB discard
count. For little endian machines, the discard count is simply the
number of bits from the LSB of the anonymous object to the LSB of the
bitfield.
/* Helper function for both unpack_value_bits_as_long and
unpack_bits_as_long. See those functions for more details on the
interface; the only difference is that this function accepts either
a NULL or a non-NULL ORIGINAL_VALUE. */
If the field is signed, we also do sign extension. */
LONGEST
unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
int bitpos, int bitsize)
static int
unpack_value_bits_as_long_1 (struct type *field_type, const gdb_byte *valaddr,
int embedded_offset, int bitpos, int bitsize,
const struct value *original_value,
LONGEST *result)
{
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (field_type));
ULONGEST val;
ULONGEST valmask;
int lsbcount;
int bytes_read;
int read_offset;
/* Read the minimum number of bytes required; there may not be
enough bytes to read an entire ULONGEST. */
@ -2565,7 +2559,14 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
else
bytes_read = TYPE_LENGTH (field_type);
val = extract_unsigned_integer (valaddr + bitpos / 8,
read_offset = bitpos / 8;
if (original_value != NULL
&& !value_bytes_available (original_value, embedded_offset + read_offset,
bytes_read))
return 0;
val = extract_unsigned_integer (valaddr + embedded_offset + read_offset,
bytes_read, byte_order);
/* Extract bits. See comment above. */
@ -2591,20 +2592,118 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
}
}
}
return (val);
*result = val;
return 1;
}
/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
VALADDR. See unpack_bits_as_long for more details. */
/* Unpack a bitfield of the specified FIELD_TYPE, from the object at
VALADDR + EMBEDDED_OFFSET, and store the result in *RESULT.
VALADDR points to the contents of ORIGINAL_VALUE, which must not be
NULL. The bitfield starts at BITPOS bits and contains BITSIZE
bits.
LONGEST
unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
Returns false if the value contents are unavailable, otherwise
returns true, indicating a valid value has been stored in *RESULT.
Extracting bits depends on endianness of the machine. Compute the
number of least significant bits to discard. For big endian machines,
we compute the total number of bits in the anonymous object, subtract
off the bit count from the MSB of the object to the MSB of the
bitfield, then the size of the bitfield, which leaves the LSB discard
count. For little endian machines, the discard count is simply the
number of bits from the LSB of the anonymous object to the LSB of the
bitfield.
If the field is signed, we also do sign extension. */
int
unpack_value_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
int embedded_offset, int bitpos, int bitsize,
const struct value *original_value,
LONGEST *result)
{
gdb_assert (original_value != NULL);
return unpack_value_bits_as_long_1 (field_type, valaddr, embedded_offset,
bitpos, bitsize, original_value, result);
}
/* Unpack a field FIELDNO of the specified TYPE, from the object at
VALADDR + EMBEDDED_OFFSET. VALADDR points to the contents of
ORIGINAL_VALUE. See unpack_value_bits_as_long for more
details. */
static int
unpack_value_field_as_long_1 (struct type *type, const gdb_byte *valaddr,
int embedded_offset, int fieldno,
const struct value *val, LONGEST *result)
{
int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
struct type *field_type = TYPE_FIELD_TYPE (type, fieldno);
return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize);
return unpack_value_bits_as_long_1 (field_type, valaddr, embedded_offset,
bitpos, bitsize, val,
result);
}
/* Unpack a field FIELDNO of the specified TYPE, from the object at
VALADDR + EMBEDDED_OFFSET. VALADDR points to the contents of
ORIGINAL_VALUE, which must not be NULL. See
unpack_value_bits_as_long for more details. */
int
unpack_value_field_as_long (struct type *type, const gdb_byte *valaddr,
int embedded_offset, int fieldno,
const struct value *val, LONGEST *result)
{
gdb_assert (val != NULL);
return unpack_value_field_as_long_1 (type, valaddr, embedded_offset,
fieldno, val, result);
}
/* Unpack a field FIELDNO of the specified TYPE, from the anonymous
object at VALADDR. See unpack_value_bits_as_long for more details.
This function differs from unpack_value_field_as_long in that it
operates without a struct value object. */
LONGEST
unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
{
LONGEST result;
unpack_value_field_as_long_1 (type, valaddr, 0, fieldno, NULL, &result);
return result;
}
/* Return a new value with type TYPE, which is FIELDNO field of the
object at VALADDR + EMBEDDEDOFFSET. VALADDR points to the contents
of VAL. If the VAL's contents required to extract the bitfield
from are unavailable, the new value is correspondingly marked as
unavailable. */
struct value *
value_field_bitfield (struct type *type, int fieldno,
const gdb_byte *valaddr,
int embedded_offset, const struct value *val)
{
LONGEST l;
if (!unpack_value_field_as_long (type, valaddr, embedded_offset, fieldno,
val, &l))
{
struct type *field_type = TYPE_FIELD_TYPE (type, fieldno);
struct value *retval = allocate_value (field_type);
mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (field_type));
return retval;
}
else
{
return value_from_longest (TYPE_FIELD_TYPE (type, fieldno), l);
}
}
/* Modify the value of a bitfield. ADDR points to a block of memory in

View File

@ -430,11 +430,25 @@ extern LONGEST unpack_long (struct type *type, const gdb_byte *valaddr);
extern DOUBLEST unpack_double (struct type *type, const gdb_byte *valaddr,
int *invp);
extern CORE_ADDR unpack_pointer (struct type *type, const gdb_byte *valaddr);
LONGEST unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
int bitpos, int bitsize);
extern int unpack_value_bits_as_long (struct type *field_type,
const gdb_byte *valaddr,
int embedded_offset, int bitpos,
int bitsize,
const struct value *original_value,
LONGEST *result);
extern LONGEST unpack_field_as_long (struct type *type,
const gdb_byte *valaddr,
int fieldno);
extern int unpack_value_field_as_long (struct type *type, const gdb_byte *valaddr,
int embedded_offset, int fieldno,
const struct value *val, LONGEST *result);
extern struct value *value_field_bitfield (struct type *type, int fieldno,
const gdb_byte *valaddr,
int embedded_offset,
const struct value *val);
extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num);