[PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Kamil Rytarowski
NetBSD implementes 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
---
 gdb/ChangeLog   |  10 +++
 gdb/nbsd-nat.c  |  45 +++++++++++++
 gdb/nbsd-nat.h  |   6 ++
 gdb/nbsd-tdep.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 233 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0c2c6552d95..6800dfd1e56 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2020-07-26  Kamil Rytarowski  <[hidden email]>
+
+ * 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.
+
 2020-07-25  Andrew Burgess  <[hidden email]>

  PR fortran/23051
diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
index a9405ebf862..6a9bfa1a13b 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);
+    }
+}
diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h
index 0a7048ecf35..59210ad1d03 100644
--- a/gdb/nbsd-nat.h
+++ b/gdb/nbsd-nat.h
@@ -49,6 +49,12 @@ struct nbsd_nat_target : public inf_ptrace_target
     override;

   bool supports_multi_process () override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+                                        const char *annex,
+                                        gdb_byte *readbuf,
+                                        const gdb_byte *writebuf,
+                                        ULONGEST offset, ULONGEST len,
+                                        ULONGEST *xfered_len) override;
 };

 #endif /* nbsd-nat.h */
diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c
index 4fdfe476b59..faf41313f68 100644
--- a/gdb/nbsd-tdep.c
+++ b/gdb/nbsd-tdep.c
@@ -373,6 +373,169 @@ nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
     return find_solib_trampoline_target (get_current_frame (), pc);
 }

+static struct gdbarch_data *nbsd_gdbarch_data_handle;
+
+struct nbsd_gdbarch_data
+  {
+    struct type *siginfo_type;
+  };
+
+static void *
+init_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nbsd_gdbarch_data);
+}
+
+static struct nbsd_gdbarch_data *
+get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return ((struct nbsd_gdbarch_data *)
+          gdbarch_data (gdbarch, nbsd_gdbarch_data_handle));
+}
+
+/* Implement the "get_siginfo_type" gdbarch method.  */
+
+static struct type *
+nbsd_get_siginfo_type (struct gdbarch *gdbarch)
+{
+  struct nbsd_gdbarch_data *nbsd_gdbarch_data;
+  struct type *char_type, *int_type, *long_type;
+  struct type *void_ptr_type;
+  struct type *int32_type, *uint32_type, *uint64_type;
+  struct type *pid_type, *lwpid_type, *uid_type, *clock_type;
+  struct type *sigval_type, *option_type;
+  struct type *siginfo_type;
+  struct type *ksiginfo_type;
+  struct type *reason_type;
+  struct type *type;
+  bool lp64;
+
+  nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
+  if (nbsd_gdbarch_data->siginfo_type != NULL)
+    return nbsd_gdbarch_data->siginfo_type;
+
+  char_type = builtin_type (gdbarch)->builtin_char;
+  int_type = builtin_type (gdbarch)->builtin_int;
+  long_type = builtin_type (gdbarch)->builtin_long;
+
+  void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
+
+  int32_type = builtin_type (gdbarch)->builtin_int32;
+  uint32_type = builtin_type (gdbarch)->builtin_uint32;
+  uint64_type = builtin_type (gdbarch)->builtin_uint64;
+
+  lp64 = TYPE_LENGTH (void_ptr_type) == 8;
+
+  /* pid_t */
+  pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT, "pid_t");
+  TYPE_TARGET_TYPE (pid_type) = int32_type;
+  TYPE_TARGET_STUB (pid_type) = 1;
+
+  /* uid_t */
+  uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (uint32_type) * TARGET_CHAR_BIT,
+ "uid_t");
+  TYPE_TARGET_TYPE (uid_type) = uint32_type;
+  TYPE_TARGET_STUB (uid_type) = 1;
+
+  /* clock_t */
+  clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+  TYPE_LENGTH (int_type) * TARGET_CHAR_BIT,
+  "clock_t");
+  TYPE_TARGET_TYPE (clock_type) = int_type;
+  TYPE_TARGET_STUB (clock_type) = 1;
+
+  /* lwpid_t */
+  lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+  TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT,
+  "lwpid_t");
+  TYPE_TARGET_TYPE (lwpid_type) = int32_type;
+  TYPE_TARGET_STUB (lwpid_type) = 1;
+
+  /* union sigval */
+  sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  sigval_type->set_name (xstrdup ("sigval"));
+  append_composite_type_field (sigval_type, "sival_int", int_type);
+  append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
+
+  /* union _option */
+  option_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  option_type->set_name (xstrdup ("_option"));
+  append_composite_type_field (option_type, "_pe_other_pid", pid_type);
+  append_composite_type_field (option_type, "_pe_lwp", lwpid_type);
+
+  /* union _reason */
+  reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+
+  /* _rt */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "_pid", pid_type);
+  append_composite_type_field (type, "_uid", uid_type);
+  append_composite_type_field (type, "_value", sigval_type);
+  append_composite_type_field (reason_type, "_rt", type);
+
+  /* _child */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "_pid", pid_type);
+  append_composite_type_field (type, "_uid", uid_type);
+  append_composite_type_field (type, "_status", int_type);
+  append_composite_type_field (type, "_utime", clock_type);
+  append_composite_type_field (type, "_stime", clock_type);
+  append_composite_type_field (reason_type, "_child", type);
+
+  /* _fault */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "_addr", void_ptr_type);
+  append_composite_type_field (type, "_trap", int_type);
+  append_composite_type_field (type, "_trap2", int_type);
+  append_composite_type_field (type, "_trap3", int_type);
+  append_composite_type_field (reason_type, "_fault", type);
+
+  /* _poll */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "_band", long_type);
+  append_composite_type_field (type, "_fd", int_type);
+  append_composite_type_field (reason_type, "_poll", type);
+
+  /* _syscall */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "_sysnum", int_type);
+  append_composite_type_field (type, "_retval",
+       init_vector_type (int_type, 2));
+  append_composite_type_field (type, "_error", int_type);
+  append_composite_type_field (type, "_args",
+       init_vector_type (uint64_type, 8));
+  append_composite_type_field (reason_type, "_syscall", type);
+
+  /* _ptrace_state */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "_pe_report_event", int_type);
+  append_composite_type_field (type, "_option", option_type);
+  append_composite_type_field (reason_type, "_ptrace_state", type);
+
+  /* struct _ksiginfo */
+  ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  ksiginfo_type->set_name (xstrdup ("_ksiginfo"));
+  append_composite_type_field (ksiginfo_type, "_signo", int_type);
+  append_composite_type_field (ksiginfo_type, "_code", int_type);
+  append_composite_type_field (ksiginfo_type, "_errno", int_type);
+  if (lp64)
+    append_composite_type_field (ksiginfo_type, "_pad", int_type);
+  append_composite_type_field (ksiginfo_type, "_reason", reason_type);
+
+  /* union siginfo */
+  siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  siginfo_type->set_name (xstrdup ("siginfo"));
+  append_composite_type_field (siginfo_type, "si_pad",
+       init_vector_type (char_type, 128));
+  append_composite_type_field (siginfo_type, "_info", ksiginfo_type);
+
+  nbsd_gdbarch_data->siginfo_type = siginfo_type;
+
+  return siginfo_type;
+}
+
 /* See nbsd-tdep.h.  */

 void
