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