From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5357 invoked by alias); 4 Dec 2013 15:26:20 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 5346 invoked by uid 89); 4 Dec 2013 15:26:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL,BAYES_50,RDNS_NONE,URIBL_BLOCKED autolearn=no version=3.3.2 X-HELO: mail-gw1-out.broadcom.com Received: from Unknown (HELO mail-gw1-out.broadcom.com) (216.31.210.62) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 04 Dec 2013 15:26:17 +0000 Received: from irvexchcas08.broadcom.com (HELO IRVEXCHCAS08.corp.ad.broadcom.com) ([10.9.208.57]) by mail-gw1-out.broadcom.com with ESMTP; 04 Dec 2013 07:29:57 -0800 Received: from IRVEXCHSMTP2.corp.ad.broadcom.com (10.9.207.52) by IRVEXCHCAS08.corp.ad.broadcom.com (10.9.208.57) with Microsoft SMTP Server (TLS) id 14.1.438.0; Wed, 4 Dec 2013 07:26:10 -0800 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP2.corp.ad.broadcom.com (10.9.207.52) with Microsoft SMTP Server id 14.1.438.0; Wed, 4 Dec 2013 07:26:10 -0800 Received: from [10.177.73.48] (unknown [10.177.73.48]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 5FC4E246A5 for ; Wed, 4 Dec 2013 07:26:08 -0800 (PST) Message-ID: <529F498F.7060909@broadcom.com> Date: Wed, 04 Dec 2013 15:26:00 -0000 From: Andrew Burgess User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Thunderbird/24.1.1 MIME-Version: 1.0 To: Subject: [PATCH [0/2] Convert the unavailable vector to be bit, not byte, based. References: <529F489F.7070805@broadcom.com> In-Reply-To: <529F489F.7070805@broadcom.com> Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2013-12/txt/msg00144.txt.bz2 This is the actual conversion, and a test. OK to apply? Thanks, Andrew gdb/testfile/ChangeLog * gdb.trace/unavailable-dwarf-piece.c: New file. * gdb.trace/unavailable-dwarf-piece.exp: New file. gdb/ChangeLog * gdb/dwarf2loc.c (read_pieced_value): Mark bits, not bytes unavailable, use correct bit length. * gdb/value.c (value_bits_available): New function. (mark_value_bits_unavailable): New function. (mark_value_bytes_unavailable): Move contents to mark_value_bits_unavailable. (value_available_contents_eq): Take account of the unavailable vector being bit based. (value_contents_copy_raw): Likewise. (unpack_value_bits_as_long_1): Check availability in bits, bot bytes. * gdb/value.h (int value_bits_available): Declare new function. (mark_value_bits_unavailable): Declare new function. diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 2d15546..ba5f338 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1709,7 +1709,7 @@ read_pieced_value (struct value *v) if (optim) set_value_optimized_out (v, 1); if (unavail) - mark_value_bytes_unavailable (v, offset, this_size); + mark_value_bits_unavailable (v, offset, this_size_bits); } } else diff --git a/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.c b/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.c new file mode 100644 index 0000000..f55b094 --- /dev/null +++ b/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.c @@ -0,0 +1,86 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +struct s +{ + unsigned char a; + unsigned char b; + unsigned char c; +}; + +struct t +{ + /* First, a complete byte. */ + unsigned char a; + /* Next, 8 single bits. */ + unsigned char b : 1; + unsigned char c : 1; + unsigned char d : 1; + unsigned char e : 1; + unsigned char f : 1; + unsigned char g : 1; + unsigned char h : 1; + unsigned char i : 1; + /* Now another byte. */ + unsigned char j; +}; + +void +end () +{ + /* Nothing. */ +} + +void +dummy () +{ + /* Nothing. */ +} + +int +foo (struct s x, struct s y, struct s z) +{ + dummy (); + asm (".global foo_end_lbl\nfoo_end_lbl:"); + return 0; +} + +int +bar (struct t x, struct t y, struct t z) +{ + dummy (); + asm (".global bar_end_lbl\nbar_end_lbl:"); + return 0; +} + +int +main () +{ + struct s v = { 0, 1, 2}; + struct t w = { 5, 0, 1, 0, 1, 0, 1, 0, 1, 7 }; + int ans; + + ans = foo (v, v, v); + + end (); + + ans = bar (w, w, w); + + end (); + + return ans; +} diff --git a/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.exp b/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.exp new file mode 100644 index 0000000..ff0614e --- /dev/null +++ b/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.exp @@ -0,0 +1,334 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib "trace-support.exp" +load_lib dwarf.exp + +if {![dwarf2_support]} { + return 0 +} + +standard_testfile .c + +set asm_file "${testfile}-dbg.s" +set opts {} + +if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \ + object {nodebug}] != "" } { + return -1 +} + +Dwarf::assemble $asm_file { + declare_labels uchar_label struct_s_label foo_label struct_t_label bar_label + + cu {} { + compile_unit {{language @DW_LANG_C}} { + uchar_label: DW_TAG_base_type { + {name "unsigned char"} + {byte_size 1 DW_FORM_sdata} + {encoding @DW_ATE_unsigned_char} + } + + struct_s_label: DW_TAG_structure_type { + {name s} + {byte_size 3 DW_FORM_sdata} + {decl_file 1} + {decl_line 1} + } { + DW_TAG_member { + {name a} + {type :$uchar_label} + {data_member_location { + DW_OP_plus_uconst 0 + } SPECIAL_expr} + } + DW_TAG_member { + {name b} + {type :$uchar_label} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name c} + {type :$uchar_label} + {data_member_location { + DW_OP_plus_uconst 2 + } SPECIAL_expr} + } + } + + struct_t_label: DW_TAG_structure_type { + {name t} + {byte_size 3 DW_FORM_sdata} + {decl_file 1} + {decl_line 1} + } { + DW_TAG_member { + {name a} + {type :$uchar_label} + {data_member_location { + DW_OP_plus_uconst 0 + } SPECIAL_expr} + } + DW_TAG_member { + {name b} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 7 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name c} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 6 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name d} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 5 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name e} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 4 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name f} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 3 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name g} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 2 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name h} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 1 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name i} + {type :$uchar_label} + {byte_size 1 DW_FORM_sdata} + {bit_size 1 DW_FORM_sdata} + {bit_offset 0 DW_FORM_sdata} + {data_member_location { + DW_OP_plus_uconst 1 + } SPECIAL_expr} + } + DW_TAG_member { + {name j} + {type :$uchar_label} + {data_member_location { + DW_OP_plus_uconst 2 + } SPECIAL_expr} + } + } + + DW_TAG_subprogram { + {name foo} + {decl_file 1} + {low_pc foo addr} + {high_pc foo_end_lbl addr} + } { + DW_TAG_formal_parameter { + {type :$struct_s_label} + {name x} + {location { + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 2 + DW_OP_reg0 + DW_OP_piece 1 + } SPECIAL_expr} + } + DW_TAG_formal_parameter { + {type :$struct_s_label} + {name y} + {location { + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + DW_OP_reg0 + DW_OP_piece 1 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + } SPECIAL_expr} + } + DW_TAG_formal_parameter { + {type :$struct_s_label} + {name z} + {location { + DW_OP_reg0 + DW_OP_piece 1 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 2 + } SPECIAL_expr} + } + } + + + DW_TAG_subprogram { + {name bar} + {decl_file 1} + {low_pc bar addr} + {high_pc bar_end_lbl addr} + } { + DW_TAG_formal_parameter { + {type :$struct_t_label} + {name x} + {location { + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + DW_OP_reg0 + DW_OP_bit_piece 1 0 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_bit_piece 7 0 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + } SPECIAL_expr} + } + DW_TAG_formal_parameter { + {type :$struct_t_label} + {name y} + {location { + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_bit_piece 3 0 + DW_OP_reg0 + DW_OP_bit_piece 1 0 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_bit_piece 4 0 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + } SPECIAL_expr} + } + DW_TAG_formal_parameter { + {type :$struct_t_label} + {name z} + {location { + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_bit_piece 7 0 + DW_OP_reg0 + DW_OP_bit_piece 1 0 + DW_OP_lit0 + DW_OP_stack_value + DW_OP_piece 1 + } SPECIAL_expr} + } + } + + } + } +} + +if { [gdb_compile ${asm_file} ${binfile}2.o object {nodebug}] != "" } { + return -1 +} + +if { [gdb_compile [list ${binfile}1.o ${binfile}2.o] ${binfile} \ + executable {}] != "" } { + return -1 +} + +clean_restart ${testfile} + +if ![runto_main] { + return -1 +} + +if ![gdb_target_supports_trace] { + unsupported "target does not support trace" + return -1 +} + +gdb_breakpoint "end" + +with_test_prefix "tracing foo" { + gdb_test "trace foo" ".*" + gdb_test_no_output "tstart" + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" + gdb_test_no_output "tstop" + + gdb_test "tfind 0" "Found trace frame 0, tracepoint .*" + gdb_test "p x" "\\\$${decimal} = {a = 0 '\\\\000', b = 0 '\\\\000', c = }" + gdb_test "p y" "\\\$${decimal} = {a = 0 '\\\\000', b = , c = 0 '\\\\000'}" + gdb_test "p z" "\\\$${decimal} = {a = , b = 0 '\\\\000', c = 0 '\\\\000'}" + + gdb_test "tfind none" "No longer looking at any trace frame.*" +} + +with_test_prefix "tracing bar" { + gdb_test "trace bar" ".*" + gdb_test_no_output "tstart" + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" + gdb_test_no_output "tstop" + + gdb_test "tfind 0" "Found trace frame 0, tracepoint .*" + gdb_test "p x" "\\\$${decimal} = {a = 0 '\\\\000', b = , c = 0 '\\\\000', d = 0 '\\\\000', e = 0 '\\\\000', f = 0 '\\\\000', g = 0 '\\\\000', h = 0 '\\\\000', i = 0 '\\\\000', j = 0 '\\\\000'}" + gdb_test "p y" "\\\$${decimal} = {a = 0 '\\\\000', b = 0 '\\\\000', c = 0 '\\\\000', d = 0 '\\\\000', e = , f = 0 '\\\\000', g = 0 '\\\\000', h = 0 '\\\\000', i = 0 '\\\\000', j = 0 '\\\\000'}" + gdb_test "p z" "\\\$${decimal} = {a = 0 '\\\\000', b = 0 '\\\\000', c = 0 '\\\\000', d = 0 '\\\\000', e = 0 '\\\\000', f = 0 '\\\\000', g = 0 '\\\\000', h = 0 '\\\\000', i = , j = 0 '\\\\000'}" + + gdb_test "tfind none" "No longer looking at any trace frame.*" +} diff --git a/gdb/value.c b/gdb/value.c index a64e7e1..3878f37 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -338,7 +338,7 @@ struct value }; int -value_bytes_available (const struct value *value, int offset, int length) +value_bits_available (const struct value *value, int offset, int length) { gdb_assert (!value->lazy); @@ -346,6 +346,14 @@ value_bytes_available (const struct value *value, int offset, int length) } int +value_bytes_available (const struct value *value, int offset, int length) +{ + return value_bits_available (value, + offset * TARGET_CHAR_BIT, + length * TARGET_CHAR_BIT); +} + +int value_entirely_available (struct value *value) { /* We can only tell whether the whole value is available when we try @@ -379,7 +387,7 @@ value_entirely_unavailable (struct value *value) } void -mark_value_bytes_unavailable (struct value *value, int offset, int length) +mark_value_bits_unavailable (struct value *value, int offset, int length) { range_s newr; int i; @@ -543,6 +551,14 @@ mark_value_bytes_unavailable (struct value *value, int offset, int length) } } +void +mark_value_bytes_unavailable (struct value *value, int offset, int length) +{ + mark_value_bits_unavailable (value, + offset * TARGET_CHAR_BIT, + length * TARGET_CHAR_BIT); +} + /* Find the first range in RANGES that overlaps the range defined by OFFSET and LENGTH, starting at element POS in the RANGES vector, Returns the index into RANGES where such overlapping range was @@ -572,6 +588,12 @@ value_available_contents_eq (const struct value *val1, int offset1, /* See function description in value.h. */ gdb_assert (!val1->lazy && !val2->lazy); + /* The offsets and length parameters are all byte based, but we store the + unavailable data in a bit based list, convert now. */ + offset1 *= TARGET_CHAR_BIT; + offset2 *= TARGET_CHAR_BIT; + length *= TARGET_CHAR_BIT; + while (length > 0) { range_s *r1, *r2; @@ -585,9 +607,9 @@ value_available_contents_eq (const struct value *val1, int offset1, /* The usual case is for both values to be completely available. */ if (idx1 == -1 && idx2 == -1) - return (memcmp (val1->contents + offset1, - val2->contents + offset2, - length) == 0); + return (memcmp (val1->contents + (offset1 / TARGET_CHAR_BIT), + val2->contents + (offset2 / TARGET_CHAR_BIT), + (length / TARGET_CHAR_BIT)) == 0); /* The contents only match equal if the available set matches as well. */ else if (idx1 == -1 || idx2 == -1) @@ -620,9 +642,9 @@ value_available_contents_eq (const struct value *val1, int offset1, return 0; /* Compare the _available_ contents. */ - if (memcmp (val1->contents + offset1, - val2->contents + offset2, - l1) != 0) + if (memcmp (val1->contents + (offset1 / TARGET_CHAR_BIT), + val2->contents + (offset2 / TARGET_CHAR_BIT), + (l1 / TARGET_CHAR_BIT)) != 0) return 0; length -= h1; @@ -972,6 +994,7 @@ value_contents_copy_raw (struct value *dst, int dst_offset, { range_s *r; int i; + int src_bit_offset, dst_bit_offset, bit_length; /* A lazy DST would make that this copy operation useless, since as soon as DST's contents were un-lazied (by a later value_contents @@ -990,17 +1013,20 @@ value_contents_copy_raw (struct value *dst, int dst_offset, length); /* Copy the meta-data, adjusted. */ + src_bit_offset = src_offset * TARGET_CHAR_BIT; + dst_bit_offset = dst_offset * TARGET_CHAR_BIT; + bit_length = length * TARGET_CHAR_BIT; for (i = 0; VEC_iterate (range_s, src->unavailable, i, r); i++) { ULONGEST h, l; - l = max (r->offset, src_offset); - h = min (r->offset + r->length, src_offset + length); + l = max (r->offset, src_bit_offset); + h = min (r->offset + r->length, src_bit_offset + length); if (l < h) - mark_value_bytes_unavailable (dst, - dst_offset + (l - src_offset), - h - l); + mark_value_bits_unavailable (dst, + dst_bit_offset + (l - src_bit_offset), + h - l); } } @@ -2884,8 +2910,8 @@ unpack_value_bits_as_long_1 (struct type *field_type, const gdb_byte *valaddr, read_offset = bitpos / 8; if (original_value != NULL - && !value_bytes_available (original_value, embedded_offset + read_offset, - bytes_read)) + && !value_bits_available (original_value, embedded_offset + bitpos, + bitsize)) return 0; val = extract_unsigned_integer (valaddr + embedded_offset + read_offset, diff --git a/gdb/value.h b/gdb/value.h index db964e3..6b158df 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -436,6 +436,14 @@ extern int value_bits_synthetic_pointer (const struct value *value, extern int value_bytes_available (const struct value *value, int offset, int length); +/* Given a value, determine whether the contents bits starting at + OFFSET and extending for LENGTH bits are available. This returns + nonzero if all bits in the given range are available, zero if any + bit is unavailable. */ + +extern int value_bits_available (const struct value *value, + int offset, int length); + /* Like value_bytes_available, but return false if any byte in the whole object is unavailable. */ extern int value_entirely_available (struct value *value); @@ -450,6 +458,12 @@ extern int value_entirely_unavailable (struct value *value); extern void mark_value_bytes_unavailable (struct value *value, int offset, int length); +/* Mark VALUE's content bits starting at OFFSET and extending for + LENGTH bits as unavailable. */ + +extern void mark_value_bits_unavailable (struct value *value, + int offset, int length); + /* Compare LENGTH bytes of VAL1's contents starting at OFFSET1 with LENGTH bytes of VAL2's contents starting at OFFSET2.