-/* $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>
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 *);
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:
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,
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;
}
-/* $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>
* Maximum number of arguments passed to a function.
*/
#define DTMAXFUNCARGS 10
+#define DTMAXARGTYPES 5
/*
* Event state: where to store information when a probe fires.
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 */
#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
/* 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 */
};