aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md33
1 files changed, 22 insertions, 11 deletions
diff --git a/README.md b/README.md
index c423c0d..e19b8a7 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,38 @@
## yaxpeax-x86
-x86 decoders implemented as part of the yaxpeax project it is a mazing projec.
+x86 decoders implemented as part of the yaxpeax project, implementing traits provided by `yaxpeax-arch`.
-`yaxpeax-x86` implements traits provided by `yaxpeax-arch`, which are likely how you want to use this library from Rust. included in the `ffi/` directory is a repackaging of `yaxpeax-x86` suitable for use by non-Rust callers, such as C or C++.
+Rust users of this library will either want to use the [quick and dirty APIs], or more generic decode interfaces from `yaxpeax-arch` - appropriate when mixing `yaxpeax-x86` usage with other `yaxpeax` decoders, such as `yaxpeax-arm`. examples of both styles are provided [in the documentation](link).
+
+the `ffi/` directory provides a repackaging of `yaxpeax-x86` suitable for use by non-Rust callers, such as C or C++. see the `examples` directory for FFI usage of this library.
### features
* `#[no_std]`
-* configurable choice of permitted instruction set extensions
+* configurable instruction set extensions
* very fast
* pretty small?
### `#[no_std]`
-the decoders provided by `yaxpeax-x86` are designed to be usable in a `no_std` setting, and does so by default. to build `yaxpeax_x86` decoders in `no_std` you'll want to set `default-features = false` as with many other `no_std` Rust crates. serde currently (though it doesn't seem _necessarily_?) relies on `std`, as well as the `colors` feature to render instructions with default (eg terminal-friendly) syntax highlighting.
+the decoders provided by `yaxpeax-x86` are designed to be usable in a `no_std` setting, and does so by default. to build `yaxpeax_x86` without `std`, add the parameter `default-features = false` to your `yaxpeax-x86` dependency; the [ffi packaging] of `yaxpeax_x86` does this and builds without the Rust standard library as well. serde can be enabled without `std`, but json serialization/deserialization [need some careful attention](https://serde.rs/no-std.html) in that mode. as well as the `colors` feature to render instructions with default (eg terminal-friendly) syntax highlighting.
### instruction set extensions
`yaxpeax-x86` decoders provide the option to specify what [instruction set extensions](http://git.iximeow.net/yaxpeax-x86/tree/src/long_mode/mod.rs#n1297) are eligible when decoding, to support decoding x86 instructions as understood by a particular microarchitecture. the default impls of decoders in `yaxpeax_x86` take an optimistsic approach to decoding and assumes all feature sets are available, as well as accepting both intel-specific and amd-specific quirks around undefined encodings.
+yaxpeax-x86 decodes long-mode (`amd64`/`x86_64`), protected-mode (`x86`/`x86_32`), and real-mode (`x86_16`) instructions. the most part, ISA extensions decode equivalently across modes; this is the full list of extensions that are supported:
+
+`3dnow`\*, `sse`\*, `sse2`\*, `sse3`, `ssse3`, `sse4.1`, `sse4.2`, `sse4a`, `avx`, `avx2`, `avx512`\*\*, `syscall`, `cmpxchg16b`, `fma3`, `aesni`, `popcnt`, `rdrand`, `xsave`, `sgx`, `monitor`, `movbe`, `sgx`, `bmi1`, `bmi2`, `invpcid`, `mpx`, `adx`, `clflushopt`, `pcommit`, `sha`, `gfni`, `pclmulqdq`, `rdtscp`, `abm`, `xop`, `skinit`, `tbm`, `svm`, `f16c`, `fma4`, `tsx`, `enqcmd`\*\*\*, `uintr`\*\*\*, `keylocker`\*\*\*, `store_direct`\*\*\*, `cet`\*\*\*
+
+\*: `3dnow`, `sse`, and `sse2` are non-optional in `x86_64`, so it is not permitted to construct a decoder that rejects them. `x86_32` and `x86_16` could have features to reject these instructions for true `8086` and `i386` compatibility, but currently do not.
+
+\*\*: `avx512` is fully supported, but decoders rejecting subgroups of the `avx512` family are not. if you need granular `avx512` compatibility controls, please file an issue.
+
+\*\*\*: i ran out of space for feature bits. `InstDecoder` is currently a `u64` and all 64 bits are used for x86 features mapping to `cpuid` bits. supporting these as optional instructions would require growing this to a pair of `u64`. since the typical case is to decode everything, these are decoded regardless of `InstDecoder` settings. growing `InstDecoder` to an `u128` is likely acceptable, but has not yet been profiled.
+
### very fast
-by the in-repo benchmark, `yaxpeax_x86::long_mode` decodes `x86_64` instructions at anywhere between 60 million instructions per second to just shy of 100 million instructions per second, depending on hardware and distribution of instructions being decoded.
+when hooked up to [`disas-bench`](https://github.com/iximeow/disas-bench#results), `yaxpeax_x86::long_mode` has shown roughly 250mb/s decode throughput and on most hardware is the fastest software x86 decoder available.
-when hooked up to [`disas-bench`](https://github.com/iximeow/disas-bench#results), `yaxpeax_x86::long_mode` has shown roughly 175mb/s decode throughput and on most hardware is the fastest software x86 decoder available.
+while there is an in-repo benchmark, i've decided it's so unrealistic as to be unuseful, and prefer `disas-bench` until it can be made more informative..
### pretty small?
`yaxpeax_x86::long_mode` is expected to be around 20kb of code and data. currently a stripped static build of `ffi/` takes a bit more space - around 130kb. instruction rendering is currently non-optional, and is a significant amount of `.text` size. data tables are larger than anticipated, and it's currently an open question if they can be reduced down, or the size target of `yaxpeax_x86::long_mode` should be raised.
@@ -35,10 +47,9 @@ the canonical copy of `yaxpeax-x86` is at [https://git.iximeow.net/yaxpeax-x86/]
### ! user beware !
* `yaxpeax-x86` will, but does not yet, have a decoder for real-mode `x86`. it is strongly recommended to use `<yaxpeax_x86::protected_mode::Arch as Arch>::Instruction` and similar type aliases, rather than using struct and operand types directly. user beware!
-* avx512 is not yet supported. user beware!
-* avx256 support is questionable. user beware!
-* `ffi/` exists, and is enough to get a bare minimum decoding and string representation of an instruction, but is not as fully populated as a non-rust caller might like. user beware!
-* `yaxpeax_x86` makes regular use of `unsafe { unreachable_unchecked(); }` and occasional use of `unsafe { _.get_unchecked() }`. while these are, to the author's knowledge, unreachable, this is audited and updated on a best-effort basis. eventually, `yaxpeax-x86` should grow a fuzzing suite that build with these cases checked and panicking.
+
+### unsafety
+`yaxpeax_x86` makes regular use of `unsafe { unreachable_unchecked(); }` and occasional use of `unsafe { _.get_unchecked() }` for purely performance reasons. `yaxpeax_x86` is fuzzed via `mishegos` and has passed multiple days of fuzzing without issue.
### changelog
a changelog across crate versions is maintained in the `CHANGELOG` file located in the repo, as well as [online](https://git.iximeow.net/yaxpeax-x86/tree/CHANGELOG).
@@ -47,4 +58,4 @@ a changelog across crate versions is maintained in the `CHANGELOG` file located
[`iced`](https://github.com/0xd4d/iced) is another very good `x86_64` decoder, also written in rust. it provides additional information about instruction semantics as part of the crate, as well as the ability to re-encode instructions.
-[`disas-bench`](https://github.com/athre0z/disas-bench), a handy benchmark of several `x86_64` decoders, easily extended to compare with `yaxpeax-x86` as well.
+[`disas-bench`](https://github.com/athre0z/disas-bench), a handy benchmark of several `x86_64` decoders including `yaxpeax-x86`.