#include <sys/systm.h>
#include <sys/sdt.h>
#include <machine/md_var.h>
bool
sdt_tracepoint_valid(uintptr_t patchpoint, uintptr_t target)
{
int64_t offset;
if (patchpoint == target ||
(patchpoint & 3) != 0 || (target & 3) != 0)
return (false);
offset = target - patchpoint;
if (offset < -(1 << 26) || offset > (1 << 26))
return (false);
return (true);
}
void
sdt_tracepoint_patch(uintptr_t patchpoint, uintptr_t target)
{
uint32_t instr;
KASSERT(sdt_tracepoint_valid(patchpoint, target),
("%s: invalid tracepoint %#jx -> %#jx",
__func__, (uintmax_t)patchpoint, (uintmax_t)target));
instr = ((target - patchpoint) & 0x7fffffful) | 0x48000000;
memcpy((void *)patchpoint, &instr, sizeof(instr));
__syncicache((void *)patchpoint, sizeof(instr));
}
void
sdt_tracepoint_restore(uintptr_t patchpoint)
{
uint32_t instr;
instr = 0x60000000;
memcpy((void *)patchpoint, &instr, sizeof(instr));
__syncicache((void *)patchpoint, sizeof(instr));
}