aboutsummaryrefslogtreecommitdiff
path: root/gdb/nbsd-nat.c
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2020-07-26 14:10:56 +0200
committerKamil Rytarowski <n54@gmx.com>2020-07-28 18:12:59 +0200
commit4d46f40270b16070398412bc02a512143380814c (patch)
treeac62a1f14be4cc8751cedbd445ea8c64716fcbe6 /gdb/nbsd-nat.c
parent377170fa319d39d5442b674fc978adc8f24db5e9 (diff)
downloadgdb-4d46f40270b16070398412bc02a512143380814c.zip
gdb-4d46f40270b16070398412bc02a512143380814c.tar.gz
gdb-4d46f40270b16070398412bc02a512143380814c.tar.bz2
Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD
NetBSD implements reading and overwriting siginfo_t received by the tracee. With TARGET_OBJECT_SIGNAL_INFO signal information can be examined and modified through the special variable $_siginfo. Implement the "get_siginfo_type" gdbarch method for NetBSD architectures. As with Linux architectures, cache the created type in the gdbarch when it is first created. Currently NetBSD uses an identical siginfo type on all architectures, so there is no support for architecture-specific fields. gdb/ChangeLog: * nbsd-nat.h (nbsd_nat_target::xfer_partial): New declaration. * nbsd-nat.c (nbsd_nat_target::xfer_partial): New function. * nbsd-tdep.c (nbsd_gdbarch_data_handle, struct nbsd_gdbarch_data) (init_nbsd_gdbarch_data, get_nbsd_gdbarch_data) (nbsd_get_siginfo_type): New. (nbsd_init_abi): Install gdbarch "get_siginfo_type" method. (_initialize_nbsd_tdep): New
Diffstat (limited to 'gdb/nbsd-nat.c')
-rw-r--r--gdb/nbsd-nat.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
index a9405eb..5b59f21 100644
--- a/gdb/nbsd-nat.c
+++ b/gdb/nbsd-nat.c
@@ -845,3 +845,48 @@ nbsd_nat_target::supports_multi_process ()
{
return true;
}
+
+/* Implement the "xfer_partial" target_ops method. */
+
+enum target_xfer_status
+nbsd_nat_target::xfer_partial (enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len)
+{
+ pid_t pid = inferior_ptid.pid ();
+
+ switch (object)
+ {
+ case TARGET_OBJECT_SIGNAL_INFO:
+ {
+ ptrace_siginfo_t psi;
+
+ if (offset > sizeof (siginfo_t))
+ return TARGET_XFER_E_IO;
+
+ if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
+ return TARGET_XFER_E_IO;
+
+ if (offset + len > sizeof (siginfo_t))
+ len = sizeof (siginfo_t) - offset;
+
+ if (readbuf != NULL)
+ memcpy (readbuf, ((gdb_byte *) &psi.psi_siginfo) + offset, len);
+ else
+ {
+ memcpy (((gdb_byte *) &psi.psi_siginfo) + offset, writebuf, len);
+
+ if (ptrace (PT_SET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
+ return TARGET_XFER_E_IO;
+ }
+ *xfered_len = len;
+ return TARGET_XFER_OK;
+ }
+ default:
+ return inf_ptrace_target::xfer_partial (object, annex,
+ readbuf, writebuf, offset,
+ len, xfered_len);
+ }
+}