@@ -469,8 +632,17 @@ nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
   set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
   set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
+  set_gdbarch_get_siginfo_type (gdbarch, nbsd_get_siginfo_type);

   /* `catch syscall' */
   set_xml_syscall_file_name (gdbarch, "syscalls/netbsd.xml");
   set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number);
 }
+
+void _initialize_nbsd_tdep ();
+void
+_initialize_nbsd_tdep ()
+{
+  nbsd_gdbarch_data_handle =
+    gdbarch_data_register_post_init (init_nbsd_gdbarch_data);
+}
--
2.26.2

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

John Baldwin
On 7/27/20 12:41 AM, Kamil Rytarowski wrote:
> NetBSD implementes 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.

Generally looks ok to me.

> +  /* struct _ksiginfo */
> +  ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
> +  ksiginfo_type->set_name (xstrdup ("_ksiginfo"));
> +  append_composite_type_field (ksiginfo_type, "_signo", int_type);
> +  append_composite_type_field (ksiginfo_type, "_code", int_type);
> +  append_composite_type_field (ksiginfo_type, "_errno", int_type);
> +  if (lp64)
> +    append_composite_type_field (ksiginfo_type, "_pad", int_type);
> +  append_composite_type_field (ksiginfo_type, "_reason", reason_type);

I was going to suggest using append_composite_type_field_aligned for
the "_reason" member, but I see in the source that _pad is explicitly
declared under #ifdef _LP64, so I think your approach here is correct
in that I think this function should strive to match the source code
declaration for siginfo_t.

--
John Baldwin
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Simon Marchi-4
In reply to this post by Kamil Rytarowski
A few comments, the patch LGTM with these fixed.

On 2020-07-27 3:41 a.m., Kamil Rytarowski wrote:
> NetBSD implementes reading and overwriting siginfo_t received by the

"implementes"

> 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.

Watch out tabs vs spaces at a few places in the patch.

