From patchwork Wed Apr 8 19:56:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 6101 Received: (qmail 56040 invoked by alias); 8 Apr 2015 19:56:35 -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 55960 invoked by uid 89); 8 Apr 2015 19:56:35 -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: usevmg20.ericsson.net Received: from usevmg20.ericsson.net (HELO usevmg20.ericsson.net) (198.24.6.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Wed, 08 Apr 2015 19:56:32 +0000 Received: from EUSAAHC008.ericsson.se (Unknown_Domain [147.117.188.96]) by usevmg20.ericsson.net (Symantec Mail Security) with SMTP id 53.C8.12456.76135255; Wed, 8 Apr 2015 15:47:19 +0200 (CEST) Received: from elxcz23q12-y4.mo.ca.am.ericsson.se (147.117.188.8) by smtps-am.internal.ericsson.com (147.117.188.96) with Microsoft SMTP Server (TLS) id 14.3.210.2; Wed, 8 Apr 2015 15:56:24 -0400 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH 5/7] target: consider byte size when reading/writing memory Date: Wed, 8 Apr 2015 15:56:17 -0400 Message-ID: <1428522979-28709-6-git-send-email-simon.marchi@ericsson.com> In-Reply-To: <1428522979-28709-1-git-send-email-simon.marchi@ericsson.com> References: <1428522979-28709-1-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 X-IsSubscribed: yes If we are reading/writing from a memory object, the length represents the number of "addresses" to read/write, so the byte size needs to be taken into account when allocating memory on gdb's side. gdb/ChangeLog: * target.c (target_read): Consider byte size when reading from a memory object. (read_memory_robust): Same. (read_whatever_is_readable): Same. (target_write_with_progress): Consider byte size when writing to a memory object. * target.h (target_read): Update documentation. (target_write): Add documentation. --- gdb/target.c | 35 ++++++++++++++++++++++++++++------- gdb/target.h | 26 ++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/gdb/target.c b/gdb/target.c index bd9a0eb..d3ada16 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 byte_size = 1; + + /* If we are reading a memory object, find the length of a byte for that + architecture. */ + if (object == TARGET_OBJECT_MEMORY + || object == TARGET_OBJECT_STACK_MEMORY + || object == TARGET_OBJECT_CODE_MEMORY + || object == TARGET_OBJECT_RAW_MEMORY) + byte_size = gdbarch_memory_byte_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 * byte_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 byte_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) * byte_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 * byte_size); + memcpy (r.data, buf + (current_end - begin) * byte_size, + region_len * byte_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 byte_size = gdbarch_memory_byte_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 * byte_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, byte_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 byte_size = 1; + + /* If we are writing to a memory object, find the length of a byte for that + architecture. */ + if (object == TARGET_OBJECT_MEMORY + || object == TARGET_OBJECT_STACK_MEMORY + || object == TARGET_OBJECT_CODE_MEMORY + || object == TARGET_OBJECT_RAW_MEMORY) + byte_size = gdbarch_memory_byte_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 * byte_size, offset + xfered_total, len - xfered_total, &xfered_partial); diff --git a/gdb/target.h b/gdb/target.h index ad50f07..c72f8b4 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -259,12 +259,15 @@ 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 +/* Request that OPS transfer up to LEN bytes of the target's OBJECT. When + reading from a memory object, the byte size is architecture dependent and + can be found using gdbarch_memory_byte_size. Otherwise, a byte is 1 octet + long. BUF should point to a buffer large enough to hold the read data, + taking into account the byte 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 bytes actually transfered, or a negative error + Return the number of bytes 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 @@ -294,6 +297,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 bytes from BUF to the target's + OBJECT. When writing to a memory object, the byte size is + architecture dependent and can be found using + gdbarch_memory_byte_size. Otherwise, a byte is 1 octet 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 bytes 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,