diff options
author | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2016-11-24 17:48:03 +0100 |
---|---|---|
committer | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2016-11-24 17:48:03 +0100 |
commit | 22347e554cd7ba2a0bf36dc81ebfcbe2e2fd74af (patch) | |
tree | 106513aca860aaa113cd2f8b37bf134a7ee5de25 /gdb/testsuite/gdb.dwarf2 | |
parent | da5b30da2d1167591aa8d71b543f97bfdc2ec2a2 (diff) | |
download | gdb-22347e554cd7ba2a0bf36dc81ebfcbe2e2fd74af.zip gdb-22347e554cd7ba2a0bf36dc81ebfcbe2e2fd74af.tar.gz gdb-22347e554cd7ba2a0bf36dc81ebfcbe2e2fd74af.tar.bz2 |
Fix copy_bitwise()
When the user writes or reads a variable whose location is described
with DWARF pieces (DW_OP_piece or DW_OP_bit_piece), GDB's helper
function copy_bitwise is invoked for each piece. The implementation of
this function has a bug that may result in a corrupted copy, depending
on alignment and bit size. (Full-byte copies are not affected.)
This rewrites copy_bitwise, replacing its algorithm by a fixed version,
and adding an appropriate test case. Without the fix the new test case
fails, e.g.:
print def_t
$2 = {a = 0, b = 4177919}
(gdb) FAIL: gdb.dwarf2/nonvar-access.exp: print def_t
Written in binary, the wrong result above looks like this:
01111111011111111111111
Which means that two zero bits have sneaked into the copy of the
original all-one bit pattern. The test uses this simple all-one value
in order to avoid another GDB bug that causes the DWARF piece of a
DW_OP_stack_value to be taken from the wrong end on big-endian
architectures.
gdb/ChangeLog:
* dwarf2loc.c (extract_bits_primitive): Remove.
(extract_bits): Remove.
(copy_bitwise): Rewrite. Fixes a possible corruption that may
occur for non-byte-aligned copies.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/nonvar-access.exp: Add a test for accessing
non-byte-aligned bit fields.
Diffstat (limited to 'gdb/testsuite/gdb.dwarf2')
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/nonvar-access.exp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp index 21532a6..8910f6d 100644 --- a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp +++ b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp @@ -32,7 +32,7 @@ Dwarf::assemble $asm_file { {DW_AT_name main.c} } { declare_labels int_type_label short_type_label - declare_labels struct_s_label + declare_labels struct_s_label struct_t_label int_type_label: base_type { {name "int"} @@ -58,6 +58,24 @@ Dwarf::assemble $asm_file { } } + struct_t_label: structure_type { + {name t} + {byte_size 4 DW_FORM_sdata} + } { + member { + {name a} + {type :$int_type_label} + {data_member_location 0 DW_FORM_udata} + {bit_size 9 DW_FORM_udata} + } + member { + {name b} + {type :$int_type_label} + {data_bit_offset 9 DW_FORM_udata} + {bit_size 23 DW_FORM_udata} + } + } + DW_TAG_subprogram { {name main} {DW_AT_external 1 flag} @@ -84,6 +102,18 @@ Dwarf::assemble $asm_file { bit_piece 24 0 } SPECIAL_expr} } + DW_TAG_variable { + {name def_t} + {type :$struct_t_label} + {location { + const1u 0 + stack_value + bit_piece 9 0 + const1s -1 + stack_value + bit_piece 23 0 + } SPECIAL_expr} + } } } } @@ -99,5 +129,6 @@ if ![runto_main] { } gdb_test "print def_s" " = \\{a = 0, b = -1\\}" +gdb_test "print def_t" " = \\{a = 0, b = -1\\}" gdb_test "print undef_int" " = <optimized out>" gdb_test "print undef_s.a" " = <optimized out>" |