use crate::{
backend::ISA,
compiler::compiled_code::{CallSite, Symbol},
};
use super::X64;
pub(super) struct X64StaticCallSite {
symbol: Symbol,
offset: usize,
start: *const u8,
}
unsafe impl Send for X64StaticCallSite {}
unsafe impl Sync for X64StaticCallSite {}
impl X64StaticCallSite {
pub fn new(symbol: Symbol, offset: usize) -> Self {
Self {
symbol,
offset,
start: 0 as _,
}
}
pub fn set_start_address(&mut self, start: *const u8) {
self.start = start;
}
}
impl CallSite for X64StaticCallSite {
fn symbol(&self) -> &Symbol {
&self.symbol
}
fn patch(&self, addr: *const u8) {
unsafe {
let return_address = self.start.add(self.offset);
let slot = self.start.add(self.offset - 4) as *mut i32;
let rel_offset: i32 = addr.offset_from(return_address) as i32;
std::ptr::write_unaligned(slot, rel_offset);
X64::flush_cache(slot as *const u8, 4)
}
}
}