> +{
> +  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;

Space after all instances of `sizeof`.

> +    }
> +}
> diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h
> index 0a7048ecf35..59210ad1d03 100644
> --- a/gdb/nbsd-nat.h
> +++ b/gdb/nbsd-nat.h
> @@ -49,6 +49,12 @@ struct nbsd_nat_target : public inf_ptrace_target
>      override;
>
>    bool supports_multi_process () override;
> +  enum target_xfer_status xfer_partial (enum target_object object,
> +                                        const char *annex,
> +                                        gdb_byte *readbuf,
> +                                        const gdb_byte *writebuf,
> +                                        ULONGEST offset, ULONGEST len,
> +                                        ULONGEST *xfered_len) override;
>  };
>
>  #endif /* nbsd-nat.h */
> diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c
> index 4fdfe476b59..faf41313f68 100644
> --- a/gdb/nbsd-tdep.c
> +++ b/gdb/nbsd-tdep.c
> @@ -373,6 +373,169 @@ nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
>      return find_solib_trampoline_target (get_current_frame (), pc);
>  }
>
> +static struct gdbarch_data *nbsd_gdbarch_data_handle;
> +
> +struct nbsd_gdbarch_data
> +  {
> +    struct type *siginfo_type;
> +  };

Remove leading indentation (`{` and `}` on column 0).

> +
> +static void *
> +init_nbsd_gdbarch_data (struct gdbarch *gdbarch)
> +{
> +  return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nbsd_gdbarch_data);
> +}
> +
> +static struct nbsd_gdbarch_data *
> +get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
> +{
> +  return ((struct nbsd_gdbarch_data *)
> +          gdbarch_data (gdbarch, nbsd_gdbarch_data_handle));
> +}
> +
> +/* Implement the "get_siginfo_type" gdbarch method.  */
> +
> +static struct type *
> +nbsd_get_siginfo_type (struct gdbarch *gdbarch)
> +{
> +  struct nbsd_gdbarch_data *nbsd_gdbarch_data;
> +  struct type *char_type, *int_type, *long_type;
> +  struct type *void_ptr_type;
> +  struct type *int32_type, *uint32_type, *uint64_type;
> +  struct type *pid_type, *lwpid_type, *uid_type, *clock_type;
> +  struct type *sigval_type, *option_type;
> +  struct type *siginfo_type;
> +  struct type *ksiginfo_type;
> +  struct type *reason_type;
> +  struct type *type;
> +  bool lp64;

Feel free to declare the variables when first using them and skip the `struct` keyword.

> +
> +  nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
> +  if (nbsd_gdbarch_data->siginfo_type != NULL)
> +    return nbsd_gdbarch_data->siginfo_type;
> +
> +  char_type = builtin_type (gdbarch)->builtin_char;
> +  int_type = builtin_type (gdbarch)->builtin_int;
> +  long_type = builtin_type (gdbarch)->builtin_long;
> +
> +  void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
> +
> +  int32_type = builtin_type (gdbarch)->builtin_int32;
> +  uint32_type = builtin_type (gdbarch)->builtin_uint32;
> +  uint64_type = builtin_type (gdbarch)->builtin_uint64;
> +
> +  lp64 = TYPE_LENGTH (void_ptr_type) == 8;
> +
> +  /* pid_t */
> +  pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
> + TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT, "pid_t");

TARGET_CHAR_BIT is bogus, since GDB can have multiple targets with possibly different
target char sizes.  It should really be removed.

Use gdbarch_addressable_memory_unit_size, and multiply that value by 8 to get
the target char size in bits.

> +  TYPE_TARGET_TYPE (pid_type) = int32_type;
> +  TYPE_TARGET_STUB (pid_type) = 1;

Is STUB really needed here?  The TYPE_TARGET_STUB comment says it only applies to
arrays and ranges.

> +
> +  /* uid_t */
> +  uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
> + TYPE_LENGTH (uint32_type) * TARGET_CHAR_BIT,
> + "uid_t");
> +  TYPE_TARGET_TYPE (uid_type) = uint32_type;
> +  TYPE_TARGET_STUB (uid_type) = 1;
> +
> +  /* clock_t */
> +  clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
> +  TYPE_LENGTH (int_type) * TARGET_CHAR_BIT,
> +  "clock_t");
> +  TYPE_TARGET_TYPE (clock_type) = int_type;
> +  TYPE_TARGET_STUB (clock_type) = 1;
> +
> +  /* lwpid_t */
> +  lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
> +  TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT,
> +  "lwpid_t");
> +  TYPE_TARGET_TYPE (lwpid_type) = int32_type;
> +  TYPE_TARGET_STUB (lwpid_type) = 1;
> +
> +  /* union sigval */
> +  sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
> +  sigval_type->set_name (xstrdup ("sigval"));

If these types are tied to the gdbarch, maybe allocate it on the gdbarch's
obstack, just like the type is?  You would use gdbarch_obstack_strdup.

You could also pass the name directly to arch_composite_type.  You would
still need to strdup it.  Oddly enough, arch_type strdups its `name` argument,
but arch_composite_type does not.

