This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 5/7] target: consider byte size when reading/writing memory
- From: Simon Marchi <simon dot marchi at ericsson dot com>
- To: <gdb-patches at sourceware dot org>
- Cc: Simon Marchi <simon dot marchi at ericsson dot com>
- Date: Wed, 8 Apr 2015 15:56:17 -0400
- Subject: [PATCH 5/7] target: consider byte size when reading/writing memory
- Authentication-results: sourceware.org; auth=none
- References: <1428522979-28709-1-git-send-email-simon dot marchi at ericsson dot com>
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,
--
2.1.4