cmplog runtime

This commit is contained in:
Andrea Fioraldi 2021-04-12 15:26:32 +02:00
parent 022c12568b
commit 5846aa2292
5 changed files with 237 additions and 0 deletions

View File

@ -10,6 +10,7 @@ pcguard_edges = []
pcguard_hitcounts = []
libfuzzer = []
value_profile = []
cmplog = []
pcguard = ["pcguard_hitcounts"]
[build-dependencies]

View File

@ -29,6 +29,15 @@ fn main() {
.file(_src_dir.join("value_profile.c"))
.compile("value_profile");
}
#[cfg(feature = "cmplog")]
{
println!("cargo:rerun-if-changed=src/cmplog.c");
cc::Build::new()
.file(_src_dir.join("cmplog.c"))
.compile("cmplog");
}
println!("cargo:rustc-link-search=native={}", &out_dir);

185
libafl_targets/src/cmplog.c Normal file
View File

@ -0,0 +1,185 @@
#include <stdint.h>
#define CMPLOG_MAP_W 65536
#define CMPLOG_MAP_H 32
#define CMPLOG_KIND_INS 0
#define CMPLOG_KIND_RTN 1
typedef struct CmpLogHeader {
uint16_t hits;
uint8_t shape;
uint8_t kind;
} CmpLogHeader;
typedef struct CmpLogOperands {
uint64_t v0;
uint64_t v1;
} CmpLogOperands;
typedef struct CmpLogMap {
CmpLogHeader headers[CMPLOG_MAP_W];
CmpLogOperands operands[CMPLOG_MAP_W][CMPLOG_MAP_H];
} CmpLogMap;
extern CmpLogMap libafl_cmplog_map;
extern uint8_t libafl_cmplog_enabled;
#if defined(__APPLE__)
#pragma weak __sanitizer_cov_trace_const_cmp1 = __sanitizer_cov_trace_cmp1
#pragma weak __sanitizer_cov_trace_const_cmp2 = __sanitizer_cov_trace_cmp2
#pragma weak __sanitizer_cov_trace_const_cmp4 = __sanitizer_cov_trace_cmp4
#pragma weak __sanitizer_cov_trace_const_cmp8 = __sanitizer_cov_trace_cmp8
#else
void __sanitizer_cov_trace_const_cmp1(uint8_t arg1, uint8_t arg2) __attribute__((alias("__sanitizer_cov_trace_cmp1")));
void __sanitizer_cov_trace_const_cmp2(uint16_t arg1, uint16_t arg2)
__attribute__((alias("__sanitizer_cov_trace_cmp2")));
void __sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2)
__attribute__((alias("__sanitizer_cov_trace_cmp4")));
void __sanitizer_cov_trace_const_cmp8(uint64_t arg1, uint64_t arg2)
__attribute__((alias("__sanitizer_cov_trace_cmp8")));
#endif
void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2) {
if (!libafl_cmplog_enabled) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1;
uint16_t hits;
if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) {
libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS;
libafl_cmplog_map.headers[k].hits = 1;
libafl_cmplog_map.headers[k].shape = 1;
hits = 0;
} else {
hits = libafl_cmplog_map.headers[k].hits++;
if (libafl_cmplog_map.headers[k].shape < 1) {
libafl_cmplog_map.headers[k].shape = 1;
}
}
hits &= CMPLOG_MAP_H - 1;
libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1;
libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2;
}
void __sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2) {
if (!libafl_cmplog_enabled) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1;
uint16_t hits;
if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) {
libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS;
libafl_cmplog_map.headers[k].hits = 1;
libafl_cmplog_map.headers[k].shape = 2;
hits = 0;
} else {
hits = libafl_cmplog_map.headers[k].hits++;
if (libafl_cmplog_map.headers[k].shape < 2) {
libafl_cmplog_map.headers[k].shape = 2;
}
}
hits &= CMPLOG_MAP_H - 1;
libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1;
libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2;
}
void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) {
if (!libafl_cmplog_enabled) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1;
uint16_t hits;
if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) {
libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS;
libafl_cmplog_map.headers[k].hits = 1;
libafl_cmplog_map.headers[k].shape = 4;
hits = 0;
} else {
hits = libafl_cmplog_map.headers[k].hits++;
if (libafl_cmplog_map.headers[k].shape < 4) {
libafl_cmplog_map.headers[k].shape = 4;
}
}
hits &= CMPLOG_MAP_H - 1;
libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1;
libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2;
}
void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2) {
if (!libafl_cmplog_enabled) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1;
uint16_t hits;
if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) {
libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS;
libafl_cmplog_map.headers[k].hits = 1;
libafl_cmplog_map.headers[k].shape = 8;
hits = 0;
} else {
hits = libafl_cmplog_map.headers[k].hits++;
if (libafl_cmplog_map.headers[k].shape < 8) {
libafl_cmplog_map.headers[k].shape = 8;
}
}
hits &= CMPLOG_MAP_H - 1;
libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1;
libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2;
}
void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
if (!libafl_cmplog_enabled) return;
uint8_t shape = (uint8_t)cases[1];
if (shape) {
shape /= 8;
}
for (uint64_t i = 0; i < cases[0]; i++) {
uintptr_t k = (uintptr_t)__builtin_return_address(0) + i;
k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1;
uint16_t hits;
if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) {
libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS;
libafl_cmplog_map.headers[k].hits = 1;
libafl_cmplog_map.headers[k].shape = shape;
hits = 0;
} else {
hits = libafl_cmplog_map.headers[k].hits++;
if (libafl_cmplog_map.headers[k].shape < shape) {
libafl_cmplog_map.headers[k].shape = shape;
}
}
hits &= CMPLOG_MAP_H - 1;
libafl_cmplog_map.operands[k][hits].v0 = val;
libafl_cmplog_map.operands[k][hits].v1 = cases[i + 2];
}
}

View File

@ -0,0 +1,36 @@
// TODO compile time flag
pub const CMPLOG_MAP_W: usize = 65536;
pub const CMPLOG_MAP_H: usize = 32;
pub const CMPLOG_MAP_SIZE: usize = CMPLOG_MAP_W * CMPLOG_MAP_H;
pub const CMPLOG_KIND_INS: u8 = 0;
pub const CMPLOG_KIND_RTN: u8 = 1;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CmpLogHeader {
hits: u16,
shape: u8,
kind: u8,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CmpLogOperands(u64, u64);
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CmpLogMap {
headers: [CmpLogHeader; CMPLOG_MAP_W],
operands: [[CmpLogOperands; CMPLOG_MAP_H]; CMPLOG_MAP_W],
}
#[no_mangle]
pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap { headers: [CmpLogHeader {hits: 0, shape: 0, kind: 0}; CMPLOG_MAP_W], operands: [[CmpLogOperands(0, 0); CMPLOG_MAP_H]; CMPLOG_MAP_W] };
pub use libafl_cmplog_map as CMPLOG_MAP;
#[no_mangle]
pub static mut libafl_cmplog_enabled: u8 = 0;
pub use libafl_cmplog_enabled as CMPLOG_ENABLED;

View File

@ -14,3 +14,9 @@ pub use value_profile::*;
pub mod libfuzzer;
#[cfg(feature = "libfuzzer")]
pub use libfuzzer::*;
#[cfg(feature = "cmplog")]
pub mod cmplog;
#[cfg(feature = "cmplog")]
pub use cmplog::*;