From 4a76eae5946577891a09412077a5bbd3ea532885 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Fri, 28 Aug 2009 18:50:49 +0000 Subject: [PATCH] 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. --- gdb/ChangeLog | 8 ++++++++ gdb/testsuite/ChangeLog | 8 ++++++++ gdb/testsuite/gdb.base/bitfields.c | 11 +++++++++++ gdb/testsuite/gdb.base/bitfields.exp | 22 ++++++++++++++++++++++ gdb/value.c | 16 ++++++++++++---- 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 + + 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 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 + + 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 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; -- 2.30.2