use core::arch::asm;
const VG_MEMCHECK_BASE: u32 = 0x4D43_0000;
const VG_USERREQ_MAKE_MEM_UNDEFINED: u32 = VG_MEMCHECK_BASE + 1;
const VG_USERREQ_MAKE_MEM_DEFINED: u32 = VG_MEMCHECK_BASE + 2;
#[inline(always)]
unsafe fn client_request(request: u32, a1: usize, a2: usize) -> usize {
let args: [usize; 6] = [request as usize, a1, a2, 0, 0, 0];
do_client_request(0, &args)
}
#[cfg(target_arch = "x86_64")]
#[inline(always)]
unsafe fn do_client_request(default: usize, args: &[usize; 6]) -> usize {
let mut result: usize = default;
asm!(
"rol rdi, 3",
"rol rdi, 13",
"rol rdi, 61",
"rol rdi, 51",
"xchg rbx, rbx",
in("rax") args.as_ptr(),
inout("rdx") result,
lateout("rdi") _,
options(nostack),
);
result
}
#[cfg(target_arch = "aarch64")]
#[inline(always)]
unsafe fn do_client_request(default: usize, args: &[usize; 6]) -> usize {
let mut result: usize;
asm!(
"mov x3, {default}",
"mov x4, {args_ptr}",
"ror x12, x12, #3",
"ror x12, x12, #13",
"ror x12, x12, #51",
"ror x12, x12, #61",
"orr x10, x10, x10",
"mov {result}, x3",
default = in(reg) default,
args_ptr = in(reg) args.as_ptr(),
result = out(reg) result,
out("x3") _,
out("x4") _,
out("x12") _,
options(nostack),
);
result
}
#[inline(always)]
pub(super) unsafe fn make_mem_undefined(ptr: *const u8, len: usize) {
client_request(VG_USERREQ_MAKE_MEM_UNDEFINED, ptr as usize, len);
}
#[inline(always)]
pub(super) unsafe fn make_mem_defined(ptr: *const u8, len: usize) {
client_request(VG_USERREQ_MAKE_MEM_DEFINED, ptr as usize, len);
}