This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]