aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2012-05-21 23:50:25 +0000
committerMaciej W. Rozycki <macro@linux-mips.org>2012-05-21 23:50:25 +0000
commit4934b29e91a6f9887cf0641575054279841d82f8 (patch)
treef230ec207edc1d92766b20fa8a12087737c9d344 /gdb
parentb1af9e975066c48b043c5234199effd47115b4d4 (diff)
downloadgdb-4934b29e91a6f9887cf0641575054279841d82f8.zip
gdb-4934b29e91a6f9887cf0641575054279841d82f8.tar.gz
gdb-4934b29e91a6f9887cf0641575054279841d82f8.tar.bz2
* linux-low.c (linux_store_registers): Don't re-retrieve data
with ptrace that has already been obtained from /proc. Always copy any data retrieved with ptrace to the buffer supplied.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/gdbserver/ChangeLog6
-rw-r--r--gdb/gdbserver/linux-low.c59
2 files changed, 43 insertions, 22 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 59c500a..cf34bac 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,9 @@
+2012-05-21 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * linux-low.c (linux_store_registers): Don't re-retrieve data
+ with ptrace that has already been obtained from /proc. Always
+ copy any data retrieved with ptrace to the buffer supplied.
+
2012-05-11 Yao Qi <yao@codesourcery.com>
Pedro Alves <palves@redhat.com>
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 143a2ed..712cc03 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4378,23 +4378,20 @@ linux_store_registers (struct regcache *regcache, int regno)
static int
linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
+ int pid = lwpid_of (get_thread_lwp (current_inferior));
+ register PTRACE_XFER_TYPE *buffer;
+ register CORE_ADDR addr;
+ register int count;
+ char filename[64];
register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
- / sizeof (PTRACE_XFER_TYPE);
- /* Allocate buffer of that many longwords. */
- register PTRACE_XFER_TYPE *buffer
- = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+ int ret;
int fd;
- char filename[64];
- int pid = lwpid_of (get_thread_lwp (current_inferior));
/* Try using /proc. Don't bother for one word. */
if (len >= 3 * sizeof (long))
{
+ int bytes;
+
/* We could keep this file open and cache it - possibly one per
thread. That requires some juggling, but is even faster. */
sprintf (filename, "/proc/%d/mem", pid);
@@ -4407,38 +4404,56 @@ linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
32-bit platforms (for instance, SPARC debugging a SPARC64
application). */
#ifdef HAVE_PREAD64
- if (pread64 (fd, myaddr, len, memaddr) != len)
+ bytes = pread64 (fd, myaddr, len, memaddr);
#else
- if (lseek (fd, memaddr, SEEK_SET) == -1 || read (fd, myaddr, len) != len)
+ bytes = -1;
+ if (lseek (fd, memaddr, SEEK_SET) != -1)
+ bytes = read (fd, myaddr, len);
#endif
- {
- close (fd);
- goto no_proc;
- }
close (fd);
- return 0;
+ if (bytes == len)
+ return 0;
+
+ /* Some data was read, we'll try to get the rest with ptrace. */
+ if (bytes > 0)
+ {
+ memaddr += bytes;
+ myaddr += bytes;
+ len -= bytes;
+ }
}
no_proc:
+ /* Round starting address down to longword boundary. */
+ addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+ /* Round ending address up; get number of longwords that makes. */
+ count = ((((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
+ / sizeof (PTRACE_XFER_TYPE));
+ /* Allocate buffer of that many longwords. */
+ buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+
/* Read all the longwords */
+ errno = 0;
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
{
- errno = 0;
/* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
about coercing an 8 byte integer to a 4 byte pointer. */
buffer[i] = ptrace (PTRACE_PEEKTEXT, pid,
(PTRACE_ARG3_TYPE) (uintptr_t) addr, 0);
if (errno)
- return errno;
+ break;
}
+ ret = errno;
/* Copy appropriate bytes out of the buffer. */
+ i *= sizeof (PTRACE_XFER_TYPE);
+ i -= memaddr & (sizeof (PTRACE_XFER_TYPE) - 1);
memcpy (myaddr,
(char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
- len);
+ i < len ? i : len);
- return 0;
+ return ret;
}
/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's