diff --git a/libafl/src/bolts/cpu.rs b/libafl/src/bolts/cpu.rs index 42d26448ea..eb2c4eea38 100644 --- a/libafl/src/bolts/cpu.rs +++ b/libafl/src/bolts/cpu.rs @@ -1,6 +1,9 @@ //! Architecture agnostic processor features -#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] +#[cfg(target_arch = "aarch64")] +use core::arch::asm; + +#[cfg(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")))] use crate::bolts::current_nanos; // TODO: Add more architectures, using C code, see @@ -26,13 +29,28 @@ pub fn read_time_counter() -> u64 { } } +/// Read a timestamp for measurements +/// +/// Fetches the counter-virtual count register +/// as we do not need to remove the cntvct_el2 offset. +#[cfg(target_arch = "aarch64")] +#[must_use] +pub fn read_time_counter() -> u64 { + let v: u64 = 0; + unsafe { + // TODO pushing a change in core::arch::aarch64 ? + asm!("mrs {v}, cntvct_el0", v = out(reg) _); + } + v +} + /// Read a timestamp for measurements. /// /// This function is a wrapper around different ways to get a timestamp, fast. /// In this way, an experiment only has to /// change this implementation rather than every instead of [`read_time_counter`] /// On unsupported architectures, it's falling back to normal system time, in millis. -#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] +#[cfg(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")))] #[must_use] pub fn read_time_counter() -> u64 { current_nanos()