Add new dt(4) ioctl DTIOCGARGS to get the types of probe arguments.
authorbluhm <bluhm@openbsd.org>
Fri, 10 Mar 2023 22:14:32 +0000 (22:14 +0000)
committerbluhm <bluhm@openbsd.org>
Fri, 10 Mar 2023 22:14:32 +0000 (22:14 +0000)
They are already tracked as strings in the kernel.  Export them to
userland using one ioctl(2) for all arguments of each probe.
OK mpi@

sys/dev/dt/dt_dev.c
sys/dev/dt/dtvar.h

index 107e972..4f84e5d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dt_dev.c,v 1.24 2023/03/10 11:04:26 claudio Exp $ */
+/*     $OpenBSD: dt_dev.c,v 1.25 2023/03/10 22:14:32 bluhm Exp $ */
 
 /*
  * Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@@ -129,6 +129,7 @@ int dtioctl(dev_t, u_long, caddr_t, int, struct proc *);
 struct dt_softc *dtlookup(int);
 
 int    dt_ioctl_list_probes(struct dt_softc *, struct dtioc_probe *);
+int    dt_ioctl_get_args(struct dt_softc *, struct dtioc_arg *);
 int    dt_ioctl_get_stats(struct dt_softc *, struct dtioc_stat *);
 int    dt_ioctl_record_start(struct dt_softc *);
 void   dt_ioctl_record_stop(struct dt_softc *);
@@ -281,6 +282,8 @@ dtioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
        switch (cmd) {
        case DTIOCGPLIST:
                return dt_ioctl_list_probes(sc, (struct dtioc_probe *)addr);
+       case DTIOCGARGS:
+               return dt_ioctl_get_args(sc, (struct dtioc_arg *)addr);
        case DTIOCGSTATS:
                return dt_ioctl_get_stats(sc, (struct dtioc_stat *)addr);
        case DTIOCRECORD:
@@ -369,12 +372,12 @@ dt_ioctl_list_probes(struct dt_softc *sc, struct dtioc_probe *dtpr)
                return 0;
 
        dtpi = dtpr->dtpr_probes;
-       memset(&info, 0, sizeof(info));
        SIMPLEQ_FOREACH(dtp, &dt_probe_list, dtp_next) {
                if (size < sizeof(*dtpi)) {
                        error = ENOSPC;
                        break;
                }
+               memset(&info, 0, sizeof(info));
                info.dtpi_pbn = dtp->dtp_pbn;
                info.dtpi_nargs = dtp->dtp_nargs;
                strlcpy(info.dtpi_prov, dtp->dtp_prov->dtpv_name,
@@ -386,7 +389,63 @@ dt_ioctl_list_probes(struct dt_softc *sc, struct dtioc_probe *dtpr)
                        break;
                size -= sizeof(*dtpi);
                dtpi++;
-       };
+       }
+
+       return error;
+}
+
+int
+dt_ioctl_get_args(struct dt_softc *sc, struct dtioc_arg *dtar)
+{
+       struct dtioc_arg_info info, *dtai;
+       struct dt_probe *dtp;
+       size_t size, n, t;
+       uint32_t pbn;
+       int error = 0;
+
+       pbn = dtar->dtar_pbn;
+       if (pbn == 0 || pbn > dt_nprobes)
+               return EINVAL;
+
+       SIMPLEQ_FOREACH(dtp, &dt_probe_list, dtp_next) {
+               if (pbn == dtp->dtp_pbn)
+                       break;
+       }
+       if (dtp == NULL)
+               return EINVAL;
+
+       if (dtp->dtp_sysnum != 0) {
+               /* currently not supported for system calls */
+               dtar->dtar_size = 0;
+               return 0;
+       }
+
+       size = dtar->dtar_size;
+       dtar->dtar_size = dtp->dtp_nargs * sizeof(*dtar);
+       if (size == 0)
+               return 0;
+
+       t = 0;
+       dtai = dtar->dtar_args;
+       for (n = 0; n < dtp->dtp_nargs; n++) {
+               if (size < sizeof(*dtai)) {
+                       error = ENOSPC;
+                       break;
+               }
+               if (n >= DTMAXARGTYPES || dtp->dtp_argtype[n] == NULL)
+                       continue;
+               memset(&info, 0, sizeof(info));
+               info.dtai_pbn = dtp->dtp_pbn;
+               info.dtai_argn = t++;
+               strlcpy(info.dtai_argtype, dtp->dtp_argtype[n],
+                   sizeof(info.dtai_argtype));
+               error = copyout(&info, dtai, sizeof(*dtai));
+               if (error)
+                       break;
+               size -= sizeof(*dtai);
+               dtai++;
+       }
+       dtar->dtar_size = t * sizeof(*dtar);
 
        return error;
 }
index 9f425df..1e01f53 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dtvar.h,v 1.14 2022/06/28 09:32:27 bluhm Exp $ */
+/*     $OpenBSD: dtvar.h,v 1.15 2023/03/10 22:14:32 bluhm Exp $ */
 
 /*
  * Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@@ -37,6 +37,7 @@
  * Maximum number of arguments passed to a function.
  */
 #define DTMAXFUNCARGS  10
+#define DTMAXARGTYPES  5
 
 /*
  * Event state: where to store information when a probe fires.
@@ -114,6 +115,18 @@ struct dtioc_probe {
        struct dtioc_probe_info *dtpr_probes;   /* array of probe info */
 };
 
+struct dtioc_arg_info {
+       uint32_t        dtai_pbn;               /* probe number */
+       uint8_t         dtai_argn;              /* arguments number */
+       char            dtai_argtype[DTNAMESIZE];
+};
+
+struct dtioc_arg {
+       uint32_t                 dtar_pbn;      /* probe number */
+       size_t                   dtar_size;     /* size of the buffer */
+       struct dtioc_arg_info   *dtar_args;     /* array of arg info */
+};
+
 struct dtioc_req {
        uint32_t                 dtrq_pbn;      /* probe number */
        struct dt_filter         dtrq_filter;   /* probe filter */
@@ -128,11 +141,10 @@ struct dtioc_stat {
 
 #define DTIOCGPLIST    _IOWR('D', 1, struct dtioc_probe)
 #define DTIOCGSTATS    _IOR('D', 2, struct dtioc_stat)
-
 #define DTIOCRECORD    _IOW('D', 3, int)
 #define DTIOCPRBENABLE _IOW('D', 4, struct dtioc_req)
 #define DTIOCPRBDISABLE         _IOW('D', 5, struct dtioc_req)
-
+#define DTIOCGARGS     _IOWR('D', 6, struct dtioc_arg)
 
 #ifdef _KERNEL
 
@@ -219,7 +231,8 @@ struct dt_probe {
 
        /* Provider specific fields. */
        int                      dtp_sysnum;    /* [I] related # of syscall */
-       const char              *dtp_argtype[5];/* [I] type of arguments */
+       const char              *dtp_argtype[DTMAXARGTYPES];
+                                               /* [I] type of arguments */
        int                      dtp_nargs;     /* [I] # of arguments */
        vaddr_t                  dtp_addr;      /* [I] address of breakpoint */
 };