From: bluhm Date: Fri, 10 Mar 2023 22:14:32 +0000 (+0000) Subject: Add new dt(4) ioctl DTIOCGARGS to get the types of probe arguments. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=cd5e52239c583d1ad74e33aa29deff117300c4ec;p=openbsd Add new dt(4) ioctl DTIOCGARGS to get the types of probe arguments. 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@ --- diff --git a/sys/dev/dt/dt_dev.c b/sys/dev/dt/dt_dev.c index 107e972800a..4f84e5dd4fc 100644 --- a/sys/dev/dt/dt_dev.c +++ b/sys/dev/dt/dt_dev.c @@ -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 @@ -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; } diff --git a/sys/dev/dt/dtvar.h b/sys/dev/dt/dtvar.h index 9f425dfe0c6..1e01f53de5d 100644 --- a/sys/dev/dt/dtvar.h +++ b/sys/dev/dt/dtvar.h @@ -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 @@ -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 */ };