aboutsummaryrefslogtreecommitdiff
path: root/gdb/ada-lang.c
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@adacore.com>2015-10-09 14:12:51 -0700
committerJoel Brobecker <brobecker@adacore.com>2015-10-09 14:30:06 -0700
commitf93fca700f0fd70532132ae535f48c1a936abb0a (patch)
tree54b5f5349f109a56079fcb4180227ef9ce280da0 /gdb/ada-lang.c
parenta1c95e6b6ede168770664cdca8ae1568187554b4 (diff)
downloadgdb-f93fca700f0fd70532132ae535f48c1a936abb0a.zip
gdb-f93fca700f0fd70532132ae535f48c1a936abb0a.tar.gz
gdb-f93fca700f0fd70532132ae535f48c1a936abb0a.tar.bz2
[Ada] split data unpacking code out of ada_value_primitive_packed_val.
This patch is just preparation work which splits the function ada_value_primitive_packed_val into two function: one which unpacks the data, and the other which now uses it to implement ada_value_primitive_packed_val. This simplifies a bit ada_value_primitive_packed_val, but will also allow us to use the new function to unpack data without actually creating a struct value as a result. gdb/ChangeLog: * ada-lang.c (ada_unpack_from_contents): New function, extracted from ada_value_primitive_packed_val. (ada_value_primitive_packed_val): Replace extracted out code by call to ada_unpack_from_contents.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r--gdb/ada-lang.c217
1 files changed, 126 insertions, 91 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 1dbbb07..6947d76 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2382,24 +2382,23 @@ has_negatives (struct type *type)
}
}
+/* With SRC being a buffer containing BIT_SIZE bits of data at BIT_OFFSET,
+ unpack that data into UNPACKED. UNPACKED_LEN is the size in bytes of
+ the unpacked buffer.
-/* Create a new value of type TYPE from the contents of OBJ starting
- at byte OFFSET, and bit offset BIT_OFFSET within that byte,
- proceeding for BIT_SIZE bits. If OBJ is an lval in memory, then
- assigning through the result will set the field fetched from.
- VALADDR is ignored unless OBJ is NULL, in which case,
- VALADDR+OFFSET must address the start of storage containing the
- packed value. The value returned in this case is never an lval.
- Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */
+ IS_BIG_ENDIAN is nonzero if the data is stored in big endian mode,
+ zero otherwise.
-struct value *
-ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
- long offset, int bit_offset, int bit_size,
- struct type *type)
-{
- struct value *v;
+ IS_SIGNED_TYPE is nonzero if the data corresponds to a signed type.
- gdb_byte *src; /* First byte containing data to unpack */
+ IS_SCALAR is nonzero if the data corresponds to a signed type. */
+
+static void
+ada_unpack_from_contents (const gdb_byte *src, int bit_offset, int bit_size,
+ gdb_byte *unpacked, int unpacked_len,
+ int is_big_endian, int is_signed_type,
+ int is_scalar)
+{
int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
int src_idx; /* Index into the source area */
int src_bytes_left; /* Number of source bytes left to process. */
@@ -2407,7 +2406,6 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
int unusedLS; /* Number of bits in next significant
byte of source that are unused */
- gdb_byte *unpacked;
int unpacked_idx; /* Index into the unpacked buffer */
int unpacked_bytes_left; /* Number of bytes left to set in unpacked. */
@@ -2417,86 +2415,31 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
/* Transmit bytes from least to most significant; delta is the direction
the indices move. */
- int delta = gdbarch_bits_big_endian (get_type_arch (type)) ? -1 : 1;
-
- type = ada_check_typedef (type);
-
- if (obj == NULL)
- {
- v = allocate_value (type);
- src = (gdb_byte *) valaddr + offset;
- }
- else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
- {
- v = value_at (type, value_address (obj) + offset);
- type = value_type (v);
- if (TYPE_LENGTH (type) * HOST_CHAR_BIT < bit_size)
- {
- /* This can happen in the case of an array of dynamic objects,
- where the size of each element changes from element to element.
- In that case, we're initially given the array stride, but
- after resolving the element type, we find that its size is
- less than this stride. In that case, adjust bit_size to
- match TYPE's length, and recompute LEN accordingly. */
- bit_size = TYPE_LENGTH (type) * HOST_CHAR_BIT;
- src_len = TYPE_LENGTH (type) + (bit_offset + HOST_CHAR_BIT - 1) / 8;
- }
- src = alloca (src_len);
- read_memory (value_address (v), src, src_len);
- }
- else
- {
- v = allocate_value (type);
- src = (gdb_byte *) value_contents (obj) + offset;
- }
-
- if (obj != NULL)
- {
- long new_offset = offset;
-
- set_value_component_location (v, obj);
- set_value_bitpos (v, bit_offset + value_bitpos (obj));
- set_value_bitsize (v, bit_size);
- if (value_bitpos (v) >= HOST_CHAR_BIT)
- {
- ++new_offset;
- set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
- }
- set_value_offset (v, new_offset);
-
- /* Also set the parent value. This is needed when trying to
- assign a new value (in inferior memory). */
- set_value_parent (v, obj);
- }
- else
- set_value_bitsize (v, bit_size);
- unpacked = (gdb_byte *) value_contents (v);
+ int delta = is_big_endian ? -1 : 1;
srcBitsLeft = bit_size;
src_bytes_left = src_len;
- unpacked_bytes_left = TYPE_LENGTH (type);
+ unpacked_bytes_left = unpacked_len;
sign = 0;
- if (bit_size == 0)
- {
- memset (unpacked, 0, TYPE_LENGTH (type));
- return v;
- }
- else if (gdbarch_bits_big_endian (get_type_arch (type)))
+
+ if (is_big_endian)
{
src_idx = src_len - 1;
- if (has_negatives (type)
- && ((src[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
+ if (is_signed_type
+ && ((src[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
sign = ~0;
unusedLS =
(HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT)
% HOST_CHAR_BIT;
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_UNION:
- case TYPE_CODE_STRUCT:
+ if (is_scalar)
+ {
+ accumSize = 0;
+ unpacked_idx = unpacked_len - 1;
+ }
+ else
+ {
/* Non-scalar values must be aligned at a byte boundary... */
accumSize =
(HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT;
@@ -2504,12 +2447,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
of the target. */
unpacked_idx = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT - 1;
unpacked_bytes_left = unpacked_idx + 1;
- break;
- default:
- accumSize = 0;
- unpacked_idx = TYPE_LENGTH (type) - 1;
- break;
- }
+ }
}
else
{
@@ -2519,7 +2457,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
unusedLS = bit_offset;
accumSize = 0;
- if (has_negatives (type) && (src[src_len - 1] & (1 << sign_bit_offset)))
+ if (is_signed_type && (src[src_len - 1] & (1 << sign_bit_offset)))
sign = ~0;
}
@@ -2561,6 +2499,103 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
unpacked_bytes_left -= 1;
unpacked_idx += delta;
}
+}
+
+/* Create a new value of type TYPE from the contents of OBJ starting
+ at byte OFFSET, and bit offset BIT_OFFSET within that byte,
+ proceeding for BIT_SIZE bits. If OBJ is an lval in memory, then
+ assigning through the result will set the field fetched from.
+ VALADDR is ignored unless OBJ is NULL, in which case,
+ VALADDR+OFFSET must address the start of storage containing the
+ packed value. The value returned in this case is never an lval.
+ Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */
+
+struct value *
+ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
+ long offset, int bit_offset, int bit_size,
+ struct type *type)
+{
+ struct value *v;
+ gdb_byte *src; /* First byte containing data to unpack */
+ int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
+ gdb_byte *unpacked;
+ int is_scalar;
+
+ type = ada_check_typedef (type);
+
+ if (obj == NULL)
+ {
+ v = allocate_value (type);
+ src = (gdb_byte *) valaddr + offset;
+ }
+ else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
+ {
+ v = value_at (type, value_address (obj) + offset);
+ type = value_type (v);
+ if (TYPE_LENGTH (type) * HOST_CHAR_BIT < bit_size)
+ {
+ /* This can happen in the case of an array of dynamic objects,
+ where the size of each element changes from element to element.
+ In that case, we're initially given the array stride, but
+ after resolving the element type, we find that its size is
+ less than this stride. In that case, adjust bit_size to
+ match TYPE's length, and recompute LEN accordingly. */
+ bit_size = TYPE_LENGTH (type) * HOST_CHAR_BIT;
+ src_len = TYPE_LENGTH (type) + (bit_offset + HOST_CHAR_BIT - 1) / 8;
+ }
+ src = alloca (src_len);
+ read_memory (value_address (v), src, src_len);
+ }
+ else
+ {
+ v = allocate_value (type);
+ src = (gdb_byte *) value_contents (obj) + offset;
+ }
+
+ if (obj != NULL)
+ {
+ long new_offset = offset;
+
+ set_value_component_location (v, obj);
+ set_value_bitpos (v, bit_offset + value_bitpos (obj));
+ set_value_bitsize (v, bit_size);
+ if (value_bitpos (v) >= HOST_CHAR_BIT)
+ {
+ ++new_offset;
+ set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
+ }
+ set_value_offset (v, new_offset);
+
+ /* Also set the parent value. This is needed when trying to
+ assign a new value (in inferior memory). */
+ set_value_parent (v, obj);
+ }
+ else
+ set_value_bitsize (v, bit_size);
+ unpacked = (gdb_byte *) value_contents (v);
+
+ if (bit_size == 0)
+ {
+ memset (unpacked, 0, TYPE_LENGTH (type));
+ return v;
+ }
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_STRUCT:
+ is_scalar = 0;
+ break;
+ default:
+ is_scalar = 1;
+ break;
+ }
+
+ ada_unpack_from_contents (src, bit_offset, bit_size,
+ unpacked, TYPE_LENGTH (type),
+ gdbarch_bits_big_endian (get_type_arch (type)),
+ has_negatives (type), is_scalar);
if (is_dynamic_type (value_type (v)))
v = value_from_contents_and_address (value_type (v), value_contents (v),