On Fri, Jan 18, 2019 at 07:34:35PM +0100, Anton Lindqvist wrote: > You're right, updated diff.
OK bluhm@
> Index: share/man/man4/kcov.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/kcov.4,v
> retrieving revision 1.6
> diff -u -p -r1.6 kcov.4
> --- share/man/man4/kcov.4 27 Dec 2018 19:33:08 -0000 1.6
> +++ share/man/man4/kcov.4 18 Jan 2019 18:26:17 -0000
> @@ -62,9 +62,35 @@ Enable code coverage tracing for the cur
> The
> .Fa mode
> must be one of the following:
> -.Bl -tag -width KCOV_MODE_TRACE_PC
> +.Bl -ohang
> .It Dv KCOV_MODE_TRACE_PC
> Trace the kernel program counter.
> +.It Dv KCOV_MODE_TRACE_CMP
> +Trace comparison instructions and switch statements.
> +For switch statements, the number of traced comparison instructions is equal
> to
> +the number of switch cases.
> +Each traced comparison instruction is represented by 4 entries in the
> coverage
> +buffer:
> +.Bl -enum
> +.It
> +A mask where the least significant bit is set if one of the comparison
> operands
> +is a compile-time constant, which is always true for switch statements.
> +The remaining bits represents the log2 size of the operands, ranging from 0
> to
> +3.
> +.It
> +First comparison operand.
> +For switch statements, this operand corresponds to the case value.
> +.It
> +Second comparison operand.
> +For switch statements, this operand corresponds to the value passed to
> switch.
> +.It
> +Kernel program counter where the comparison instruction took place.
> +.El
> +.Pp
> +In this mode, the first entry in the coverage buffer reflects the number of
> +traced comparison instructions.
> +Thus, the effective number of entries in the coverage buffer is given by
> +multiplying the first entry by 4.
> .El
> .It Dv KIODISABLE Fa void
> Disable code coverage tracing for the current thread.
> Index: sys/arch/amd64/conf/Makefile.amd64
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/Makefile.amd64,v
> retrieving revision 1.108
> diff -u -p -r1.108 Makefile.amd64
> --- sys/arch/amd64/conf/Makefile.amd64 7 Jan 2019 20:24:59 -0000
> 1.108
> +++ sys/arch/amd64/conf/Makefile.amd64 18 Jan 2019 18:26:17 -0000
> @@ -95,7 +95,7 @@ LINKFLAGS+= -S
> .endif
>
> .if ${SYSTEM_OBJ:Mkcov.o} && ${COMPILER_VERSION:Mclang}
> -PROF= -fsanitize-coverage=trace-pc
> +PROF= -fsanitize-coverage=trace-pc,trace-cmp
> .endif
>
> %LOAD
> @@ -152,7 +152,7 @@ vers.o: ${SYSTEM_DEP:Ngap.o}
>
> .if ${SYSTEM_OBJ:Mkcov.o} && ${COMPILER_VERSION:Mclang}
> kcov.o: $S/dev/kcov.c
> - ${NORMAL_C} -fno-sanitize-coverage=trace-pc
> + ${NORMAL_C} -fno-sanitize-coverage=trace-pc,trace-cmp
> .endif
>
> clean:
> Index: sys/arch/i386/conf/Makefile.i386
> ===================================================================
> RCS file: /cvs/src/sys/arch/i386/conf/Makefile.i386,v
> retrieving revision 1.130
> diff -u -p -r1.130 Makefile.i386
> --- sys/arch/i386/conf/Makefile.i386 30 Oct 2018 11:08:30 -0000 1.130
> +++ sys/arch/i386/conf/Makefile.i386 18 Jan 2019 18:26:17 -0000
> @@ -97,7 +97,7 @@ LINKFLAGS+= -S
> .endif
>
> .if ${SYSTEM_OBJ:Mkcov.o} && ${COMPILER_VERSION:Mclang}
> -PROF= -fsanitize-coverage=trace-pc
> +PROF= -fsanitize-coverage=trace-pc,trace-cmp
> .endif
>
> %LOAD
> @@ -148,7 +148,7 @@ vers.o: ${SYSTEM_DEP:Ngap.o}
>
> .if ${SYSTEM_OBJ:Mkcov.o} && ${COMPILER_VERSION:Mclang}
> kcov.o: $S/dev/kcov.c
> - ${NORMAL_C} -fno-sanitize-coverage=trace-pc
> + ${NORMAL_C} -fno-sanitize-coverage=trace-pc,trace-cmp
> .endif
>
> clean:
> Index: sys/dev/kcov.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/kcov.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 kcov.c
> --- sys/dev/kcov.c 16 Jan 2019 19:27:07 -0000 1.10
> +++ sys/dev/kcov.c 18 Jan 2019 18:26:17 -0000
> @@ -26,6 +26,9 @@
>
> #include <uvm/uvm_extern.h>
>
> +#define KCOV_CMP_CONST 0x1
> +#define KCOV_CMP_SIZE(x) ((x) << 1)
> +
> /* #define KCOV_DEBUG */
> #ifdef KCOV_DEBUG
> #define DPRINTF(x...) do { if (kcov_debug) printf(x); } while (0)
> @@ -99,12 +102,140 @@ __sanitizer_cov_trace_pc(void)
> return;
>
> idx = kd->kd_buf[0];
> - if (idx < kd->kd_nmemb) {
> + if (idx + 1 <= kd->kd_nmemb) {
> kd->kd_buf[idx + 1] = (uintptr_t)__builtin_return_address(0);
> kd->kd_buf[0] = idx + 1;
> }
> }
>
> +/*
> + * Compiling the kernel with the `-fsanitize-coverage=trace-cmp' option will
> + * cause the following function to be called upon integer comparisons and
> switch
> + * statements.
> + *
> + * If kcov is enabled for the current thread, the comparison will be stored
> in
> + * its corresponding coverage buffer.
> + */
> +void
> +trace_cmp(uint64_t type, uint64_t arg1, uint64_t arg2, uintptr_t pc)
> +{
> + struct kcov_dev *kd;
> + uint64_t idx;
> +
> + /*
> + * Do not trace before kcovopen() has been called at least once.
> + * At this point, all secondary CPUs have booted and accessing curcpu()
> + * is safe.
> + */
> + if (kcov_cold)
> + return;
> +
> + /* Do not trace in interrupts to prevent noisy coverage. */
> + if (inintr())
> + return;
> +
> + kd = curproc->p_kd;
> + if (kd == NULL || kd->kd_mode != KCOV_MODE_TRACE_CMP)
> + return;
> +
> + idx = kd->kd_buf[0];
> + if (idx * 4 + 4 <= kd->kd_nmemb) {
> + kd->kd_buf[idx * 4 + 1] = type;
> + kd->kd_buf[idx * 4 + 2] = arg1;
> + kd->kd_buf[idx * 4 + 3] = arg2;
> + kd->kd_buf[idx * 4 + 4] = pc;
> + kd->kd_buf[0] = idx + 1;
> + }
> +}
> +
> +void
> +__sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(0), arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(1), arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(2), arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(3), arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_const_cmp1(uint8_t arg1, uint8_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(0) | KCOV_CMP_CONST, arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_const_cmp2(uint16_t arg1, uint16_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(1) | KCOV_CMP_CONST, arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(2) | KCOV_CMP_CONST, arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_const_cmp8(uint64_t arg1, uint64_t arg2)
> +{
> + trace_cmp(KCOV_CMP_SIZE(3) | KCOV_CMP_CONST, arg1, arg2,
> + (uintptr_t)__builtin_return_address(0));
> +}
> +
> +void
> +__sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases)
> +{
> + uint64_t i, nbits, ncases, type;
> + uintptr_t pc;
> +
> + pc = (uintptr_t)__builtin_return_address(0);
> + ncases = cases[0];
> + nbits = cases[1];
> +
> + switch (nbits) {
> + case 8:
> + type = KCOV_CMP_SIZE(0);
> + break;
> + case 16:
> + type = KCOV_CMP_SIZE(1);
> + break;
> + case 32:
> + type = KCOV_CMP_SIZE(2);
> + break;
> + case 64:
> + type = KCOV_CMP_SIZE(3);
> + break;
> + default:
> + return;
> + }
> + type |= KCOV_CMP_CONST;
> +
> + for (i = 0; i < ncases; i++)
> + trace_cmp(type, cases[i + 2], val, pc);
> +}
> +
> void
> kcovattach(int count)
> {
> @@ -173,7 +304,7 @@ kcovioctl(dev_t dev, u_long cmd, caddr_t
> break;
> }
> mode = *((int *)data);
> - if (mode != KCOV_MODE_TRACE_PC) {
> + if (mode != KCOV_MODE_TRACE_PC && mode != KCOV_MODE_TRACE_CMP) {
> error = EINVAL;
> break;
> }
> Index: sys/sys/kcov.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/kcov.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 kcov.h
> --- sys/sys/kcov.h 27 Dec 2018 19:33:08 -0000 1.3
> +++ sys/sys/kcov.h 18 Jan 2019 18:26:17 -0000
> @@ -27,6 +27,7 @@
>
> #define KCOV_MODE_NONE 0
> #define KCOV_MODE_TRACE_PC 1
> +#define KCOV_MODE_TRACE_CMP 2
>
> #ifdef _KERNEL
>
signature.asc
Description: PGP signature
