Coverage collection speed up 4x!
Also, adjust disk cache size and move set_eflags_tf() to trace_lbr.c.
This commit is contained in:
parent
2a4cfff503
commit
67f7873e27
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,6 +17,7 @@ umka.fas
|
||||
umka.sym
|
||||
umka.lst
|
||||
umka.prp
|
||||
umka.cov
|
||||
tags
|
||||
*.out
|
||||
coverage.*
|
||||
|
24
covpreproc.c
24
covpreproc.c
@ -3,7 +3,7 @@
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define MAX_COVERED_CODE_SIZE (128*1024)
|
||||
#define MAX_COVERED_CODE_SIZE (256*1024)
|
||||
|
||||
typedef struct {
|
||||
uint64_t to_cnt, from_cnt;
|
||||
@ -18,16 +18,18 @@ void read_coverage_file(const char *fname) {
|
||||
fseeko(f, 0, SEEK_END);
|
||||
off_t fsize = ftello(f);
|
||||
fseeko(f, 0, SEEK_SET);
|
||||
size_t branch_cnt = fsize/(2*sizeof(uint32_t));
|
||||
fread(&coverage_begin, sizeof(uint32_t), 1, f);
|
||||
fread(&coverage_end, sizeof(uint32_t), 1, f);
|
||||
size_t branch_cnt = (fsize-4*2)/(2*4);
|
||||
for (size_t i = 0; i < branch_cnt; i++) {
|
||||
uint32_t from, to;
|
||||
fread(&from, sizeof(uint32_t), 1, f);
|
||||
fread(&to, sizeof(uint32_t), 1, f);
|
||||
if (from >= coverage_begin && from < coverage_end /*&& to < 0x80000000u*/) {
|
||||
if (from >= coverage_begin && from < coverage_end) {
|
||||
from = from - coverage_begin + coverage_offset;
|
||||
branches[from].from_cnt++;
|
||||
}
|
||||
if (to >= coverage_begin && to < coverage_end /*&& from < 0x80000000u*/) {
|
||||
if (to >= coverage_begin && to < coverage_end) {
|
||||
to = to - coverage_begin + coverage_offset;
|
||||
branches[to].to_cnt++;
|
||||
}
|
||||
@ -94,15 +96,13 @@ int is_cond_jump(const char *s) {
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 6) {
|
||||
fprintf(stderr, "usage: covpreproc <listing file> <coverage_begin offset> <coverage_begin address> <coverage_end address> <coverage files ...>\n");
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "usage: covpreproc <listing file> <coverage_begin offset> <coverage files ...>\n");
|
||||
exit(1);
|
||||
}
|
||||
sscanf(argv[2], "%" SCNx32, &coverage_offset);
|
||||
sscanf(argv[3], "%" SCNx32, &coverage_begin);
|
||||
sscanf(argv[4], "%" SCNx32, &coverage_end);
|
||||
|
||||
for (int i = 5; i < argc; i++) {
|
||||
for (int i = 3; i < argc; i++) {
|
||||
read_coverage_file(argv[i]);
|
||||
}
|
||||
|
||||
@ -123,8 +123,10 @@ int main(int argc, char **argv) {
|
||||
unsigned long pos = strtoul(tmp, NULL, 16);
|
||||
size_t total_to = 0, total_from = 0;
|
||||
for (size_t i = 0; i < inst_len; i++) {
|
||||
total_to += branches[pos + i].to_cnt;
|
||||
total_from += branches[pos + i].from_cnt;
|
||||
if (pos + i < coverage_end - coverage_begin + coverage_offset) {
|
||||
total_to += branches[pos + i].to_cnt;
|
||||
total_from += branches[pos + i].from_cnt;
|
||||
}
|
||||
}
|
||||
cur += total_to;
|
||||
if (is_cond) {
|
||||
|
@ -110,8 +110,8 @@ typedef struct {
|
||||
int (*querymedia)(void *userdata, diskmediainfo_t *info) __attribute__((__stdcall__));
|
||||
int (*read)(void *userdata, void *buffer, off_t startsector, size_t *numsectors) __attribute__((__stdcall__));
|
||||
int (*write)(void *userdata, void *buffer, off_t startsector, size_t *numsectors) __attribute__((__stdcall__));
|
||||
int (*flush)(void* userdata) __attribute__((__stdcall__));
|
||||
unsigned int (*adjust_cache_size)(uint32_t suggested_size) __attribute__((__stdcall__));
|
||||
int (*flush)(void *userdata) __attribute__((__stdcall__));
|
||||
unsigned int (*adjust_cache_size)(void *userdata, uint32_t suggested_size) __attribute__((__stdcall__));
|
||||
} diskfunc_t;
|
||||
|
||||
struct disk_t {
|
||||
@ -231,7 +231,6 @@ typedef struct {
|
||||
void kos_init(void);
|
||||
void i40(void);
|
||||
uint32_t kos_time_to_epoch(uint32_t *time);
|
||||
void set_eflags_tf(int x);
|
||||
|
||||
void *disk_add(diskfunc_t *disk, const char *name, void *userdata, uint32_t flags) __attribute__((__stdcall__));
|
||||
void *disk_media_changed(diskfunc_t *disk, int inserted) __attribute__((__stdcall__));
|
||||
|
16
makefile
16
makefile
@ -4,7 +4,7 @@ WARNINGS=-Wall -Wextra -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wre
|
||||
CFLAGS=$(WARNINGS) -g -O0 -D_FILE_OFFSET_BITS=64 -Wno-address-of-packed-member -DNDEBUG -masm=intel
|
||||
CFLAGS_32=$(CFLAGS) -m32
|
||||
LDFLAGS=
|
||||
LDFLAGS_32=-m32
|
||||
LDFLAGS_32=$(LDFLAGS) -m32
|
||||
|
||||
all: umka_shell umka_fuse umka.sym umka.prp umka.lst tags tools/mkdirrange tools/mkfilepattern covpreproc
|
||||
|
||||
@ -12,10 +12,10 @@ covpreproc: covpreproc.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
|
||||
|
||||
umka_shell: umka_shell.o umka.o trace.o trace_lbr.o vdisk.o lodepng.o
|
||||
$(CC) $(LDFLAGS) $(LDFLAGS_32) $^ -o $@ -static
|
||||
$(CC) $(LDFLAGS_32) $^ -o $@ -static
|
||||
|
||||
umka_fuse: umka_fuse.o umka.o vdisk.o
|
||||
$(CC) $(LDFLAGS) $(LDFLAGS_32) $^ -o $@ `pkg-config fuse3 --libs`
|
||||
$(CC) $(LDFLAGS_32) $^ -o $@ `pkg-config fuse3 --libs`
|
||||
|
||||
umka.o umka.fas: umka.asm skin.skn
|
||||
INCLUDE="$(KOLIBRI)/kernel/trunk;$(KOLIBRI)/programs/develop/libraries/libcrash/trunk" $(FASM) $< umka.o -s umka.fas -m 1234567
|
||||
@ -39,19 +39,19 @@ tags: umka.sym
|
||||
fasmtags.py $<
|
||||
|
||||
trace.o: trace.c trace.h trace_lbr.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_32) -c $<
|
||||
$(CC) $(CFLAGS_32) -c $<
|
||||
|
||||
trace_lbr.o: trace_lbr.c trace_lbr.h kolibri.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_32) -c $<
|
||||
$(CC) $(CFLAGS_32) -c $<
|
||||
|
||||
vdisk.o: vdisk.c
|
||||
$(CC) $(CFLAGS) $(CFLAGS_32) -c $<
|
||||
$(CC) $(CFLAGS_32) -c $<
|
||||
|
||||
umka_shell.o: umka_shell.c kolibri.h trace.h syscalls.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_32) -c $< -std=c99 -D_POSIX_C_SOURCE=2
|
||||
$(CC) $(CFLAGS_32) -c $< -std=c99 -D_POSIX_C_SOURCE=2
|
||||
|
||||
umka_fuse.o: umka_fuse.c kolibri.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $< -std=gnu99
|
||||
$(CC) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $< -std=gnu99
|
||||
|
||||
tools/mkdirrange: tools/mkdirrange.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
@ -37,3 +37,11 @@ draw: $(draw_tests)
|
||||
$(UMKA_SHELL) < $*.t > $@
|
||||
@ cmp $@ $<
|
||||
@ if [ -f "$*.ref.png" ]; then cmp $*.out.png $*.ref.png; fi
|
||||
|
||||
coverage:
|
||||
../covpreproc ../umka.lst 0x34 coverage.* > ../umka.cov
|
||||
|
||||
clean:
|
||||
rm -f ???_*.out.{log,png} coverage coverage.*
|
||||
|
||||
.PHONY: clean coverage
|
||||
|
34
trace_lbr.c
34
trace_lbr.c
@ -10,6 +10,12 @@
|
||||
#include <sched.h>
|
||||
#include "kolibri.h"
|
||||
|
||||
#define MSR_IA32_DEBUGCTLMSR 0x1d9
|
||||
#define MSR_IA32_LASTBRANCHFROMIP 0x1db
|
||||
#define MSR_IA32_LASTBRANCHTOIP 0x1dc
|
||||
#define MSR_IA32_LASTINTFROMIP 0x1dd
|
||||
#define MSR_IA32_LASTINTTOIP 0x1de
|
||||
|
||||
int covfd, msrfd;
|
||||
|
||||
uint64_t rdmsr(uint32_t reg)
|
||||
@ -43,8 +49,8 @@ void wrmsr(uint32_t reg, uint64_t data)
|
||||
}
|
||||
|
||||
void handle_sigtrap() {
|
||||
uint64_t from = rdmsr(0x1db);
|
||||
uint64_t to = rdmsr(0x1dc);
|
||||
uint64_t from = rdmsr(MSR_IA32_LASTBRANCHFROMIP);
|
||||
uint64_t to = rdmsr(MSR_IA32_LASTBRANCHTOIP);
|
||||
|
||||
if ((from >= (uintptr_t)coverage_begin && from < (uintptr_t)coverage_end) ||
|
||||
(to >= (uintptr_t)coverage_begin && to < (uintptr_t)coverage_end)) {
|
||||
@ -52,7 +58,21 @@ void handle_sigtrap() {
|
||||
write(covfd, &to, 4);
|
||||
}
|
||||
|
||||
wrmsr(0x1d9, 3);
|
||||
wrmsr(MSR_IA32_DEBUGCTLMSR, 3);
|
||||
}
|
||||
|
||||
void set_eflags_tf(uint32_t tf) {
|
||||
__asm__ __inline__ __volatile__ (
|
||||
"pushfd;"
|
||||
"pop eax;"
|
||||
"shl ecx, 8;" // TF
|
||||
"and eax, ~(1 << 8);"
|
||||
"or eax, ecx;"
|
||||
"push eax;"
|
||||
"popfd"
|
||||
:
|
||||
: "c"(tf)
|
||||
: "eax", "memory");
|
||||
}
|
||||
|
||||
void trace_lbr_begin() {
|
||||
@ -66,7 +86,7 @@ void trace_lbr_begin() {
|
||||
CPU_ZERO(&my_set);
|
||||
CPU_SET(0, &my_set);
|
||||
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
|
||||
wrmsr(0x1d9, 3);
|
||||
wrmsr(MSR_IA32_DEBUGCTLMSR, 3);
|
||||
msrfd = open("/dev/cpu/0/msr", O_RDONLY);
|
||||
if (msrfd < 0) {
|
||||
perror("rdmsr: open");
|
||||
@ -75,12 +95,16 @@ void trace_lbr_begin() {
|
||||
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);
|
||||
void *coverage_begin_addr = &coverage_begin;
|
||||
void *coverage_end_addr = &coverage_end;
|
||||
write(covfd, &coverage_begin_addr, 4);
|
||||
write(covfd, &coverage_end_addr, 4);
|
||||
set_eflags_tf(1);
|
||||
}
|
||||
|
||||
void trace_lbr_end() {
|
||||
set_eflags_tf(0);
|
||||
wrmsr(0x1d9, 0);
|
||||
wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
|
||||
close(msrfd);
|
||||
close(covfd);
|
||||
}
|
||||
|
14
umka.asm
14
umka.asm
@ -19,7 +19,6 @@ public coverage_begin
|
||||
public coverage_end
|
||||
|
||||
public sha3_256_oneshot as 'hash_oneshot'
|
||||
public set_eflags_tf
|
||||
public kos_time_to_epoch
|
||||
public kos_init
|
||||
|
||||
@ -145,19 +144,6 @@ proc sha3_256_oneshot c uses ebx esi edi ebp, _ctx, _data, _len
|
||||
ret
|
||||
endp
|
||||
|
||||
; TODO: move to trace_lbr
|
||||
set_eflags_tf:
|
||||
pushfd
|
||||
pop eax
|
||||
mov ecx, [esp + 4]
|
||||
and ecx, 1
|
||||
shl ecx, 8 ; TF
|
||||
and eax, NOT (1 SHL 8)
|
||||
or eax, ecx
|
||||
push eax
|
||||
popfd
|
||||
ret
|
||||
|
||||
proc kos_time_to_epoch c uses ebx esi edi ebp, _time
|
||||
mov esi, [_time]
|
||||
call fsCalculateTime
|
||||
|
@ -62,14 +62,14 @@ diskfunc_t vdisk_functions = {
|
||||
.read = vdisk_read,
|
||||
.write = vdisk_write,
|
||||
.flush = NULL,
|
||||
.adjust_cache_size = NULL,
|
||||
.adjust_cache_size = vdisk_adjust_cache_size,
|
||||
};
|
||||
char cur_dir[PATH_MAX] = "/";
|
||||
const char *last_dir = cur_dir;
|
||||
bool cur_dir_changed = true;
|
||||
|
||||
char cmd_buf[FGETS_BUF_LEN];
|
||||
int trace;
|
||||
int trace = 0;
|
||||
|
||||
const char *f70_status_name[] = {
|
||||
"success",
|
||||
@ -974,7 +974,7 @@ void *run_test(const char *infile_name) {
|
||||
usage();
|
||||
return NULL;
|
||||
}
|
||||
strcpy(last_dot, ".out");
|
||||
strcpy(last_dot, ".out.log");
|
||||
infile = fopen(infile_name, "r");
|
||||
outfile = fopen(outfile_name, "w");
|
||||
if (!infile || !outfile) {
|
||||
|
7
vdisk.c
7
vdisk.c
@ -60,3 +60,10 @@ int vdisk_querymedia(void *userdata, diskmediainfo_t *minfo) {
|
||||
minfo->capacity = vdisk->sect_cnt;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
__attribute__((__stdcall__))
|
||||
unsigned int vdisk_adjust_cache_size(void *userdata, unsigned int suggested_size) {
|
||||
(void)userdata;
|
||||
(void)suggested_size;
|
||||
return 64*1024;
|
||||
}
|
||||
|
3
vdisk.h
3
vdisk.h
@ -19,4 +19,7 @@ int vdisk_write(void *userdata, void *buffer, off_t startsector, size_t *numsect
|
||||
__attribute__((__stdcall__))
|
||||
int vdisk_querymedia(void *userdata, diskmediainfo_t *minfo);
|
||||
|
||||
__attribute__((__stdcall__))
|
||||
unsigned int vdisk_adjust_cache_size(void *userdata, unsigned int suggested_size);
|
||||
|
||||
#endif // VDISK_H_INCLUDED
|
||||
|
Loading…
Reference in New Issue
Block a user