aboutsummaryrefslogtreecommitdiff
path: root/gdb/nat
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2020-10-07 05:57:52 +0200
committerKamil Rytarowski <n54@gmx.com>2020-10-07 14:52:25 +0200
commit91e5e8db334b9a87c54f03982dfa0c88e3c9d7a1 (patch)
treea46f4667d6dd8c4b099d0c06b9884c39d9c1bb56 /gdb/nat
parent9529c852664bbfc64f3ccda6abd81fc1aced6f16 (diff)
downloadgdb-91e5e8db334b9a87c54f03982dfa0c88e3c9d7a1.zip
gdb-91e5e8db334b9a87c54f03982dfa0c88e3c9d7a1.tar.gz
gdb-91e5e8db334b9a87c54f03982dfa0c88e3c9d7a1.tar.bz2
Add common write_memory and read_memory NetBSD routines
Instead of sharing the native-only code with all BSDs with slightly different semantics of the kernels, share the NetBSD-only behavior beteen the NetBSD native and gdbserver setup. NetBSD does not differentiate the address space I and D in the operations (contrary to OpenBSD). NetBSD handles EACCES that integrates with NetBSD specific PaX MPROTECT error handling. Add a verbose message in the native client that an operation could be cancelled due to PaX MPROTECT setup. gdb/ChangeLog: * nat/netbsd-nat.c (write_memory, read_memory): Add. * nat/netbsd-nat.h (write_memory, read_memory): Likewise. * nbsd-nat.c (nbsd_nat_target::xfer_partial): Update. gdbserver/ChangeLog: * netbsd-low.cc (netbsd_process_target::read_memory) (netbsd_process_target::write_memory): Update.
Diffstat (limited to 'gdb/nat')
-rw-r--r--gdb/nat/netbsd-nat.c80
-rw-r--r--gdb/nat/netbsd-nat.h22
2 files changed, 102 insertions, 0 deletions
diff --git a/gdb/nat/netbsd-nat.c b/gdb/nat/netbsd-nat.c
index 41b67cb..cae9cc2 100644
--- a/gdb/nat/netbsd-nat.c
+++ b/gdb/nat/netbsd-nat.c
@@ -210,4 +210,84 @@ qxfer_siginfo (pid_t pid, const char *annex, unsigned char *readbuf,
return len;
}
+/* See netbsd-nat.h. */
+
+int
+write_memory (pid_t pid, unsigned const char *writebuf, CORE_ADDR offset,
+ size_t len, size_t *xfered_len)
+{
+ struct ptrace_io_desc io;
+ io.piod_op = PIOD_WRITE_D;
+ io.piod_len = len;
+
+ size_t bytes_written = 0;
+
+ /* Zero length write always succeeds. */
+ if (len > 0)
+ {
+ do
+ {
+ io.piod_addr = (void *)(writebuf + bytes_written);
+ io.piod_offs = (void *)(offset + bytes_written);
+
+ errno = 0;
+ int rv = ptrace (PT_IO, pid, &io, 0);
+ if (rv == -1)
+ {
+ gdb_assert (errno != 0);
+ return errno;
+ }
+ if (io.piod_len == 0)
+ return 0;
+
+ bytes_written += io.piod_len;
+ io.piod_len = len - bytes_written;
+ }
+ while (bytes_written < len);
+ }
+
+ if (xfered_len != nullptr)
+ *xfered_len = bytes_written;
+
+ return 0;
+}
+
+/* See netbsd-nat.h. */
+
+int
+read_memory (pid_t pid, unsigned char *readbuf, CORE_ADDR offset,
+ size_t len, size_t *xfered_len)
+{
+ struct ptrace_io_desc io;
+ io.piod_op = PIOD_READ_D;
+ io.piod_len = len;
+
+ size_t bytes_read = 0;
+
+ /* Zero length read always succeeds. */
+ if (len > 0)
+ {
+ do
+ {
+ io.piod_offs = (void *)(offset + bytes_read);
+ io.piod_addr = readbuf + bytes_read;
+
+ int rv = ptrace (PT_IO, pid, &io, 0);
+ if (rv == -1)
+ return errno;
+ if (io.piod_len == 0)
+ return 0;
+
+ bytes_read += io.piod_len;
+ io.piod_len = len - bytes_read;
+ }
+ while (bytes_read < len);
+ }
+
+ if (xfered_len != nullptr)
+ *xfered_len = bytes_read;
+
+ return 0;
+}
+
}
diff --git a/gdb/nat/netbsd-nat.h b/gdb/nat/netbsd-nat.h
index d77119b..594dec1 100644
--- a/gdb/nat/netbsd-nat.h
+++ b/gdb/nat/netbsd-nat.h
@@ -67,6 +67,28 @@ extern void enable_proc_events (pid_t pid);
extern int qxfer_siginfo (pid_t pid, const char *annex, unsigned char *readbuf,
unsigned const char *writebuf, CORE_ADDR offset,
int len);
+
+/* Write gdb's LEN bytes from WRITEBUF and copy it to OFFSET in inferior
+ process' address space. The inferior is specified by PID.
+ Returns 0 on success or errno on failure and the number of bytes
+ on a successful transfer in XFERED_LEN.
+
+ This function assumes internally that the queried process is stopped and
+ traced. */
+
+extern int write_memory (pid_t pid, unsigned const char *writebuf,
+ CORE_ADDR offset, size_t len, size_t *xfered_len);
+
+/* Read inferior process's LEN bytes from OFFSET and copy it to WRITEBUF in
+ gdb's address space.
+ Returns 0 on success or errno on failure and the number of bytes
+ on a successful transfer in XFERED_LEN.
+
+ This function assumes internally that the queried process is stopped and
+ traced. */
+
+extern int read_memory (pid_t pid, unsigned char *readbuf, CORE_ADDR offset,
+ size_t len, size_t *xfered_len);
}
#endif