aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2009-08-28 18:50:49 +0000
committerDaniel Jacobowitz <drow@false.org>2009-08-28 18:50:49 +0000
commit4a76eae5946577891a09412077a5bbd3ea532885 (patch)
tree072a437dc31f2c364206b6e61bb53ae2a3d844e0
parentgdb/ (diff)
downloadbinutils-gdb-4a76eae5946577891a09412077a5bbd3ea532885.tar.gz
binutils-gdb-4a76eae5946577891a09412077a5bbd3ea532885.tar.bz2
binutils-gdb-4a76eae5946577891a09412077a5bbd3ea532885.zip
PR gdb/10565
* value.c (value_primitive_field): Do not save value_offset for bitfields. (unpack_bits_as_long): Do not read an entire ULONGEST. testsuite/ PR gdb/10565 * gdb.base/bitfields.c (struct container, container): New. (main): Initialize it and call break5. * gdb.base/bitfields.exp (bitfield_at_offset): New test.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/testsuite/ChangeLog8
-rw-r--r--gdb/testsuite/gdb.base/bitfields.c11
-rw-r--r--gdb/testsuite/gdb.base/bitfields.exp22
-rw-r--r--gdb/value.c16
5 files changed, 61 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8f534a7032d..4cd1e538ba7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2009-08-28 Daniel Jacobowitz <dan@codesourcery.com>
+
+ PR gdb/10565
+
+ * value.c (value_primitive_field): Do not save value_offset for
+ bitfields.
+ (unpack_bits_as_long): Do not read an entire ULONGEST.
+
2009-08-28 Jan Kratochvil <jan.kratochvil@redhat.com>
Support constant DW_AT_data_member_location by GCC PR debug/40659.
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index a07ed2a3cd6..0d102814414 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2009-08-28 Daniel Jacobowitz <dan@codesourcery.com>
+
+ PR gdb/10565
+
+ * gdb.base/bitfields.c (struct container, container): New.
+ (main): Initialize it and call break5.
+ * gdb.base/bitfields.exp (bitfield_at_offset): New test.
+
2009-08-28 Jan Kratochvil <jan.kratochvil@redhat.com>
Support constant DW_AT_data_member_location by GCC PR debug/40659.
diff --git a/gdb/testsuite/gdb.base/bitfields.c b/gdb/testsuite/gdb.base/bitfields.c
index bd411f7b647..3b5e42c6299 100644
--- a/gdb/testsuite/gdb.base/bitfields.c
+++ b/gdb/testsuite/gdb.base/bitfields.c
@@ -63,6 +63,12 @@ void break10 ()
{
}
+struct container
+{
+ struct fields one;
+ struct fields two;
+} container;
+
/* This is used by bitfields.exp to determine if the target understands
signed bitfields. */
int i;
@@ -190,5 +196,10 @@ int main ()
flags.s3 = 0;
flags.s9 = 0;
+ /* Bitfields at a non-zero offset in a containing structure. */
+ container.one.u3 = 5;
+ container.two.u3 = 3;
+ break5 ();
+
return 0;
}
diff --git a/gdb/testsuite/gdb.base/bitfields.exp b/gdb/testsuite/gdb.base/bitfields.exp
index 31e8b0151c5..659785e69b6 100644
--- a/gdb/testsuite/gdb.base/bitfields.exp
+++ b/gdb/testsuite/gdb.base/bitfields.exp
@@ -233,6 +233,26 @@ proc bitfield_signedness {} {
gdb_stop_suppressing_tests;
}
+# Test bitfields at non-zero offsets in a struct.
+
+proc bitfield_at_offset {} {
+ global decimal
+ global hex
+ global gdb_prompt
+ global srcfile
+
+ gdb_breakpoint break5
+ if [gdb_test "cont" "Break.*break5 \\(\\) at .*$srcfile:$decimal.*" "continuing to break5"] {
+ return
+ }
+
+ set one ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 5, s9 = 0, u9 = 0, sc = 0.*"
+ set two ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 3, s9 = 0, u9 = 0, sc = 0.*"
+ gdb_test "print container" "$one$two" "distinct bitfields in container"
+ gdb_test "print container.one.u3" ".* = 5"
+ gdb_test "print container.two.u3" ".* = 3"
+}
+
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
@@ -264,3 +284,5 @@ if [istarget "mips-idt-*"] then {
gdb_load ${binfile}
}
bitfield_signedness
+
+bitfield_at_offset
diff --git a/gdb/value.c b/gdb/value.c
index 330ab156956..f26e16c7d62 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1878,7 +1878,7 @@ value_primitive_field (struct value *arg1, int offset,
v->bitpos = bitpos % container_bitsize;
else
v->bitpos = bitpos % 8;
- v->offset = value_offset (arg1) + value_embedded_offset (arg1)
+ v->offset = value_embedded_offset (arg1)
+ (bitpos - v->bitpos) / 8;
v->parent = arg1;
value_incref (v->parent);
@@ -2031,15 +2031,23 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
ULONGEST val;
ULONGEST valmask;
int lsbcount;
+ int bytes_read;
- val = extract_unsigned_integer (valaddr + bitpos / 8,
- sizeof (val), byte_order);
+ /* Read the minimum number of bytes required; there may not be
+ enough bytes to read an entire ULONGEST. */
CHECK_TYPEDEF (field_type);
+ if (bitsize)
+ bytes_read = ((bitpos % 8) + bitsize + 7) / 8;
+ else
+ bytes_read = TYPE_LENGTH (field_type);
+
+ val = extract_unsigned_integer (valaddr + bitpos / 8,
+ bytes_read, byte_order);
/* Extract bits. See comment above. */
if (gdbarch_bits_big_endian (get_type_arch (field_type)))
- lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
+ lsbcount = (bytes_read * 8 - bitpos % 8 - bitsize);
else
lsbcount = (bitpos % 8);
val >>= lsbcount;