This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[commit] Fix xfer-partial edge cases
- From: Andrew Cagney <cagney at gnu dot org>
- To: gdb-patches at sources dot redhat dot com
- Date: Fri, 01 Oct 2004 12:16:30 -0400
- Subject: [commit] Fix xfer-partial edge cases
Hello,
This cleans up xfer_using_stratum and inf_ptrace_xfer_partial that were
flushed out when I enabled that code for GNU/Linux (pending patch). Of
note: a ptrace write parameter was wrong; the partial xfer loop wasn't
updating all it needed.
committed,
Andrew
2004-10-01 Andrew Cagney <cagney@gnu.org>
* target.c (xfer_using_stratum): Change return type to LONGEST.
On each iteration offset, readbuf and writebuf.
* inf-ptrace.c (inf_ptrace_xfer_partial): Simplify computation of
partial_length, and read/modify/write predicate, update comments.
Pass buffer.word to ptrace write.
Index: inf-ptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-ptrace.c,v
retrieving revision 1.9
diff -p -u -r1.9 inf-ptrace.c
--- inf-ptrace.c 30 Sep 2004 16:46:40 -0000 1.9
+++ inf-ptrace.c 1 Oct 2004 16:10:49 -0000
@@ -514,25 +514,27 @@ inf_ptrace_xfer_partial (struct target_o
ULONGEST rounded_offset;
LONGEST partial_len;
- /* Round the start address down to the next long word boundary. */
+ /* Round the start offset down to the next long word
+ boundary. */
rounded_offset = offset & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
- /* Truncate the length so that at max a single word will be
- transfered. Remember, this function is required to perform
- only a partial read so no more than one word should be
- transfered). */
- if (rounded_offset + sizeof (PTRACE_TYPE_RET) < offset + len)
- partial_len = sizeof (PTRACE_TYPE_RET) - (offset - rounded_offset);
- else
+ /* Since ptrace will transfer a single word starting at that
+ rounded_offset the partial_len needs to be adjusted down to
+ that (remember this function only does a single transfer).
+ Should the required length be even less, adjust it down
+ again. */
+ partial_len = (rounded_offset + sizeof (PTRACE_TYPE_RET)) - offset;
+ if (partial_len > len)
partial_len = len;
if (writebuf)
{
- /* Fill start and end extra bytes of buffer with existing
- memory data. */
+ /* If OFFSET:PARTIAL_LEN is smaller than
+ ROUNDED_OFFSET:WORDSIZE then a read/modify write will
+ be needed. Read in the entire word. */
if (rounded_offset < offset
- || (partial_len + (offset - rounded_offset)
- < sizeof (PTRACE_TYPE_RET)))
+ || (offset + partial_len
+ < rounded_offset + sizeof (PTRACE_TYPE_RET)))
/* Need part of initial word -- fetch it. */
buffer.word = ptrace (PT_READ_I, PIDGET (inferior_ptid),
(PTRACE_TYPE_ARG3) (long) rounded_offset,
@@ -545,7 +547,7 @@ inf_ptrace_xfer_partial (struct target_o
errno = 0;
ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
(PTRACE_TYPE_ARG3) (long) rounded_offset,
- (int) buffer.byte);
+ buffer.word);
if (errno)
{
/* Using the appropriate one (I or D) is necessary for
@@ -553,7 +555,7 @@ inf_ptrace_xfer_partial (struct target_o
errno = 0;
ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
(PTRACE_TYPE_ARG3) (long) rounded_offset,
- (int) buffer.byte);
+ buffer.word);
if (errno)
return 0;
}
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.85
diff -p -u -r1.85 target.c
--- target.c 30 Sep 2004 20:36:27 -0000 1.85
+++ target.c 1 Oct 2004 16:10:49 -0000
@@ -927,9 +927,9 @@ target_xfer_partial (struct target_ops *
implementing another singluar mechanism (for instance, a generic
object:annex onto inferior:object:annex say). */
-static int
+static LONGEST
xfer_using_stratum (enum target_object object, const char *annex,
- CORE_ADDR memaddr, int len, void *readbuf,
+ ULONGEST offset, LONGEST len, void *readbuf,
const void *writebuf)
{
LONGEST xfered;
@@ -946,7 +946,7 @@ xfer_using_stratum (enum target_object o
while (1)
{
xfered = target_xfer_partial (target, object, annex,
- readbuf, writebuf, memaddr, len);
+ readbuf, writebuf, offset, len);
if (xfered > 0)
{
/* The partial xfer succeeded, update the counts, check that
@@ -955,6 +955,11 @@ xfer_using_stratum (enum target_object o
len -= xfered;
if (len <= 0)
return 0;
+ offset += xfered;
+ if (readbuf != NULL)
+ readbuf = (bfd_byte *) readbuf + xfered;
+ if (writebuf != NULL)
+ writebuf = (bfd_byte *) writebuf + xfered;
target = target_stack;
}
else if (xfered < 0)