#![cfg(feature = "starry-kcov")]
use core::arch::naked_asm;
use ax_percpu::def_percpu;
#[def_percpu]
static IN_KCOV_TRACE: u8 = 0;
#[used]
pub static mut KCOV_GLOBAL_GATE: u8 = 0;
unsafe extern "C" {
fn kcov_trace_pc_impl(pc: u64);
}
#[cfg(target_arch = "x86_64")]
#[unsafe(no_mangle)]
#[unsafe(naked)]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc() {
naked_asm!(
"cmp byte ptr [rip + {global}], 0",
"je 2f",
"cmp byte ptr gs:[offset {guard}], 0",
"jne 1f",
"mov byte ptr gs:[offset {guard}], 1",
"mov rdi, [rsp]",
"call {impl}",
"mov byte ptr gs:[offset {guard}], 0",
"1:",
"2:",
"ret",
global = sym KCOV_GLOBAL_GATE,
guard = sym __PERCPU_IN_KCOV_TRACE,
impl = sym kcov_trace_pc_impl,
);
}
#[cfg(target_arch = "aarch64")]
#[unsafe(no_mangle)]
#[unsafe(naked)]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc() {
naked_asm!(
"adrp x16, {global}",
"ldrb w17, [x16, #:lo12:{global}]",
"cbz w17, 2f",
"mrs x16, tpidr_el1",
"movz x17, #:abs_g0_nc:{guard}",
"add x16, x16, x17",
"ldrb w17, [x16]",
"cbnz w17, 1f",
"mov w17, #1",
"strb w17, [x16]",
"str x30, [sp, #-16]!",
"mov x0, x30",
"bl {impl}",
"ldr x30, [sp], #16",
"mrs x16, tpidr_el1",
"movz x17, #:abs_g0_nc:{guard}",
"add x16, x16, x17",
"strb wzr, [x16]",
"1:",
"2:",
"ret",
global = sym KCOV_GLOBAL_GATE,
guard = sym __PERCPU_IN_KCOV_TRACE,
impl = sym kcov_trace_pc_impl,
);
}
#[cfg(target_arch = "riscv64")]
#[unsafe(no_mangle)]
#[unsafe(naked)]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc() {
naked_asm!(
"1: auipc t0, %pcrel_hi({global})",
"addi t0, t0, %pcrel_lo(1b)",
"lb t1, 0(t0)",
"beqz t1, 2f",
"lui t0, %hi({guard})",
"add t0, t0, gp",
"addi t0, t0, %lo({guard})",
"lb t1, 0(t0)",
"bnez t1, 1f",
"li t1, 1",
"sb t1, 0(t0)",
"addi sp, sp, -16",
"sd ra, 0(sp)",
"mv a0, ra",
"call {impl}",
"ld ra, 0(sp)",
"addi sp, sp, 16",
"lui t0, %hi({guard})",
"add t0, t0, gp",
"addi t0, t0, %lo({guard})",
"sb zero, 0(t0)",
"1:",
"2:",
"ret",
global = sym KCOV_GLOBAL_GATE,
guard = sym __PERCPU_IN_KCOV_TRACE,
impl = sym kcov_trace_pc_impl,
);
}
#[cfg(target_arch = "loongarch64")]
#[unsafe(no_mangle)]
#[unsafe(naked)]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc() {
naked_asm!(
"pcalau12i $t0, %pc_hi20({global})",
"addi.d $t0, $t0, %pc_lo12({global})",
"ld.b $t1, $t0, 0",
"beqz $t1, 2f",
"lu12i.w $t0, %abs_hi20({guard})",
"ori $t0, $t0, %abs_lo12({guard})",
"add.d $t0, $t0, $r21",
"ld.b $t1, $t0, 0",
"bnez $t1, 1f",
"ori $t1, $zero, 1",
"st.b $t1, $t0, 0",
"addi.d $sp, $sp, -16",
"st.d $ra, $sp, 0",
"ori $a0, $ra, 0",
"bl {impl}",
"ld.d $ra, $sp, 0",
"addi.d $sp, $sp, 16",
"lu12i.w $t0, %abs_hi20({guard})",
"ori $t0, $t0, %abs_lo12({guard})",
"add.d $t0, $t0, $r21",
"st.b $zero, $t0, 0",
"1:",
"2:",
"jirl $zero, $ra, 0",
global = sym KCOV_GLOBAL_GATE,
guard = sym __PERCPU_IN_KCOV_TRACE,
impl = sym kcov_trace_pc_impl,
);
}