> +
> +void _initialize_nbsd_tdep ();
> +void
> +_initialize_nbsd_tdep ()
> +{
> +  nbsd_gdbarch_data_handle =
> +    gdbarch_data_register_post_init (init_nbsd_gdbarch_data);

Assignment operator on the next line:

  nbsd_gdbarch_data_handle
    = ...

Simon
Reply | Threaded
Open this post in threaded view
|

[PATCH v2] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Kamil Rytarowski
In reply to this post by Kamil Rytarowski
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
---
 gdb/ChangeLog   |  10 ++++
 gdb/nbsd-nat.c  |  45 ++++++++++++++
 gdb/nbsd-nat.h  |   6 ++
 gdb/nbsd-tdep.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 217 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index defca83c263..c12eda04285 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2020-07-28  Kamil Rytarowski  <[hidden email]>
+
+ * 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.
+
 2020-07-28  H.J. Lu  <[hidden email]>

  PR binutils/26301
diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
index a9405ebf862..bdf3388de0b 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);
+    }
+}
diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h
index 0a7048ecf35..59210ad1d03 100644
--- a/gdb/nbsd-nat.h
+++ b/gdb/nbsd-nat.h
@@ -49,6 +49,12 @@ struct nbsd_nat_target : public inf_ptrace_target
     override;

   bool supports_multi_process () override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+                                        const char *annex,
+                                        gdb_byte *readbuf,
+                                        const gdb_byte *writebuf,
+                                        ULONGEST offset, ULONGEST len,
+                                        ULONGEST *xfered_len) override;
 };

 #endif /* nbsd-nat.h */
diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c
index 4fdfe476b59..ecbcbcfe163 100644
--- a/gdb/nbsd-tdep.c
+++ b/gdb/nbsd-tdep.c
@@ -373,6 +373,153 @@ nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
     return find_solib_trampoline_target (get_current_frame (), pc);
 }

+static struct gdbarch_data *nbsd_gdbarch_data_handle;
+
+struct nbsd_gdbarch_data
+{
+  struct type *siginfo_type;
+};
+
+static void *
+init_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nbsd_gdbarch_data);
+}
+
+static struct nbsd_gdbarch_data *
+get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return ((struct nbsd_gdbarch_data *)
+          gdbarch_data (gdbarch, nbsd_gdbarch_data_handle));
+}
+
+/* Implement the "get_siginfo_type" gdbarch method.  */
+
+static struct type *
+nbsd_get_siginfo_type (struct gdbarch *gdbarch)
+{
+  nbsd_gdbarch_data *nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
+  if (nbsd_gdbarch_data->siginfo_type != NULL)
+    return nbsd_gdbarch_data->siginfo_type;
+
+  type *char_type = builtin_type (gdbarch)->builtin_char;
+  type *int_type = builtin_type (gdbarch)->builtin_int;
+  type *long_type = builtin_type (gdbarch)->builtin_long;
+
+  type *void_ptr_type
+    = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
+
+  type *int32_type = builtin_type (gdbarch)->builtin_int32;
+  type *uint32_type = builtin_type (gdbarch)->builtin_uint32;
+  type *uint64_type = builtin_type (gdbarch)->builtin_uint64;
+
+  bool lp64 = TYPE_LENGTH (void_ptr_type) == 8;
+  size_t char_bits = gdbarch_addressable_memory_unit_size (gdbarch) * 8;
+
+  /* pid_t */
+  type *pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+      TYPE_LENGTH (int32_type) * char_bits, "pid_t");
+  TYPE_TARGET_TYPE (pid_type) = int32_type;
+
+  /* uid_t */
+  type *uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+      TYPE_LENGTH (uint32_type) * char_bits, "uid_t");
+  TYPE_TARGET_TYPE (uid_type) = uint32_type;
+
+  /* clock_t */
+  type *clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int_type) * char_bits, "clock_t");
+  TYPE_TARGET_TYPE (clock_type) = int_type;
+
+  /* lwpid_t */
+  type *lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int32_type) * char_bits,
+ "lwpid_t");
+  TYPE_TARGET_TYPE (lwpid_type) = int32_type;
+
+  /* union sigval */
+  type *sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  sigval_type->set_name (gdbarch_obstack_strdup (gdbarch, "sigval"));
+  append_composite_type_field (sigval_type, "sival_int", int_type);
+  append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
+
+  /* union _option */
+  type *option_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  option_type->set_name (gdbarch_obstack_strdup (gdbarch, "_option"));
+  append_composite_type_field (option_type, "_pe_other_pid", pid_type);
+  append_composite_type_field (option_type, "_pe_lwp", lwpid_type);
+
+  /* union _reason */
+  type *reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+
+  /* _rt */
+  type *t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_pid", pid_type);
+  append_composite_type_field (t, "_uid", uid_type);
+  append_composite_type_field (t, "_value", sigval_type);
+  append_composite_type_field (reason_type, "_rt", t);
+
+  /* _child */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_pid", pid_type);
+  append_composite_type_field (t, "_uid", uid_type);
+  append_composite_type_field (t, "_status", int_type);
+  append_composite_type_field (t, "_utime", clock_type);
+  append_composite_type_field (t, "_stime", clock_type);
+  append_composite_type_field (reason_type, "_child", t);
+
+  /* _fault */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_addr", void_ptr_type);
+  append_composite_type_field (t, "_trap", int_type);
+  append_composite_type_field (t, "_trap2", int_type);
+  append_composite_type_field (t, "_trap3", int_type);
+  append_composite_type_field (reason_type, "_fault", t);
+
+  /* _poll */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_band", long_type);
+  append_composite_type_field (t, "_fd", int_type);
+  append_composite_type_field (reason_type, "_poll", t);
+
+  /* _syscall */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_sysnum", int_type);
+  append_composite_type_field (t, "_retval",
+       init_vector_type (int_type, 2));
+  append_composite_type_field (t, "_error", int_type);
+  append_composite_type_field (t, "_args",
+       init_vector_type (uint64_type, 8));
+  append_composite_type_field (reason_type, "_syscall", t);
+
+  /* _ptrace_state */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_pe_report_event", int_type);
+  append_composite_type_field (t, "_option", option_type);
+  append_composite_type_field (reason_type, "_ptrace_state", t);
+
+  /* struct _ksiginfo */
+  type *ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  ksiginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "_ksiginfo"));
+  append_composite_type_field (ksiginfo_type, "_signo", int_type);
+  append_composite_type_field (ksiginfo_type, "_code", int_type);
+  append_composite_type_field (ksiginfo_type, "_errno", int_type);
+  if (lp64)
+    append_composite_type_field (ksiginfo_type, "_pad", int_type);
+  append_composite_type_field (ksiginfo_type, "_reason", reason_type);
+
+  /* union siginfo */
+  type *siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  siginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "siginfo"));
+  append_composite_type_field (siginfo_type, "si_pad",
+       init_vector_type (char_type, 128));
+  append_composite_type_field (siginfo_type, "_info", ksiginfo_type);
+
+  nbsd_gdbarch_data->siginfo_type = siginfo_type;
+
+  return siginfo_type;
+}
+
 /* See nbsd-tdep.h.  */

 void
