linux-nat: Exploit /proc/<pid>/mem for writing
So far linux_proc_xfer_partial refused to handle write requests. This is still based on the assumption that the Linux kernel does not support writes to /proc/<pid>/mem. That used to be true, but has changed with Linux 2.6.39 released in May 2011. This patch lifts this restriction and now exploits /proc/<pid>/mem for writing to inferior memory as well, if possible. gdb/ChangeLog: * linux-nat.c (linux_proc_xfer_partial): Handle write operations as well.
This commit is contained in:
parent
8a6200ba86
commit
a379284af2
|
@ -1,3 +1,8 @@
|
||||||
|
2017-03-14 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
* linux-nat.c (linux_proc_xfer_partial): Handle write operations
|
||||||
|
as well.
|
||||||
|
|
||||||
2017-03-14 Pedro Alves <palves@redhat.com>
|
2017-03-14 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* cp-name-parser.y (cp_demangled_name_to_comp): Update comment.
|
* cp-name-parser.y (cp_demangled_name_to_comp): Update comment.
|
||||||
|
|
|
@ -3978,10 +3978,9 @@ linux_child_pid_to_exec_file (struct target_ops *self, int pid)
|
||||||
return linux_proc_pid_to_exec_file (pid);
|
return linux_proc_pid_to_exec_file (pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implement the to_xfer_partial interface for memory reads using the /proc
|
/* Implement the to_xfer_partial target method using /proc/<pid>/mem.
|
||||||
filesystem. Because we can use a single read() call for /proc, this
|
Because we can use a single read/write call, this can be much more
|
||||||
can be much more efficient than banging away at PTRACE_PEEKTEXT,
|
efficient than banging away at PTRACE_PEEKTEXT. */
|
||||||
but it doesn't support writes. */
|
|
||||||
|
|
||||||
static enum target_xfer_status
|
static enum target_xfer_status
|
||||||
linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
|
linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||||
|
@ -3993,7 +3992,7 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||||
int fd;
|
int fd;
|
||||||
char filename[64];
|
char filename[64];
|
||||||
|
|
||||||
if (object != TARGET_OBJECT_MEMORY || !readbuf)
|
if (object != TARGET_OBJECT_MEMORY)
|
||||||
return TARGET_XFER_EOF;
|
return TARGET_XFER_EOF;
|
||||||
|
|
||||||
/* Don't bother for one word. */
|
/* Don't bother for one word. */
|
||||||
|
@ -4004,26 +4003,27 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||||
thread. That requires some juggling, but is even faster. */
|
thread. That requires some juggling, but is even faster. */
|
||||||
xsnprintf (filename, sizeof filename, "/proc/%d/mem",
|
xsnprintf (filename, sizeof filename, "/proc/%d/mem",
|
||||||
ptid_get_pid (inferior_ptid));
|
ptid_get_pid (inferior_ptid));
|
||||||
fd = gdb_open_cloexec (filename, O_RDONLY | O_LARGEFILE, 0);
|
fd = gdb_open_cloexec (filename, ((readbuf ? O_RDONLY : O_WRONLY)
|
||||||
|
| O_LARGEFILE), 0);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return TARGET_XFER_EOF;
|
return TARGET_XFER_EOF;
|
||||||
|
|
||||||
/* If pread64 is available, use it. It's faster if the kernel
|
/* Use pread64/pwrite64 if available, since they save a syscall and can
|
||||||
supports it (only one syscall), and it's 64-bit safe even on
|
handle 64-bit offsets even on 32-bit platforms (for instance, SPARC
|
||||||
32-bit platforms (for instance, SPARC debugging a SPARC64
|
debugging a SPARC64 application). */
|
||||||
application). */
|
|
||||||
#ifdef HAVE_PREAD64
|
#ifdef HAVE_PREAD64
|
||||||
if (pread64 (fd, readbuf, len, offset) != len)
|
ret = (readbuf ? pread64 (fd, readbuf, len, offset)
|
||||||
|
: pwrite64 (fd, writebuf, len, offset));
|
||||||
#else
|
#else
|
||||||
if (lseek (fd, offset, SEEK_SET) == -1 || read (fd, readbuf, len) != len)
|
ret = lseek (fd, offset, SEEK_SET);
|
||||||
|
if (ret != -1)
|
||||||
|
ret = (readbuf ? read (fd, readbuf, len)
|
||||||
|
: write (fd, writebuf, len));
|
||||||
#endif
|
#endif
|
||||||
ret = 0;
|
|
||||||
else
|
|
||||||
ret = len;
|
|
||||||
|
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == -1 || ret == 0)
|
||||||
return TARGET_XFER_EOF;
|
return TARGET_XFER_EOF;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue