Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
9325 Boppan 1
#include 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8
#include 
9
#include "umka.h"
10
 
11
#define MSR_IA32_DEBUGCTLMSR        0x1d9
12
#define MSR_IA32_LASTBRANCHFROMIP   0x1db
13
#define MSR_IA32_LASTBRANCHTOIP     0x1dc
14
 
15
int covfd, msrfd;
16
 
17
uint64_t rdmsr(uint32_t reg)
18
{
19
    uint64_t data;
20
 
21
    if (pread(msrfd, &data, sizeof data, reg) != sizeof data) {
22
        perror("rdmsr: pread");
23
        exit(1);
24
    }
25
 
26
    return data;
27
}
28
 
29
void wrmsr(uint32_t reg, uint64_t data)
30
{
31
    int fd;
32
    fd = open("/dev/cpu/0/msr", O_WRONLY);
33
    if (fd < 0) {
34
        perror("wrmsr: open");
35
        exit(1);
36
    }
37
 
38
    if (pwrite(fd, &data, sizeof data, reg) != sizeof data) {
39
        perror("wrmsr: pwrite");
40
        exit(1);
41
    }
42
 
43
    close(fd);
44
    return;
45
}
46
 
47
void handle_sigtrap() {
48
    uint64_t from = rdmsr(MSR_IA32_LASTBRANCHFROMIP);
49
    uint64_t to = rdmsr(MSR_IA32_LASTBRANCHTOIP);
50
 
51
    if ((from >= (uintptr_t)coverage_begin && from < (uintptr_t)coverage_end) ||
52
        (to >= (uintptr_t)coverage_begin && to < (uintptr_t)coverage_end)) {
53
        write(covfd, &from, 4);
54
        write(covfd, &to, 4);
55
    }
56
 
57
    wrmsr(MSR_IA32_DEBUGCTLMSR, 3);
58
}
59
 
60
uint32_t set_eflags_tf(uint32_t tf) {
61
    uint32_t prev;
62
    __asm__ __inline__ __volatile__ (
63
        "pushfd;"
64
        "pop    eax;"
65
        "ror    eax, 8;"
66
        "mov    edx, eax;"
67
        "and    edx, 1;"
68
        "and    eax, ~1;"
69
        "or     eax, ecx;"
70
        "rol    eax, 8;"
71
        "push   eax;"
72
        "popfd"
73
        : "=d"(prev)
74
        : "c"(tf)
75
        : "eax", "memory");
76
    return prev;
77
}
78
 
79
void trace_lbr_begin() {
80
    struct sigaction action;
81
    action.sa_sigaction = &handle_sigtrap;
82
    action.sa_flags = SA_SIGINFO;
83
    sigaction(SIGTRAP, &action, NULL);
84
 
85
    wrmsr(MSR_IA32_DEBUGCTLMSR, 3);
86
    msrfd = open("/dev/cpu/0/msr", O_RDONLY);
87
    if (msrfd < 0) {
88
        perror("rdmsr: open");
89
        exit(1);
90
    }
91
    char coverage_filename[32];
92
    sprintf(coverage_filename, "coverage.%i", getpid());
93
    covfd = open(coverage_filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_IWOTH);
94
    void *coverage_begin_addr = coverage_begin;
95
    void *coverage_end_addr = coverage_end;
96
    write(covfd, &coverage_begin_addr, 4);
97
    write(covfd, &coverage_end_addr, 4);
98
}
99
 
100
void trace_lbr_end() {
101
    wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
102
    close(msrfd);
103
    close(covfd);
104
}
105
 
106
uint32_t trace_lbr_pause(void) {
107
    return set_eflags_tf(0u);
108
}
109
 
110
void trace_lbr_resume(uint32_t value) {
111
    set_eflags_tf(value);
112
}