From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 53409 invoked by alias); 15 Apr 2015 19:47:57 -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 53341 invoked by uid 89); 15 Apr 2015 19:47:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: usevmg21.ericsson.net Received: from usevmg21.ericsson.net (HELO usevmg21.ericsson.net) (198.24.6.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Wed, 15 Apr 2015 19:47:53 +0000 Received: from EUSAAHC001.ericsson.se (Unknown_Domain [147.117.188.75]) by usevmg21.ericsson.net (Symantec Mail Security) with SMTP id 56.E5.17241.C5D5E255; Wed, 15 Apr 2015 14:45:16 +0200 (CEST) Received: from elxcz23q12-y4.mo.ca.am.ericsson.se (147.117.188.8) by smtps-am.internal.ericsson.com (147.117.188.75) with Microsoft SMTP Server (TLS) id 14.3.210.2; Wed, 15 Apr 2015 15:47:47 -0400 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH v2 5/7] target: consider addressable unit size when reading/writing memory Date: Wed, 15 Apr 2015 19:47:00 -0000 Message-ID: <1429127258-1033-6-git-send-email-simon.marchi@ericsson.com> In-Reply-To: <1429127258-1033-1-git-send-email-simon.marchi@ericsson.com> References: <1429127258-1033-1-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2015-04/txt/msg00589.txt.bz2 If we are reading/writing from a memory object, the length represents the number of "addresses" to read/write, so the addressable unit size needs to be taken into account when allocating memory on gdb's side. gdb/ChangeLog: * target.c (target_read): Consider addressable unit size when reading from a memory object. (read_memory_robust): Same. (read_whatever_is_readable): Same. (target_write_with_progress): Consider addressable unit size when writing to a memory object. * target.h (target_read): Update documentation. (target_write): Add documentation. --- gdb/target.c | 35 ++++++++++++++++++++++++++++------- gdb/target.h | 33 ++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/gdb/target.c b/gdb/target.c index bd9a0eb..437b34e 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1589,6 +1589,15 @@ target_read (struct target_ops *ops, ULONGEST offset, LONGEST len) { LONGEST xfered_total = 0; + int unit_size = 1; + + /* If we are reading from a memory object, find the length of an addressable + unit for that architecture. */ + if (object == TARGET_OBJECT_MEMORY + || object == TARGET_OBJECT_STACK_MEMORY + || object == TARGET_OBJECT_CODE_MEMORY + || object == TARGET_OBJECT_RAW_MEMORY) + unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch()); while (xfered_total < len) { @@ -1596,7 +1605,7 @@ target_read (struct target_ops *ops, enum target_xfer_status status; status = target_read_partial (ops, object, annex, - buf + xfered_total, + buf + xfered_total * unit_size, offset + xfered_total, len - xfered_total, &xfered_partial); @@ -1639,6 +1648,7 @@ target_read (struct target_ops *ops, static void read_whatever_is_readable (struct target_ops *ops, const ULONGEST begin, const ULONGEST end, + int unit_size, VEC(memory_read_result_s) **result) { gdb_byte *buf = xmalloc (end - begin); @@ -1705,7 +1715,7 @@ read_whatever_is_readable (struct target_ops *ops, } xfer = target_read (ops, TARGET_OBJECT_MEMORY, NULL, - buf + (first_half_begin - begin), + buf + (first_half_begin - begin) * unit_size, first_half_begin, first_half_end - first_half_begin); @@ -1741,8 +1751,9 @@ read_whatever_is_readable (struct target_ops *ops, /* The [current_end, end) range has been read. */ LONGEST region_len = end - current_end; - r.data = xmalloc (region_len); - memcpy (r.data, buf + current_end - begin, region_len); + r.data = xmalloc (region_len * unit_size); + memcpy (r.data, buf + (current_end - begin) * unit_size, + region_len * unit_size); r.begin = current_end; r.end = end; xfree (buf); @@ -1769,6 +1780,7 @@ read_memory_robust (struct target_ops *ops, const ULONGEST offset, const LONGEST len) { VEC(memory_read_result_s) *result = 0; + int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ()); LONGEST xfered_total = 0; while (xfered_total < len) @@ -1794,7 +1806,7 @@ read_memory_robust (struct target_ops *ops, else { LONGEST to_read = min (len - xfered_total, region_len); - gdb_byte *buffer = (gdb_byte *)xmalloc (to_read); + gdb_byte *buffer = (gdb_byte *) xmalloc (to_read * unit_size); LONGEST xfered_partial = target_read (ops, TARGET_OBJECT_MEMORY, NULL, @@ -1806,7 +1818,7 @@ read_memory_robust (struct target_ops *ops, /* Got an error reading full chunk. See if maybe we can read some subrange. */ xfree (buffer); - read_whatever_is_readable (ops, offset + xfered_total, + read_whatever_is_readable (ops, offset + xfered_total, unit_size, offset + xfered_total + to_read, &result); xfered_total += to_read; } @@ -1836,6 +1848,15 @@ target_write_with_progress (struct target_ops *ops, void (*progress) (ULONGEST, void *), void *baton) { LONGEST xfered_total = 0; + int unit_size = 1; + + /* If we are writing to a memory object, find the length of an addressable + unit for that architecture. */ + if (object == TARGET_OBJECT_MEMORY + || object == TARGET_OBJECT_STACK_MEMORY + || object == TARGET_OBJECT_CODE_MEMORY + || object == TARGET_OBJECT_RAW_MEMORY) + unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ()); /* Give the progress callback a chance to set up. */ if (progress) @@ -1847,7 +1868,7 @@ target_write_with_progress (struct target_ops *ops, enum target_xfer_status status; status = target_write_partial (ops, object, annex, - (gdb_byte *) buf + xfered_total, + buf + xfered_total * unit_size, offset + xfered_total, len - xfered_total, &xfered_partial); diff --git a/gdb/target.h b/gdb/target.h index ad50f07..6f9ff65 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -259,13 +259,17 @@ typedef enum target_xfer_status ULONGEST len, ULONGEST *xfered_len); -/* Request that OPS transfer up to LEN 8-bit bytes of the target's - OBJECT. The OFFSET, for a seekable object, specifies the - starting point. The ANNEX can be used to provide additional - data-specific information to the target. - - Return the number of bytes actually transfered, or a negative error - code (an 'enum target_xfer_error' value) if the transfer is not +/* Request that OPS transfer up to LEN addressable units of the target's + OBJECT. When reading from a memory object, the size of an addressable unit + is architecture dependent and can be found using + gdbarch_addressable_memory_unit_size. Otherwise, an addressable unit is 1 + byte long. BUF should point to a buffer large enough to hold the read data, + taking into account the addressable unit size. The OFFSET, for a seekable + object, specifies the starting point. The ANNEX can be used to provide + additional data-specific information to the target. + + Return the number of addressable units actually transferred, or a negative + error code (an 'enum target_xfer_error' value) if the transfer is not supported or otherwise fails. Return of a positive value less than LEN indicates that no further transfer is possible. Unlike the raw to_xfer_partial interface, callers of these functions do not need @@ -294,6 +298,21 @@ extern VEC(memory_read_result_s)* read_memory_robust (struct target_ops *ops, const ULONGEST offset, const LONGEST len); +/* Request that OPS transfer up to LEN addressable units from BUF to the + target's OBJECT. When writing to a memory object, the addressable unit + size is architecture dependent and can be found using + gdbarch_addressable_memory_unit_size. Otherwise, an addressable unit is 1 + byte long. The OFFSET, for a seekable object, specifies the starting point. + The ANNEX can be used to provide additional data-specific information to + the target. + + Return the number of addressable units actually transferred, or a negative + error code (an 'enum target_xfer_status' value) if the transfer is not + supported or otherwise fails. Return of a positive value less than + LEN indicates that no further transfer is possible. Unlike the raw + to_xfer_partial interface, callers of these functions do not need to + retry partial transfers. */ + extern LONGEST target_write (struct target_ops *ops, enum target_object object, const char *annex, const gdb_byte *buf, -- 2.1.4