#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include "kolibri.h" int covfd, msrfd; uint64_t rdmsr(uint32_t reg) { uint64_t data; if (pread(msrfd, &data, sizeof data, reg) != sizeof data) { perror("rdmsr: pread"); exit(1); } return data; } void wrmsr(uint32_t reg, uint64_t data) { int fd; fd = open("/dev/cpu/0/msr", O_WRONLY); if (fd < 0) { perror("wrmsr: open"); exit(1); } if (pwrite(fd, &data, sizeof data, reg) != sizeof data) { perror("wrmsr: pwrite"); exit(1); } close(fd); return; } void handle_sigtrap() { uint64_t from = rdmsr(0x1db); uint64_t to = rdmsr(0x1dc); if ((from >= (uintptr_t)coverage_begin && from < (uintptr_t)coverage_end) || (to >= (uintptr_t)coverage_begin && to < (uintptr_t)coverage_end)) { write(covfd, &from, 4); write(covfd, &to, 4); } wrmsr(0x1d9, 3); } void trace_lbr_begin() { printf("hello from lbr!\n"); struct sigaction action; action.sa_sigaction = &handle_sigtrap; action.sa_flags = SA_SIGINFO; sigaction(SIGTRAP, &action, NULL); cpu_set_t my_set; CPU_ZERO(&my_set); CPU_SET(0, &my_set); sched_setaffinity(0, sizeof(cpu_set_t), &my_set); wrmsr(0x1d9, 3); msrfd = open("/dev/cpu/0/msr", O_RDONLY); if (msrfd < 0) { perror("rdmsr: open"); exit(1); } char coverage_filename[32]; sprintf(coverage_filename, "coverage.%i", getpid()); covfd = open(coverage_filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); set_eflags_tf(1); } void trace_lbr_end() { set_eflags_tf(0); wrmsr(0x1d9, 0); close(msrfd); close(covfd); }