lib/isa/src/root.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 //! The package reads x86-64 machine code and describes the first instruction in
 2 //! a byte slice as a structured value, calling no allocator. A caller walks a
 3 //! stream of instructions by advancing past the length each decoded instruction
 4 //! reports.
 5 //!
 6 //! A verifier has to know which instructions a program holds before the program
 7 //! runs, and an executor has to know what each instruction reads and writes,
 8 //! and both must read the same bytes the same way.
 9 //!
10 //! x86-64 instructions vary in length up to 15 bytes, and optional prefix bytes
11 //! change how the rest is read, so every prefix combination has to be
12 //! recognized or refused. An allow list needs a compact, stable identity for
13 //! each kind of instruction, one that does not change when a register or a
14 //! constant does. What an instruction does to flags and memory is a question of
15 //! execution, which a decoder that stops at the encoding cannot settle.
16 //!
17 //! The
18 //! [Intel Software Developer's Manuals](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html)
19 //! define the x86-64 instruction format, and the decoder follows that format:
20 //! prefix bytes, a one-byte opcode table and a second table reached through the
21 //! escape byte 0x0F, a byte that selects registers or a memory address form
22 //! with an optional scaled-index byte, then displacement and immediate bytes,
23 //! at most 15 bytes in all.
24 //!
25 //! The decoder covers the instructions it models and returns a named error for
26 //! the rest, such as `error.UnsupportedOpcode` or
27 //! `error.UnsupportedAddressSize`. The decoder describes each instruction by
28 //! its shape as one 64-bit value (a *form*), and consumers compare that value
29 //! against allow lists, such as a kernel policy table searched by that value
30 //! and a loader that checks each decoded instruction against a recorded one.
31 //! That summary records the prefix combination, the opcode table and byte, the
32 //! operand width, the addressing mode, the role and access of each operand, and
33 //! for `int` its vector byte. That value leaves out register numbers,
34 //! displacements and immediate values, so a consumer that needs the exact bytes
35 //! checks them separately. Each decoded instruction also names what it does as
36 //! a numbered identity (an *operation*), such as `add` or `jne`, each belonging
37 //! to one family such as arithmetic or control. The numbers 0 to 48 are stored
38 //! in kernel policy, so new identities take new numbers and existing ones never
39 //! move. The decoded value reports operands, their read and write access, and
40 //! the registers an instruction uses implicitly, and the execution backends
41 //! keep the effects on flags and memory for themselves.
42 
43 pub const x86 = @import("x86/root.zig");