[Development report #7] Improve the kinst DTrace provider

From: Christos Margiolis <christos_at_freebsd.org>
Date: Mon, 10 Apr 2023 18:42:18 UTC
The past few days I've been working on the forthcoming RISC-V port of
kinst.

Tracing of individual instructions in kinst so far (i.e in amd64) works
by using a trampoline which contains the actual instruction, followed by
an unconditional jump back to the next instruction so that we can resume
execution. In RISC-V however this turns out to not really be possible,
because we cannot encode large displacement values in a single
instruction in order to form a far jump [1]. To compensate for this, the
RISC-V trampoline contains the instruction, followed by an EBREAK
(breakpoint) instruction. kinst_invop() is able to detect if the
breakpoint was triggered by the trampoline, where in this case, it
manually sets the program counter to the next instruction, instead of
using a jump.

So far only instructions that do not address memory can be traced
without problems. Since the displacement issue I mentioned above
re-appears here as well, instructions that need modification [2] will
most likely not use the trampoline at all, and be emulated in software
instead, like we do in amd64 kinst for call instructions.

[1] Trampoline addresses are located above the kernel base address,
    which can be several MBs away from the instruction we are tracing.
[2] Some instructions need modification, that is, for instructions that
    use relative addressing (e.g PC-relative ones), we have to
    recalculate the displacement to be relative to the trampoline
    address.