@@ -469,8 +616,17 @@ nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
   set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
   set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
+  set_gdbarch_get_siginfo_type (gdbarch, nbsd_get_siginfo_type);

   /* `catch syscall' */
   set_xml_syscall_file_name (gdbarch, "syscalls/netbsd.xml");
   set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number);
 }
+
+void _initialize_nbsd_tdep ();
+void
+_initialize_nbsd_tdep ()
+{
+  nbsd_gdbarch_data_handle
+    = gdbarch_data_register_post_init (init_nbsd_gdbarch_data);
+}
--
2.26.2

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Kamil Rytarowski-2
In reply to this post by Simon Marchi-4
On 28.07.2020 15:26, Simon Marchi wrote:
> A few comments, the patch LGTM with these fixed.
>
> On 2020-07-27 3:41 a.m., Kamil Rytarowski wrote:
>> NetBSD implementes reading and overwriting siginfo_t received by the
>
> "implementes"
>

Done.

>> 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.
>
> Watch out tabs vs spaces at a few places in the patch.
>
Please specify exact lines if there is still anything left.

>> +{
>> +  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;
>
> Space after all instances of `sizeof`.
>
Done.

>> +    }
>> +}
>> diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h
>> index 0a7048ecf35..59210ad1d03 100644
>> --- a/gdb/nbsd-nat.h
>> +++ b/gdb/nbsd-nat.h
>> @@ -49,6 +49,12 @@ struct nbsd_nat_target : public inf_ptrace_target
>>      override;
>>
>>    bool supports_multi_process () override;
>> +  enum target_xfer_status xfer_partial (enum target_object object,
>> +                                        const char *annex,
>> +                                        gdb_byte *readbuf,
>> +                                        const gdb_byte *writebuf,
>> +                                        ULONGEST offset, ULONGEST len,
>> +                                        ULONGEST *xfered_len) override;
>>  };
>>
>>  #endif /* nbsd-nat.h */
>> diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c
>> index 4fdfe476b59..faf41313f68 100644
>> --- a/gdb/nbsd-tdep.c
>> +++ b/gdb/nbsd-tdep.c
>> @@ -373,6 +373,169 @@ nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
>>      return find_solib_trampoline_target (get_current_frame (), pc);
>>  }
>>
>> +static struct gdbarch_data *nbsd_gdbarch_data_handle;
>> +
>> +struct nbsd_gdbarch_data
>> +  {
>> +    struct type *siginfo_type;
>> +  };
>
> Remove leading indentation (`{` and `}` on column 0).
>
Done.

