use std::sync::atomic::{AtomicU32, AtomicU8, Ordering};
pub const MAP_SIZE: usize = 1 << 16;
static MAP: [AtomicU8; MAP_SIZE] = [const { AtomicU8::new(0) }; MAP_SIZE];
static NEXT_GUARD: AtomicU32 = AtomicU32::new(1);
pub fn reset() {
for b in MAP.iter() {
b.store(0, Ordering::Relaxed);
}
}
pub fn snapshot(out: &mut Vec<u8>) {
out.clear();
out.extend(MAP.iter().map(|b| b.load(Ordering::Relaxed)));
}
pub fn guards() -> u32 {
NEXT_GUARD.load(Ordering::Relaxed) - 1
}
#[no_mangle]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(start: *mut u32, stop: *mut u32) {
if start.is_null() || start == stop {
return;
}
unsafe {
if *start != 0 {
return; }
let mut p = start;
while p < stop {
*p = NEXT_GUARD.fetch_add(1, Ordering::Relaxed);
p = p.add(1);
}
}
}
#[no_mangle]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard(guard: *mut u32) {
let g = unsafe { *guard } as usize;
if g != 0 {
let b = &MAP[g & (MAP_SIZE - 1)];
b.store(b.load(Ordering::Relaxed).wrapping_add(1), Ordering::Relaxed);
}
}