-vers(a, {-$OpenBSD: MAKEDEV.common,v 1.99 2018/07/28 08:09:50 ratchov Exp $-})dnl
+vers(a, {-$OpenBSD: MAKEDEV.common,v 1.100 2018/08/19 11:42:33 anton Exp $-})dnl
dnl
dnl Copyright (c) 2001-2006 Todd T. Fries <todd@OpenBSD.org>
dnl
target(all, vmm)dnl
target(all, pvbus, 0, 1)dnl
target(all, bpf)dnl
+target(all, kcov)dnl
dnl
_mkdev(all, {-all-}, {-dnl
show_target(all)dnl
__devitem(pvbus, pvbus*, paravirtual device tree root)dnl
_mkdev(pvbus, {-pvbus*-}, {-M pvbus$U c major_pvbus_c $U 640-}, 640)dnl
_mkdev(local, local, {-test -s $T.local && sh $T.local-})dnl
+__devitem(kcov, kcov, Kernel code coverage tracing)dnl
+_mkdev(kcov, kcov, {-M kcov c major_kcov_c 0 600-})dnl
define(MACHINE,amd64)dnl
vers(__file__,
- {-$OpenBSD: MAKEDEV.md,v 1.69 2016/09/11 19:59:53 deraadt Exp $-},
+ {-$OpenBSD: MAKEDEV.md,v 1.70 2018/08/19 11:42:33 anton Exp $-},
etc.MACHINE)dnl
dnl
dnl Copyright (c) 2001-2006 Todd T. Fries <todd@OpenBSD.org>
_DEV(ipmi, 96)
dnl _DEV(joy, 26)
_DEV(nvram, 85)
+_DEV(kcov, 19)
_DEV(pci, 72)
_DEV(pctr, 46)
_DEV(pf, 73)
define(MACHINE,i386)dnl
vers(__file__,
- {-$OpenBSD: MAKEDEV.md,v 1.83 2016/09/11 19:59:53 deraadt Exp $-},
+ {-$OpenBSD: MAKEDEV.md,v 1.84 2018/08/19 11:42:33 anton Exp $-},
etc.MACHINE)dnl
dnl
dnl Copyright (c) 2001-2006 Todd T. Fries <todd@OpenBSD.org>
_DEV(hotplug, 82)
_DEV(ipmi, 96)
_DEV(joy, 26)
+_DEV(kcov, 19)
_DEV(nvram, 84)
_DEV(pci, 72)
_DEV(pctr, 46)
-# $OpenBSD: Makefile,v 1.689 2018/08/03 01:50:14 kevlo Exp $
+# $OpenBSD: Makefile,v 1.690 2018/08/19 11:42:33 anton Exp $
MAN= aac.4 ac97.4 acphy.4 acrtc.4 \
acpi.4 acpiac.4 acpials.4 acpiasus.4 acpibat.4 \
ip.4 ip6.4 ipcomp.4 ipgphy.4 ipmi.4 ips.4 ipsec.4 ipw.4 \
isa.4 isagpio.4 isapnp.4 islrtc.4 it.4 itherm.4 iwi.4 iwn.4 iwm.4 \
ix.4 ixgb.4 jmb.4 jme.4 jmphy.4 \
- kate.4 km.4 ksyms.4 kue.4 lc.4 lge.4 lii.4 lisa.4 lm.4 \
+ kate.4 kcov.4 km.4 ksyms.4 kue.4 lc.4 lge.4 lii.4 lisa.4 lm.4 \
lmenv.4 lmn.4 lmtemp.4 lo.4 lpt.4 lxtphy.4 luphy.4 \
maestro.4 mainbus.4 malo.4 maxds.4 maxrtc.4 maxtmp.4 mbg.4 midi.4 \
mii.4 mfi.4 \
--- /dev/null
+.\" $OpenBSD: kcov.4,v 1.1 2018/08/19 11:42:33 anton Exp $
+.\"
+.\" Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: August 19 2018 $
+.Dt KCOV 4
+.Os
+.Sh NAME
+.Nm kcov
+.Nd kernel code coverage tracing
+.Sh SYNOPSIS
+.Cd option KCOV
+.Pp
+.In sys/kcov.h
+.Sh DESCRIPTION
+The
+.Nm
+driver implements collection of code coverage inside the kernel.
+It can be enabled on a per process basis from userland,
+allowing the kernel program counter to be collected during syscalls triggered by
+the same process.
+The collected coverage can be accessed by mapping the device
+using
+.Xr mmap 2 .
+.Pp
+By default,
+.Nm
+is not enabled but requires the compile-time configuration
+.Cd option KCOV
+to be present,
+see
+.Xr options 4 .
+.Pp
+The following
+.Xr ioctl 2
+calls are provided:
+.Bl -tag -width 4n
+.It Dv KIOSETBUFSIZE Fa unsigned long *nentries
+Allocate a coverage buffer with a capacity of
+.Fa nentries .
+The buffer can be accessed using
+.Xr mmap 2
+whereas the returned pointer must be interpreted as an array of
+.Vt unsigned long
+entries.
+The first entry contains the number of entries in the array,
+excluding the first entry.
+.It Dv KIOENABLE Fa void
+Enable code coverage tracing for the current process.
+.It Dv KIODISABLE Fa void
+Disable code coverage tracing for the current process.
+.El
+.Sh FILES
+.Bl -tag -width /dev/kcov -compact
+.It Pa /dev/kcov
+Default device node.
+.El
+.Sh EXAMPLES
+In the following example,
+the
+.Xr read 2
+syscall is traced and the coverage displayed which in turn can be passed to
+.Xr addr2line 1
+in order to translate the kernel program counter into the file name and line
+number it corresponds to.
+.Bd -literal
+#include <sys/ioctl.h>
+#include <sys/kcov.h>
+#include <sys/mman.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+ unsigned long *cover, i;
+ unsigned long size = 1024;
+ int fd;
+
+ fd = open("/dev/kcov", O_RDWR);
+ if (fd == -1)
+ err(1, "open");
+
+ if (ioctl(fd, KIOSETBUFSIZE, &size) == -1)
+ err(1, "ioctl: KIOSETBUFSIZE");
+ cover = mmap(NULL, size * sizeof(unsigned long),
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (cover == MAP_FAILED)
+ err(1, "mmap");
+
+ if (ioctl(fd, KIOENABLE) == -1)
+ err(1, "ioctl: KIOENABLE");
+ read(-1, NULL, 0);
+ if (ioctl(fd, KIODISABLE) == -1)
+ err(1, "ioctl: KIODISABLE");
+
+ for (i = 0; i < cover[0]; i++)
+ printf("%p\en", (void *)cover[i + 1]);
+
+ if (munmap(cover, size * sizeof(unsigned long)) == -1)
+ err(1, "munmap");
+ close(fd);
+
+ return 0;
+}
+.Ed
+.Sh SEE ALSO
+.Xr options 4
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Ox 6.4 .
+.Sh AUTHORS
+.An Anton Lindqvist Aq Mt anton@openbsd.org
+.Sh CAVEATS
+The
+.Nm
+driver is limited to architectures using
+.Xr clang 1
+as their default compiler.
-/* $OpenBSD: conf.c,v 1.60 2016/09/04 10:51:23 naddy Exp $ */
+/* $OpenBSD: conf.c,v 1.61 2018/08/19 11:42:33 anton Exp $ */
/*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
(dev_type_stop((*))) enodev, 0, seltrue, \
(dev_type_mmap((*))) enodev }
+/* open, close, ioctl, mmap */
+#define cdev_kcov_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) enodev, 0, selfalse, \
+ (dev_init(c,n,mmap)), 0, D_CLONE }
#define mmread mmrw
#define mmwrite mmrw
cdev_decl(drm);
#include "viocon.h"
cdev_decl(viocon);
+cdev_decl(kcov);
#include "wsdisplay.h"
#include "wskbd.h"
cdev_lpt_init(NLPT,lpt), /* 16: parallel printer */
cdev_ch_init(NCH,ch), /* 17: SCSI autochanger */
cdev_notdef(), /* 18: was: concatenated disk driver */
- cdev_notdef(), /* 19 */
+ cdev_kcov_init(1,kcov), /* 19: kcov */
cdev_uk_init(NUK,uk), /* 20: unknown SCSI */
cdev_notdef(), /* 21 */
cdev_fd_init(1,filedesc), /* 22: file descriptor pseudo-device */
-# $OpenBSD: GENERIC,v 1.457 2018/08/03 01:50:14 kevlo Exp $
+# $OpenBSD: GENERIC,v 1.458 2018/08/19 11:42:33 anton Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
# mouse & keyboard multiplexor pseudo-devices
pseudo-device wsmux 2
+# kernel code coverage
+pseudo-device kcov 1
+
# Virtio devices
virtio* at pci? # Virtio PCI device
vioblk* at virtio? # Virtio block device
-# $OpenBSD: Makefile.amd64,v 1.98 2018/07/13 08:10:56 deraadt Exp $
+# $OpenBSD: Makefile.amd64,v 1.99 2018/08/19 11:42:33 anton Exp $
# For instructions on building kernels consult the config(8) and options(4)
# manual pages.
.else
CMACHFLAGS+= -mretpoline
.endif
+.if ${IDENT:M-DKCOV} && ${COMPILER_VERSION:Mclang}
+CMACHFLAGS+= -fno-ret-protector
+PROF= -fsanitize-coverage=trace-pc
+.endif
.if ${COMPILER_VERSION:Mclang}
NO_INTEGR_AS= -no-integrated-as
.endif
sh $S/conf/newvers.sh
${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
+.if ${IDENT:M-DKCOV} && ${COMPILER_VERSION:Mclang}
+kcov.o: $S/dev/kcov.c
+ ${NORMAL_C} -fno-sanitize-coverage=trace-pc
+.endif
+
+
clean:
rm -f *bsd *bsd.gdb *.[dio] [a-z]*.s assym.* \
gap.link ld.script lorder makegap.sh param.c
-# $OpenBSD: files.amd64,v 1.97 2018/07/12 12:46:00 fcambus Exp $
+# $OpenBSD: files.amd64,v 1.98 2018/08/19 11:42:33 anton Exp $
maxpartitions 16
maxusers 2 16 128
file arch/amd64/amd64/vmm.c vmm needs-flag
file arch/amd64/amd64/vmm_support.S vmm
+#
+# KCOV
+#
+pseudo-device kcov
+file dev/kcov.c kcov
+
#
# Machine-independent SD/MMC drivers
#
-# $OpenBSD: GENERIC,v 1.833 2018/08/03 01:50:14 kevlo Exp $
+# $OpenBSD: GENERIC,v 1.834 2018/08/19 11:42:33 anton Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
# mouse & keyboard multiplexor pseudo-devices
pseudo-device wsmux 2
+# kernel code coverage
+pseudo-device kcov 1
+
# Virtio devices
virtio* at pci? # Virtio PCI device
vioblk* at virtio? # Virtio block device
-# $OpenBSD: Makefile.i386,v 1.124 2018/07/13 08:10:45 deraadt Exp $
+# $OpenBSD: Makefile.i386,v 1.125 2018/08/19 11:42:33 anton Exp $
# For instructions on building kernels consult the config(8) and options(4)
# manual pages.
.else
CMACHFLAGS+= -mretpoline
.endif
+.if ${IDENT:M-DKCOV} && ${COMPILER_VERSION:Mclang}
+PROF= -fsanitize-coverage=trace-pc
+.endif
.if ${COMPILER_VERSION:Mclang}
NO_INTEGR_AS= -no-integrated-as
.endif
sh $S/conf/newvers.sh
${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
+.if ${IDENT:M-DKCOV} && ${COMPILER_VERSION:Mclang}
+kcov.o: $S/dev/kcov.c
+ ${NORMAL_C} -fno-sanitize-coverage=trace-pc
+.endif
+
clean:
rm -f *bsd *bsd.gdb *.[dio] [a-z]*.s assym.* \
gap.link ld.script lorder makegap.sh param.c
-# $OpenBSD: files.i386,v 1.239 2018/07/09 19:20:29 guenther Exp $
+# $OpenBSD: files.i386,v 1.240 2018/08/19 11:42:33 anton Exp $
#
# new style config file for i386 architecture
#
file arch/i386/i386/vmm.c vmm needs-flag
file arch/i386/i386/vmm_support.S vmm
+#
+# KCOV
+#
+pseudo-device kcov
+file dev/kcov.c kcov
+
#
# IPMI
#
-/* $OpenBSD: conf.c,v 1.158 2016/10/21 06:20:58 mlarkin Exp $ */
+/* $OpenBSD: conf.c,v 1.159 2018/08/19 11:42:33 anton Exp $ */
/* $NetBSD: conf.c,v 1.75 1996/05/03 19:40:20 christos Exp $ */
/*
(dev_type_stop((*))) enodev, 0, seltrue, \
(dev_type_mmap((*))) enodev }
+/* open, close, ioctl, mmap */
+#define cdev_kcov_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) enodev, 0, selfalse, \
+ (dev_init(c,n,mmap)), 0, D_CLONE }
+
#define mmread mmrw
#define mmwrite mmrw
cdev_decl(mm);
cdev_decl(nvram);
#include "drm.h"
cdev_decl(drm);
+cdev_decl(kcov);
#include "wsdisplay.h"
#include "wskbd.h"
cdev_lpt_init(NLPT,lpt), /* 16: parallel printer */
cdev_ch_init(NCH,ch), /* 17: SCSI autochanger */
cdev_notdef(), /* 18: was: concatenated disk driver */
- cdev_notdef(), /* 19 */
+ cdev_kcov_init(1,kcov), /* 19: kcov */
cdev_uk_init(NUK,uk), /* 20: unknown SCSI */
cdev_acpiapm_init(1,acpiapm), /* 21: Power Management stuff */
cdev_fd_init(1,filedesc), /* 22: file descriptor pseudo-device */
--- /dev/null
+/* $OpenBSD: kcov.c,v 1.1 2018/08/19 11:42:33 anton Exp $ */
+
+/*
+ * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/kcov.h>
+#include <sys/malloc.h>
+#include <sys/stdint.h>
+#include <sys/queue.h>
+
+#include <uvm/uvm_extern.h>
+
+/* #define KCOV_DEBUG */
+#ifdef KCOV_DEBUG
+#define DPRINTF(x...) do { if (kcov_debug) printf(x); } while (0)
+#else
+#define DPRINTF(x...)
+#endif
+
+/* kcov descriptor */
+struct kd {
+ enum {
+ KCOV_MODE_DISABLED,
+ KCOV_MODE_INIT,
+ KCOV_MODE_TRACE_PC,
+ } kd_mode;
+ int kd_unit; /* device minor */
+ pid_t kd_pid; /* process being traced */
+ uintptr_t *kd_buf; /* traced coverage */
+ size_t kd_nmemb;
+ size_t kd_size;
+
+ TAILQ_ENTRY(kd) kd_entry;
+};
+
+void kcovattach(int);
+
+int kd_alloc(struct kd *, unsigned long);
+struct kd *kd_lookup(int);
+
+static inline struct kd *kd_lookup_pid(pid_t);
+static inline int inintr(void);
+
+TAILQ_HEAD(, kd) kd_list = TAILQ_HEAD_INITIALIZER(kd_list);
+
+#ifdef KCOV_DEBUG
+int kcov_debug = 1;
+#endif
+
+/*
+ * Compiling the kernel with the `-fsanitize-coverage=trace-pc' option will
+ * cause the following function to be called upon function entry and before
+ * each block instructions that maps to a single line in the original source
+ * code.
+ *
+ * If kcov is enabled for the current process, the executed address will be
+ * stored in the corresponding coverage buffer.
+ * The first element in the coverage buffer holds the index of next available
+ * element.
+ */
+void
+__sanitizer_cov_trace_pc(void)
+{
+ extern int cold;
+ struct kd *kd;
+ uint64_t idx;
+
+ /* Do not trace during boot. */
+ if (cold)
+ return;
+
+ /* Do not trace in interrupts to prevent noisy coverage. */
+ if (inintr())
+ return;
+
+ kd = kd_lookup_pid(curproc->p_p->ps_pid);
+ if (kd == NULL)
+ return;
+
+ idx = kd->kd_buf[0];
+ if (idx < kd->kd_nmemb) {
+ kd->kd_buf[idx + 1] = (uintptr_t)__builtin_return_address(0);
+ kd->kd_buf[0] = idx + 1;
+ }
+}
+
+void
+kcovattach(int count)
+{
+}
+
+int
+kcovopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+#ifdef KCOV
+ struct kd *kd;
+
+ if (kd_lookup(minor(dev)) != NULL)
+ return (EBUSY);
+
+ DPRINTF("%s: unit=%d\n", __func__, minor(dev));
+
+ kd = malloc(sizeof(*kd), M_SUBPROC, M_WAITOK | M_ZERO);
+ kd->kd_unit = minor(dev);
+ TAILQ_INSERT_TAIL(&kd_list, kd, kd_entry);
+ return (0);
+#else
+ return (ENXIO);
+#endif
+}
+
+int
+kcovclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct kd *kd;
+
+ kd = kd_lookup(minor(dev));
+ if (kd == NULL)
+ return (EINVAL);
+
+ DPRINTF("%s: unit=%d\n", __func__, minor(dev));
+
+ TAILQ_REMOVE(&kd_list, kd, kd_entry);
+ free(kd->kd_buf, M_SUBPROC, kd->kd_size);
+ free(kd, M_SUBPROC, sizeof(struct kd));
+ return (0);
+}
+
+int
+kcovioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct kd *kd;
+ int error = 0;
+
+ kd = kd_lookup(minor(dev));
+ if (kd == NULL)
+ return (ENXIO);
+
+ switch (cmd) {
+ case KIOSETBUFSIZE:
+ if (kd->kd_mode != KCOV_MODE_DISABLED) {
+ error = EBUSY;
+ break;
+ }
+ error = kd_alloc(kd, *((unsigned long *)data));
+ if (error == 0)
+ kd->kd_mode = KCOV_MODE_INIT;
+ break;
+ case KIOENABLE:
+ if (kd->kd_mode != KCOV_MODE_INIT) {
+ error = EBUSY;
+ break;
+ }
+ kd->kd_mode = KCOV_MODE_TRACE_PC;
+ kd->kd_pid = p->p_p->ps_pid;
+ break;
+ case KIODISABLE:
+ /* Only the enabled process may disable itself. */
+ if (kd->kd_pid != p->p_p->ps_pid ||
+ kd->kd_mode != KCOV_MODE_TRACE_PC) {
+ error = EBUSY;
+ break;
+ }
+ kd->kd_mode = KCOV_MODE_INIT;
+ kd->kd_pid = 0;
+ break;
+ default:
+ error = EINVAL;
+ DPRINTF("%s: %lu: unknown command\n", __func__, cmd);
+ }
+
+ DPRINTF("%s: unit=%d, mode=%d, pid=%d, error=%d\n",
+ __func__, kd->kd_unit, kd->kd_mode, kd->kd_pid, error);
+
+ return (error);
+}
+
+paddr_t
+kcovmmap(dev_t dev, off_t offset, int prot)
+{
+ struct kd *kd;
+ paddr_t pa;
+ vaddr_t va;
+
+ kd = kd_lookup(minor(dev));
+ if (kd == NULL)
+ return (paddr_t)(-1);
+
+ if (offset < 0 || offset >= kd->kd_nmemb * sizeof(uintptr_t))
+ return (paddr_t)(-1);
+
+ va = (vaddr_t)kd->kd_buf + offset;
+ if (pmap_extract(pmap_kernel(), va, &pa) == FALSE)
+ return (paddr_t)(-1);
+ return (pa);
+}
+
+void
+kcov_exit(struct proc *p)
+{
+ struct kd *kd;
+
+ kd = kd_lookup_pid(p->p_p->ps_pid);
+ if (kd == NULL)
+ return;
+
+ kd->kd_mode = KCOV_MODE_INIT;
+ kd->kd_pid = 0;
+}
+
+struct kd *
+kd_lookup(int unit)
+{
+ struct kd *kd;
+
+ TAILQ_FOREACH(kd, &kd_list, kd_entry) {
+ if (kd->kd_unit == unit)
+ return (kd);
+ }
+ return (NULL);
+}
+
+int
+kd_alloc(struct kd *kd, unsigned long nmemb)
+{
+ size_t size;
+
+ KASSERT(kd->kd_buf == NULL);
+
+ if (nmemb == 0 || nmemb > KCOV_BUF_MAX_NMEMB)
+ return (EINVAL);
+
+ size = roundup(nmemb * sizeof(uintptr_t), PAGE_SIZE);
+ kd->kd_buf = malloc(size, M_SUBPROC, M_WAITOK | M_ZERO);
+ /* The first element is reserved to hold the number of used elements. */
+ kd->kd_nmemb = nmemb - 1;
+ kd->kd_size = size;
+ return (0);
+}
+
+static inline struct kd *
+kd_lookup_pid(pid_t pid)
+{
+ struct kd *kd;
+
+ TAILQ_FOREACH(kd, &kd_list, kd_entry) {
+ if (kd->kd_pid == pid && kd->kd_mode == KCOV_MODE_TRACE_PC)
+ return (kd);
+ }
+ return (NULL);
+}
+
+static inline int
+inintr(void)
+{
+#if defined(__amd64__) || defined(__i386__)
+ return (curcpu()->ci_idepth > 0);
+#else
+ return (0);
+#endif
+}
-/* $OpenBSD: kern_exit.c,v 1.166 2018/08/13 15:26:17 visa Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.167 2018/08/19 11:42:33 anton Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
#include <sys/filedesc.h>
#include <sys/signalvar.h>
#include <sys/sched.h>
+#include <sys/kcov.h>
#include <sys/ktrace.h>
#include <sys/pool.h>
#include <sys/mutex.h>
acct_process(p);
#endif
+#ifdef KCOV
+ kcov_exit(p);
+#endif
+
#ifdef KTRACE
/* release trace file */
if (pr->ps_tracevp)
--- /dev/null
+/* $OpenBSD: kcov.h,v 1.1 2018/08/19 11:42:33 anton Exp $ */
+
+/*
+ * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_KCOV_H_
+#define _SYS_KCOV_H_
+
+#include <sys/ioccom.h>
+
+#define KIOSETBUFSIZE _IOW('K', 1, unsigned long)
+#define KIOENABLE _IO('K', 2)
+#define KIODISABLE _IO('K', 3)
+
+#ifdef _KERNEL
+
+#define KCOV_BUF_MAX_NMEMB (256 << 10)
+
+void kcov_exit(struct proc *);
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_KCOV_H_ */