>> +
>> +static void *
>> +init_nbsd_gdbarch_data (struct gdbarch *gdbarch)
>> +{
>> +  return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nbsd_gdbarch_data);
>> +}
>> +
>> +static struct nbsd_gdbarch_data *
>> +get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
>> +{
>> +  return ((struct nbsd_gdbarch_data *)
>> +          gdbarch_data (gdbarch, nbsd_gdbarch_data_handle));
>> +}
>> +
>> +/* Implement the "get_siginfo_type" gdbarch method.  */
>> +
>> +static struct type *
>> +nbsd_get_siginfo_type (struct gdbarch *gdbarch)
>> +{
>> +  struct nbsd_gdbarch_data *nbsd_gdbarch_data;
>> +  struct type *char_type, *int_type, *long_type;
>> +  struct type *void_ptr_type;
>> +  struct type *int32_type, *uint32_type, *uint64_type;
>> +  struct type *pid_type, *lwpid_type, *uid_type, *clock_type;
>> +  struct type *sigval_type, *option_type;
>> +  struct type *siginfo_type;
>> +  struct type *ksiginfo_type;
>> +  struct type *reason_type;
>> +  struct type *type;
>> +  bool lp64;
>
> Feel free to declare the variables when first using them and skip the `struct` keyword.
>
Done.

>> +
>> +  nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
>> +  if (nbsd_gdbarch_data->siginfo_type != NULL)
>> +    return nbsd_gdbarch_data->siginfo_type;
>> +
>> +  char_type = builtin_type (gdbarch)->builtin_char;
>> +  int_type = builtin_type (gdbarch)->builtin_int;
>> +  long_type = builtin_type (gdbarch)->builtin_long;
>> +
>> +  void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
>> +
>> +  int32_type = builtin_type (gdbarch)->builtin_int32;
>> +  uint32_type = builtin_type (gdbarch)->builtin_uint32;
>> +  uint64_type = builtin_type (gdbarch)->builtin_uint64;
>> +
>> +  lp64 = TYPE_LENGTH (void_ptr_type) == 8;
>> +
>> +  /* pid_t */
>> +  pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
>> + TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT, "pid_t");
>
> TARGET_CHAR_BIT is bogus, since GDB can have multiple targets with possibly different
> target char sizes.  It should really be removed.
>
> Use gdbarch_addressable_memory_unit_size, and multiply that value by 8 to get
> the target char size in bits.
>
Done.

>> +  TYPE_TARGET_TYPE (pid_type) = int32_type;
>> +  TYPE_TARGET_STUB (pid_type) = 1;
>
> Is STUB really needed here?  The TYPE_TARGET_STUB comment says it only applies to
> arrays and ranges.
>

Done.

>> +
>> +  /* uid_t */
>> +  uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
>> + TYPE_LENGTH (uint32_type) * TARGET_CHAR_BIT,
>> + "uid_t");
>> +  TYPE_TARGET_TYPE (uid_type) = uint32_type;
>> +  TYPE_TARGET_STUB (uid_type) = 1;
>> +
>> +  /* clock_t */
>> +  clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
>> +  TYPE_LENGTH (int_type) * TARGET_CHAR_BIT,
>> +  "clock_t");
>> +  TYPE_TARGET_TYPE (clock_type) = int_type;
>> +  TYPE_TARGET_STUB (clock_type) = 1;
>> +
>> +  /* lwpid_t */
>> +  lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
>> +  TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT,
>> +  "lwpid_t");
>> +  TYPE_TARGET_TYPE (lwpid_type) = int32_type;
>> +  TYPE_TARGET_STUB (lwpid_type) = 1;
>> +
>> +  /* union sigval */
>> +  sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
>> +  sigval_type->set_name (xstrdup ("sigval"));
>
> If these types are tied to the gdbarch, maybe allocate it on the gdbarch's
> obstack, just like the type is?  You would use gdbarch_obstack_strdup.
>
> You could also pass the name directly to arch_composite_type.  You would
> still need to strdup it.  Oddly enough, arch_type strdups its `name` argument,
> but arch_composite_type does not.
>
This looks like a generic GDB bug wiith this arch_composite_type vs
arch_type. For now, I have used set_name + gdbarch_obstack_strdup.

Feel free to fix the problem in GDB later and pass the name directly in
arch_composite_type.

>> +
>> +void _initialize_nbsd_tdep ();
>> +void
>> +_initialize_nbsd_tdep ()
>> +{
>> +  nbsd_gdbarch_data_handle =
>> +    gdbarch_data_register_post_init (init_nbsd_gdbarch_data);
>
> Assignment operator on the next line:
>
>   nbsd_gdbarch_data_handle
>     = ...
>
Done.

> Simon
>



signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Simon Marchi-4
On 2020-07-28 11:07 a.m., Kamil Rytarowski wrote:
> This looks like a generic GDB bug wiith this arch_composite_type vs
> arch_type. For now, I have used set_name + gdbarch_obstack_strdup.
>
> Feel free to fix the problem in GDB later and pass the name directly in
> arch_composite_type.

I mean, you could easily use for now:

  arch_composite_type (..., gdbarch_obstack_strdup (name), ...);

Simon
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Simon Marchi-4
In reply to this post by Kamil Rytarowski
On 2020-07-28 11:04 a.m., Kamil Rytarowski wrote:

> diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
> index a9405ebf862..bdf3388de0b 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)

