diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 62819e798d..bfeaea0338 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2004-10-01 Andrew Cagney + + * 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. + 2004-10-01 Paul N. Hilfinger * symfile.c (init_filename_language_table): Add extensions for diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c index 4a37d394d6..0aa6fd17c8 100644 --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -514,25 +514,27 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object, 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_ops *ops, enum target_object object, 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_ops *ops, enum target_object object, errno = 0; ptrace (PT_WRITE_I, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) (long) rounded_offset, - (int) buffer.byte); + buffer.word); if (errno) return 0; } diff --git a/gdb/target.c b/gdb/target.c index 81784da4a4..48bf8fb6f5 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -927,9 +927,9 @@ target_xfer_partial (struct target_ops *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 object, const char *annex, 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 object, const char *annex, 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)