From patchwork Tue May 9 17:46:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Arnez X-Patchwork-Id: 20355 Received: (qmail 3857 invoked by alias); 9 May 2017 18:00:22 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 3576 invoked by uid 89); 9 May 2017 18:00:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-22.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy= X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 09 May 2017 18:00:01 +0000 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v49HwTvB098555 for ; Tue, 9 May 2017 14:00:03 -0400 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0a-001b2d01.pphosted.com with ESMTP id 2abfbds2q5-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 09 May 2017 14:00:02 -0400 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 9 May 2017 18:59:59 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 9 May 2017 18:59:57 +0100 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v49HxvOo16449830 for ; Tue, 9 May 2017 17:59:57 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C409B52043 for ; Tue, 9 May 2017 17:57:20 +0100 (BST) Received: from oc1027705133.ibm.com (unknown [9.152.212.109]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id AA55C5203F for ; Tue, 9 May 2017 17:57:20 +0100 (BST) From: Andreas Arnez To: gdb-patches@sourceware.org Subject: [PATCH v2 19/19] read/write_pieced_value: Merge into one function Date: Tue, 9 May 2017 19:46:15 +0200 In-Reply-To: <1494352015-10465-1-git-send-email-arnez@linux.vnet.ibm.com> References: <1494352015-10465-1-git-send-email-arnez@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17050917-0012-0000-0000-00000526C761 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17050917-0013-0000-0000-00001865B87B Message-Id: <1494352015-10465-20-git-send-email-arnez@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-05-09_14:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1705090099 X-IsSubscribed: yes Since read_pieced_value and write_pieced_value share significant logic, this patch merges them into a single function rw_pieced_value. gdb/ChangeLog: * dwarf2loc.c (rw_pieced_value): New. Merge logic from... (read_pieced_value, write_pieced_value): ...here. Reduce to wrappers that just call rw_pieced_value. --- gdb/dwarf2loc.c | 357 +++++++++++++++++++++++++++----------------------------- 1 file changed, 175 insertions(+), 182 deletions(-) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 94175ef..beb11f5 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1761,31 +1761,55 @@ bits_to_bytes (ULONGEST start, ULONGEST n_bits) return (start % 8 + n_bits + 7) / 8; } +/* Read or write a pieced value V. If FROM != NULL, operate in "write + mode": copy FROM into the pieces comprising V. If FROM == NULL, + operate in "read mode": fetch the contents of the (lazy) value V by + composing it from its pieces. */ + static void -read_pieced_value (struct value *v) +rw_pieced_value (struct value *v, struct value *from) { int i; LONGEST offset = 0, max_offset; ULONGEST bits_to_skip; - gdb_byte *contents; + gdb_byte *v_contents; + const gdb_byte *from_contents; struct piece_closure *c = (struct piece_closure *) value_computed_closure (v); std::vector buffer; int bits_big_endian = gdbarch_bits_big_endian (get_type_arch (value_type (v))); - if (value_type (v) != value_enclosing_type (v)) - internal_error (__FILE__, __LINE__, - _("Should not be able to create a lazy value with " - "an enclosing type")); + if (from != NULL) + { + from_contents = value_contents (from); + v_contents = NULL; + } + else + { + if (value_type (v) != value_enclosing_type (v)) + internal_error (__FILE__, __LINE__, + _("Should not be able to create a lazy value with " + "an enclosing type")); + v_contents = value_contents_raw (v); + from_contents = NULL; + } - contents = value_contents_raw (v); bits_to_skip = 8 * value_offset (v); if (value_bitsize (v)) { bits_to_skip += (8 * value_offset (value_parent (v)) + value_bitpos (v)); - max_offset = value_bitsize (v); + if (from != NULL + && (gdbarch_byte_order (get_type_arch (value_type (from))) + == BFD_ENDIAN_BIG)) + { + /* Use the least significant bits of FROM. */ + max_offset = 8 * TYPE_LENGTH (value_type (from)); + offset = max_offset - value_bitsize (v); + } + else + max_offset = value_bitsize (v); } else max_offset = 8 * TYPE_LENGTH (value_type (v)); @@ -1797,13 +1821,12 @@ read_pieced_value (struct value *v) for (; i < c->n_pieces && offset < max_offset; i++) { struct dwarf_expr_piece *p = &c->pieces[i]; - size_t this_size, this_size_bits; + size_t this_size_bits, this_size; this_size_bits = p->size - bits_to_skip; if (this_size_bits > max_offset - offset) this_size_bits = max_offset - offset; - /* Copy from the source to DEST_BUFFER. */ switch (p->location) { case DWARF_VALUE_REGISTER: @@ -1826,39 +1849,134 @@ read_pieced_value (struct value *v) this_size = bits_to_bytes (bits_to_skip, this_size_bits); buffer.reserve (this_size); - if (!get_frame_register_bytes (frame, gdb_regnum, - bits_to_skip / 8, - this_size, buffer.data (), - &optim, &unavail)) + if (from == NULL) { - if (optim) - mark_value_bits_optimized_out (v, offset, this_size_bits); - if (unavail) - mark_value_bits_unavailable (v, offset, this_size_bits); - break; + /* Read mode. */ + if (!get_frame_register_bytes (frame, gdb_regnum, + bits_to_skip / 8, + this_size, buffer.data (), + &optim, &unavail)) + { + if (optim) + mark_value_bits_optimized_out (v, offset, + this_size_bits); + if (unavail) + mark_value_bits_unavailable (v, offset, + this_size_bits); + break; + } + + copy_bitwise (v_contents, offset, + buffer.data (), bits_to_skip % 8, + this_size_bits, bits_big_endian); + } + else + { + /* Write mode. */ + if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0) + { + /* Data is copied non-byte-aligned into the register. + Need some bits from original register value. */ + get_frame_register_bytes (frame, gdb_regnum, + bits_to_skip / 8, + this_size, buffer.data (), + &optim, &unavail); + if (optim) + throw_error (OPTIMIZED_OUT_ERROR, + _("Can't do read-modify-write to " + "update bitfield; containing word " + "has been optimized out")); + if (unavail) + throw_error (NOT_AVAILABLE_ERROR, + _("Can't do read-modify-write to " + "update bitfield; containing word " + "is unavailable")); + } + + copy_bitwise (buffer.data (), bits_to_skip % 8, + from_contents, offset, + this_size_bits, bits_big_endian); + put_frame_register_bytes (frame, gdb_regnum, + bits_to_skip / 8, + this_size, buffer.data ()); } - copy_bitwise (contents, offset, - buffer.data (), bits_to_skip % 8, - this_size_bits, bits_big_endian); } break; case DWARF_VALUE_MEMORY: - bits_to_skip += p->offset; - this_size = bits_to_bytes (bits_to_skip, this_size_bits); - buffer.reserve (this_size); - - read_value_memory (v, offset, - p->v.mem.in_stack_memory, - p->v.mem.addr + bits_to_skip / 8, - buffer.data (), this_size); - copy_bitwise (contents, offset, - buffer.data (), bits_to_skip % 8, - this_size_bits, bits_big_endian); + { + bits_to_skip += p->offset; + + CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8; + + if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0 + && offset % 8 == 0) + { + /* Everything is byte-aligned; no buffer needed. */ + if (from != NULL) + write_memory_with_notification (start_addr, + (from_contents + + offset / 8), + this_size_bits / 8); + else + read_value_memory (v, offset, + p->v.mem.in_stack_memory, + p->v.mem.addr + bits_to_skip / 8, + v_contents + offset / 8, + this_size_bits / 8); + break; + } + + this_size = bits_to_bytes (bits_to_skip, this_size_bits); + buffer.reserve (this_size); + + if (from == NULL) + { + /* Read mode. */ + read_value_memory (v, offset, + p->v.mem.in_stack_memory, + p->v.mem.addr + bits_to_skip / 8, + buffer.data (), this_size); + copy_bitwise (v_contents, offset, + buffer.data (), bits_to_skip % 8, + this_size_bits, bits_big_endian); + break; + } + + /* Write mode. */ + if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0) + { + if (this_size <= 8) + { + /* Perform a single read for small sizes. */ + read_memory (start_addr, buffer.data (), this_size); + } + else + { + /* Only the first and last bytes can possibly have any + bits reused. */ + read_memory (start_addr, buffer.data (), 1); + read_memory (start_addr + this_size - 1, + &buffer[this_size - 1], 1); + } + } + + copy_bitwise (buffer.data (), bits_to_skip % 8, + from_contents, offset, + this_size_bits, bits_big_endian); + write_memory_with_notification (start_addr, buffer.data (), + this_size); + } break; case DWARF_VALUE_STACK: { + if (from != NULL) + { + mark_value_bits_optimized_out (v, offset, this_size_bits); + break; + } + struct objfile *objfile = dwarf2_per_cu_objfile (c->per_cu); struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile); ULONGEST stack_value_size_bits @@ -1874,7 +1992,7 @@ read_pieced_value (struct value *v) else bits_to_skip += p->offset; - copy_bitwise (contents, offset, + copy_bitwise (v_contents, offset, value_contents_all (p->v.value), bits_to_skip, this_size_bits, bits_big_endian); @@ -1883,6 +2001,12 @@ read_pieced_value (struct value *v) case DWARF_VALUE_LITERAL: { + if (from != NULL) + { + mark_value_bits_optimized_out (v, offset, this_size_bits); + break; + } + ULONGEST literal_size_bits = 8 * p->v.literal.length; size_t n = this_size_bits; @@ -1893,15 +2017,21 @@ read_pieced_value (struct value *v) if (n > literal_size_bits - bits_to_skip) n = literal_size_bits - bits_to_skip; - copy_bitwise (contents, offset, + copy_bitwise (v_contents, offset, p->v.literal.data, bits_to_skip, n, bits_big_endian); } break; - /* These bits show up as zeros -- but do not cause the value - to be considered optimized-out. */ case DWARF_VALUE_IMPLICIT_POINTER: + if (from != NULL) + { + mark_value_bits_optimized_out (v, offset, this_size_bits); + break; + } + + /* These bits show up as zeros -- but do not cause the value to + be considered optimized-out. */ break; case DWARF_VALUE_OPTIMIZED_OUT: @@ -1917,154 +2047,17 @@ read_pieced_value (struct value *v) } } + static void -write_pieced_value (struct value *to, struct value *from) +read_pieced_value (struct value *v) { - int i; - ULONGEST bits_to_skip; - LONGEST offset = 0, max_offset; - const gdb_byte *contents; - struct piece_closure *c - = (struct piece_closure *) value_computed_closure (to); - std::vector buffer; - int bits_big_endian - = gdbarch_bits_big_endian (get_type_arch (value_type (to))); - - contents = value_contents (from); - bits_to_skip = 8 * value_offset (to); - if (value_bitsize (to)) - { - bits_to_skip += (8 * value_offset (value_parent (to)) - + value_bitpos (to)); - /* Use the least significant bits of FROM. */ - if (gdbarch_byte_order (get_type_arch (value_type (from))) - == BFD_ENDIAN_BIG) - { - max_offset = 8 * TYPE_LENGTH (value_type (from)); - offset = max_offset - value_bitsize (to); - } - else - max_offset = value_bitsize (to); - } - else - max_offset = 8 * TYPE_LENGTH (value_type (to)); - - /* Advance to the first non-skipped piece. */ - for (i = 0; i < c->n_pieces && bits_to_skip >= c->pieces[i].size; i++) - bits_to_skip -= c->pieces[i].size; - - for (; i < c->n_pieces && offset < max_offset; i++) - { - struct dwarf_expr_piece *p = &c->pieces[i]; - size_t this_size_bits, this_size; - - this_size_bits = p->size - bits_to_skip; - if (this_size_bits > max_offset - offset) - this_size_bits = max_offset - offset; - - switch (p->location) - { - case DWARF_VALUE_REGISTER: - { - struct frame_info *frame = frame_find_by_id (c->frame_id); - struct gdbarch *arch = get_frame_arch (frame); - int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno); - ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum); - - if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG - && p->offset + p->size < reg_bits) - { - /* Big-endian, and we want less than full size. */ - bits_to_skip += reg_bits - (p->offset + p->size); - } - else - bits_to_skip += p->offset; - - this_size = bits_to_bytes (bits_to_skip, this_size_bits); - buffer.reserve (this_size); - - if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0) - { - /* Data is copied non-byte-aligned into the register. - Need some bits from original register value. */ - int optim, unavail; - - if (!get_frame_register_bytes (frame, gdb_regnum, - bits_to_skip / 8, - this_size, buffer.data (), - &optim, &unavail)) - { - if (optim) - throw_error (OPTIMIZED_OUT_ERROR, - _("Can't do read-modify-write to " - "update bitfield; containing word " - "has been optimized out")); - if (unavail) - throw_error (NOT_AVAILABLE_ERROR, - _("Can't do read-modify-write to update " - "bitfield; containing word " - "is unavailable")); - } - } - - copy_bitwise (buffer.data (), bits_to_skip % 8, - contents, offset, - this_size_bits, bits_big_endian); - put_frame_register_bytes (frame, gdb_regnum, - bits_to_skip / 8, - this_size, buffer.data ()); - } - break; - case DWARF_VALUE_MEMORY: - { - bits_to_skip += p->offset; - - CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8; - - if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0 - && offset % 8 == 0) - { - /* Everything is byte-aligned; no buffer needed. */ - write_memory_with_notification (start_addr, - contents + offset / 8, - this_size_bits / 8); - break; - } - - this_size = bits_to_bytes (bits_to_skip, this_size_bits); - buffer.reserve (this_size); - - if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0) - { - if (this_size <= 8) - { - /* Perform a single read for small sizes. */ - read_memory (start_addr, buffer.data (), this_size); - } - else - { - /* Only the first and last bytes can possibly have any - bits reused. */ - read_memory (start_addr, buffer.data (), 1); - read_memory (start_addr + this_size - 1, - &buffer[this_size - 1], 1); - } - } + rw_pieced_value (v, NULL); +} - copy_bitwise (buffer.data (), bits_to_skip % 8, - contents, offset, - this_size_bits, bits_big_endian); - write_memory_with_notification (start_addr, buffer.data (), - this_size); - } - break; - default: - mark_value_bytes_optimized_out (to, 0, TYPE_LENGTH (value_type (to))); - break; - } - offset += this_size_bits; - bits_to_skip = 0; - } +static void +write_pieced_value (struct value *to, struct value *from) +{ + rw_pieced_value (to, from); } /* An implementation of an lval_funcs method to see whether a value is