Spaces here.

Just search for "        " (8 spaces) in the files, it's quite easy to find.

If there are pre-existing offenders, you can push obvious fixes to fix them.

Simon
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Kamil Rytarowski-2
In reply to this post by Simon Marchi-4
On 28.07.2020 17:15, Simon Marchi wrote:

> On 2020-07-28 11:07 a.m., Kamil Rytarowski wrote:
>> This looks like a generic GDB bug wiith this arch_composite_type vs
>> arch_type. For now, I have used set_name + gdbarch_obstack_strdup.
>>
>> Feel free to fix the problem in GDB later and pass the name directly in
>> arch_composite_type.
>
> I mean, you could easily use for now:
>
>   arch_composite_type (..., gdbarch_obstack_strdup (name), ...);
>
> Simon
>
I know, I decided to go for set_name as it will be more agnostic to
further possible arch_composite_type() changes.

On 28.07.2020 17:17, Simon Marchi wrote:

> On 2020-07-28 11:04 a.m., Kamil Rytarowski wrote:
>> diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
>> index a9405ebf862..bdf3388de0b 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)
> Spaces here.

I'm going to fix this.

Is this patch good otherwise?


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Simon Marchi-4
On 2020-07-28 11:17 a.m., Kamil Rytarowski wrote:
> Is this patch good otherwise?

The v2 is good, assuming all whitespace issues are fixed.

Simon
Reply | Threaded
Open this post in threaded view
|

[PATCH v3] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Kamil Rytarowski
In reply to this post by Kamil Rytarowski
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
---
 gdb/ChangeLog   |  10 ++++
 gdb/nbsd-nat.c  |  45 ++++++++++++++
 gdb/nbsd-nat.h  |   6 ++
 gdb/nbsd-tdep.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 217 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index defca83c263..c12eda04285 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2020-07-28  Kamil Rytarowski  <[hidden email]>
+
+ * 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.
+
 2020-07-28  H.J. Lu  <[hidden email]>

  PR binutils/26301
diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
index a9405ebf862..5b59f2130d7 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);
+    }
+}
diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h
index 0a7048ecf35..665a71a0f78 100644
--- a/gdb/nbsd-nat.h
+++ b/gdb/nbsd-nat.h
@@ -49,6 +49,12 @@ struct nbsd_nat_target : public inf_ptrace_target
     override;

   bool supports_multi_process () override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+ const char *annex,
+ gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len) override;
 };

 #endif /* nbsd-nat.h */
diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c
index 4fdfe476b59..2db994af218 100644
--- a/gdb/nbsd-tdep.c
+++ b/gdb/nbsd-tdep.c
@@ -373,6 +373,153 @@ nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
     return find_solib_trampoline_target (get_current_frame (), pc);
 }

