#ifdef SAN_NEEDS_INTERCEPTORS
#define SAN_RUNTIME
#endif
#include <sys/param.h>
#include <sys/coverage.h>
#include <machine/atomic.h>
void __sanitizer_cov_trace_pc(void);
void __sanitizer_cov_trace_cmp1(uint8_t, uint8_t);
void __sanitizer_cov_trace_cmp2(uint16_t, uint16_t);
void __sanitizer_cov_trace_cmp4(uint32_t, uint32_t);
void __sanitizer_cov_trace_cmp8(uint64_t, uint64_t);
void __sanitizer_cov_trace_const_cmp1(uint8_t, uint8_t);
void __sanitizer_cov_trace_const_cmp2(uint16_t, uint16_t);
void __sanitizer_cov_trace_const_cmp4(uint32_t, uint32_t);
void __sanitizer_cov_trace_const_cmp8(uint64_t, uint64_t);
void __sanitizer_cov_trace_switch(uint64_t, uint64_t *);
static cov_trace_pc_t cov_trace_pc;
static cov_trace_cmp_t cov_trace_cmp;
void
cov_register_pc(cov_trace_pc_t trace_pc)
{
atomic_store_ptr(&cov_trace_pc, trace_pc);
}
void
cov_unregister_pc(void)
{
atomic_store_ptr(&cov_trace_pc, NULL);
}
void
cov_register_cmp(cov_trace_cmp_t trace_cmp)
{
atomic_store_ptr(&cov_trace_cmp, trace_cmp);
}
void
cov_unregister_cmp(void)
{
atomic_store_ptr(&cov_trace_cmp, NULL);
}
void
__sanitizer_cov_trace_pc(void)
{
cov_trace_pc_t trace_pc;
trace_pc = atomic_load_ptr(&cov_trace_pc);
if (trace_pc != NULL)
trace_pc((uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(0), arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(1), arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(2), arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(3), arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_const_cmp1(uint8_t arg1, uint8_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(0) | COV_CMP_CONST, arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_const_cmp2(uint16_t arg1, uint16_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(1) | COV_CMP_CONST, arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(2) | COV_CMP_CONST, arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_const_cmp8(uint64_t arg1, uint64_t arg2)
{
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp != NULL)
trace_cmp(COV_CMP_SIZE(3) | COV_CMP_CONST, arg1, arg2,
(uint64_t)__builtin_return_address(0));
}
void
__sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases)
{
uint64_t i, count, ret, type;
cov_trace_cmp_t trace_cmp;
trace_cmp = atomic_load_ptr(&cov_trace_cmp);
if (trace_cmp == NULL)
return;
count = cases[0];
ret = (uint64_t)__builtin_return_address(0);
switch (cases[1]) {
case 8:
type = COV_CMP_SIZE(0);
break;
case 16:
type = COV_CMP_SIZE(1);
break;
case 32:
type = COV_CMP_SIZE(2);
break;
case 64:
type = COV_CMP_SIZE(3);
break;
default:
return;
}
val |= COV_CMP_CONST;
for (i = 0; i < count; i++)
if (!trace_cmp(type, val, cases[i + 2], ret))
return;
}