aboutsummaryrefslogtreecommitdiff
path: root/gdb
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
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')
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/nat/netbsd-nat.c80
-rw-r--r--gdb/nat/netbsd-nat.h22
-rw-r--r--gdb/nbsd-nat.c23
4 files changed, 131 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6a69e63..4dc729c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2020-10-07 Kamil Rytarowski <n54@gmx.com>
+
+ * 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.
+
2020-10-07 Simon Marchi <simon.marchi@polymtl.ca>
* break-catch-sig.c (signal_catch_counts): Make a static arrray.
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
diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
index 7a07fbf..46dcfac 100644
--- a/gdb/nbsd-nat.c
+++ b/gdb/nbsd-nat.c
@@ -764,6 +764,29 @@ nbsd_nat_target::xfer_partial (enum target_object object,
*xfered_len = len;
return TARGET_XFER_OK;
}
+ case TARGET_OBJECT_MEMORY:
+ {
+ size_t xfered;
+ int res;
+ if (writebuf != nullptr)
+ res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered);
+ else
+ res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered);
+ if (res != 0)
+ {
+ if (res == EACCES)
+ fprintf_unfiltered (gdb_stderr, "Cannot %s process at %s (%s). "
+ "Is PaX MPROTECT active? See security(7), "
+ "sysctl(7), paxctl(8)\n",
+ (writebuf ? "write to" : "read from"),
+ pulongest (offset), safe_strerror (errno));
+ return TARGET_XFER_E_IO;
+ }
+ if (xfered == 0)
+ return TARGET_XFER_EOF;
+ *xfered_len = (ULONGEST) xfered;
+ return TARGET_XFER_OK;
+ }
default:
return inf_ptrace_target::xfer_partial (object, annex,
readbuf, writebuf, offset,