+static struct gdbarch_data *nbsd_gdbarch_data_handle;
+
+struct nbsd_gdbarch_data
+{
+  struct type *siginfo_type;
+};
+
+static void *
+init_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nbsd_gdbarch_data);
+}
+
+static struct nbsd_gdbarch_data *
+get_nbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return ((struct nbsd_gdbarch_data *)
+  gdbarch_data (gdbarch, nbsd_gdbarch_data_handle));
+}
+
+/* Implement the "get_siginfo_type" gdbarch method.  */
+
+static struct type *
+nbsd_get_siginfo_type (struct gdbarch *gdbarch)
+{
+  nbsd_gdbarch_data *nbsd_gdbarch_data = get_nbsd_gdbarch_data (gdbarch);
+  if (nbsd_gdbarch_data->siginfo_type != NULL)
+    return nbsd_gdbarch_data->siginfo_type;
+
+  type *char_type = builtin_type (gdbarch)->builtin_char;
+  type *int_type = builtin_type (gdbarch)->builtin_int;
+  type *long_type = builtin_type (gdbarch)->builtin_long;
+
+  type *void_ptr_type
+    = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
+
+  type *int32_type = builtin_type (gdbarch)->builtin_int32;
+  type *uint32_type = builtin_type (gdbarch)->builtin_uint32;
+  type *uint64_type = builtin_type (gdbarch)->builtin_uint64;
+
+  bool lp64 = TYPE_LENGTH (void_ptr_type) == 8;
+  size_t char_bits = gdbarch_addressable_memory_unit_size (gdbarch) * 8;
+
+  /* pid_t */
+  type *pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+      TYPE_LENGTH (int32_type) * char_bits, "pid_t");
+  TYPE_TARGET_TYPE (pid_type) = int32_type;
+
+  /* uid_t */
+  type *uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+      TYPE_LENGTH (uint32_type) * char_bits, "uid_t");
+  TYPE_TARGET_TYPE (uid_type) = uint32_type;
+
+  /* clock_t */
+  type *clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int_type) * char_bits, "clock_t");
+  TYPE_TARGET_TYPE (clock_type) = int_type;
+
+  /* lwpid_t */
+  type *lwpid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+ TYPE_LENGTH (int32_type) * char_bits,
+ "lwpid_t");
+  TYPE_TARGET_TYPE (lwpid_type) = int32_type;
+
+  /* union sigval */
+  type *sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  sigval_type->set_name (gdbarch_obstack_strdup (gdbarch, "sigval"));
+  append_composite_type_field (sigval_type, "sival_int", int_type);
+  append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
+
+  /* union _option */
+  type *option_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  option_type->set_name (gdbarch_obstack_strdup (gdbarch, "_option"));
+  append_composite_type_field (option_type, "_pe_other_pid", pid_type);
+  append_composite_type_field (option_type, "_pe_lwp", lwpid_type);
+
+  /* union _reason */
+  type *reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+
+  /* _rt */
+  type *t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_pid", pid_type);
+  append_composite_type_field (t, "_uid", uid_type);
+  append_composite_type_field (t, "_value", sigval_type);
+  append_composite_type_field (reason_type, "_rt", t);
+
+  /* _child */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_pid", pid_type);
+  append_composite_type_field (t, "_uid", uid_type);
+  append_composite_type_field (t, "_status", int_type);
+  append_composite_type_field (t, "_utime", clock_type);
+  append_composite_type_field (t, "_stime", clock_type);
+  append_composite_type_field (reason_type, "_child", t);
+
+  /* _fault */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_addr", void_ptr_type);
+  append_composite_type_field (t, "_trap", int_type);
+  append_composite_type_field (t, "_trap2", int_type);
+  append_composite_type_field (t, "_trap3", int_type);
+  append_composite_type_field (reason_type, "_fault", t);
+
+  /* _poll */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_band", long_type);
+  append_composite_type_field (t, "_fd", int_type);
+  append_composite_type_field (reason_type, "_poll", t);
+
+  /* _syscall */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_sysnum", int_type);
+  append_composite_type_field (t, "_retval",
+       init_vector_type (int_type, 2));
+  append_composite_type_field (t, "_error", int_type);
+  append_composite_type_field (t, "_args",
+       init_vector_type (uint64_type, 8));
+  append_composite_type_field (reason_type, "_syscall", t);
+
+  /* _ptrace_state */
+  t = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (t, "_pe_report_event", int_type);
+  append_composite_type_field (t, "_option", option_type);
+  append_composite_type_field (reason_type, "_ptrace_state", t);
+
+  /* struct _ksiginfo */
+  type *ksiginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  ksiginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "_ksiginfo"));
+  append_composite_type_field (ksiginfo_type, "_signo", int_type);
+  append_composite_type_field (ksiginfo_type, "_code", int_type);
+  append_composite_type_field (ksiginfo_type, "_errno", int_type);
+  if (lp64)
+    append_composite_type_field (ksiginfo_type, "_pad", int_type);
+  append_composite_type_field (ksiginfo_type, "_reason", reason_type);
+
+  /* union siginfo */
+  type *siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  siginfo_type->set_name (gdbarch_obstack_strdup (gdbarch, "siginfo"));
+  append_composite_type_field (siginfo_type, "si_pad",
+       init_vector_type (char_type, 128));
+  append_composite_type_field (siginfo_type, "_info", ksiginfo_type);
+
+  nbsd_gdbarch_data->siginfo_type = siginfo_type;
+
+  return siginfo_type;
+}
+
 /* See nbsd-tdep.h.  */

 void
@@ -469,8 +616,17 @@ nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
   set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
   set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
+  set_gdbarch_get_siginfo_type (gdbarch, nbsd_get_siginfo_type);

   /* `catch syscall' */
   set_xml_syscall_file_name (gdbarch, "syscalls/netbsd.xml");
   set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number);
 }
+
+void _initialize_nbsd_tdep ();
+void
+_initialize_nbsd_tdep ()
+{
+  nbsd_gdbarch_data_handle
+    = gdbarch_data_register_post_init (init_nbsd_gdbarch_data);
+}
--
2.26.2

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v3] Implement xfer_partial TARGET_OBJECT_SIGNAL_INFO for NetBSD

Simon Marchi-4
On 2020-07-28 11:58 a.m., Kamil Rytarowski wrote:

> 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
> ---

Thanks, this is OK.

Simon