Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
bbdf78c
display opt: mem size labels and minor segment reporting changes
iximeow Apr 2, 2024
27c0d46
swap test order for segment override applicability
iximeow Apr 2, 2024
3291884
display: gate rep printing with a simpler check
iximeow Apr 2, 2024
8b79d59
lets see how a visitor for operands works out here...
iximeow Apr 2, 2024
ed4f238
less write, more write_str
iximeow Apr 2, 2024
050bc1c
display: remove some pointless checks
iximeow Apr 2, 2024
214da3d
use a bit of Opcode to indicate rep/repne applicability
iximeow Jun 13, 2024
fe2917b
adapting contextualize_intel to use new operand visitor stuff
iximeow Jun 16, 2024
ead58f6
commit unshippable wildly unsafe asm-filled printing code
iximeow Jun 16, 2024
2df5d55
move to shared (safe) impl of RelativeBranchPrinter
iximeow Jun 16, 2024
6f03fac
remove branch better handled elsewhere
iximeow Jun 16, 2024
7ab69f6
use less of core::fmt, write by hand
iximeow Jun 16, 2024
0399548
might be an ok way to redesign colorization....
iximeow Jun 17, 2024
1f18a96
add token spans for some registers
iximeow Jun 17, 2024
0e99d94
enough infratructure to avoid bounds checks, at incredible user cost
iximeow Jun 18, 2024
2ac7935
figuring out how to handle short variable-size strings
iximeow Jun 18, 2024
00dc2b6
helper to clear BigEnoughString
iximeow Jun 18, 2024
4af752a
a few more accurate hints
iximeow Jun 18, 2024
49f5472
less integer formatting in operands
iximeow Jun 18, 2024
758ddc6
move away from fmt for visit_i64 and displacements too
iximeow Jun 18, 2024
4142a4a
move non-avx512 operand printing away from fmt
iximeow Jun 18, 2024
53012e2
mem size strings are all 7b or less
iximeow Jun 18, 2024
166695d
write_fixed_size impls for string and BigEnoughString
iximeow Jun 18, 2024
4fb6542
actually use small-string specializations when available
iximeow Jun 18, 2024
754e0da
looks like that becomes memcpy, not ideal
iximeow Jun 18, 2024
9314571
avoid intermediate buffer and copy of hex-formatted ints
iximeow Jun 18, 2024
bebba5a
slightly more centralized hex formatting
iximeow Jun 19, 2024
514586f
write_fixed_size really should always be inlined...
iximeow Jun 19, 2024
0717863
visit_disp is called in only two places, is tiny..
iximeow Jun 19, 2024
afc361c
use get_kinda_unchecked for mem size strings
iximeow Jun 19, 2024
95c3f48
use specialized write helpers for register labels
iximeow Jun 19, 2024
8de036c
use specialized printers for immediate operands
iximeow Jun 19, 2024
1506b8f
use hex printer helpers for relative offsets too
iximeow Jun 19, 2024
eff863b
whats it do without the unused colors parameter
iximeow Jun 19, 2024
2475794
move avx512 operand printing off of fmt
iximeow Jun 19, 2024
cbdfa84
inline the write u8/u32 helpers, lets see what that does
iximeow Jun 19, 2024
89838f6
unreachable panics for impossible op_nr. clean this up though..
iximeow Jun 19, 2024
e904f61
try grouping characters printed with or without segment prefixes
iximeow Jun 19, 2024
d91b2d1
more unused arguments
iximeow Jun 19, 2024
1dc7462
make write_2 work again for comparison (kinda)
iximeow Jun 19, 2024
cc6f7ca
helpers for those i8/u8 immediates too
iximeow Jun 19, 2024
6b0a7aa
configurable inlining to help with opts
iximeow Jun 19, 2024
f6ad0a9
hint better about codegen for contextualize_intel
iximeow Jun 19, 2024
85700ee
write_u64 helpers
iximeow Jun 19, 2024
49e910b
more profiling outlining
iximeow Jun 19, 2024
5554860
hoist set_len calls to have fewer live values
iximeow Jun 19, 2024
2e7bdee
write_2 did its job, seem to have reaped all that can be reaped
iximeow Jun 19, 2024
1b65f5b
clean up warnings, scope unsafe blocks better
iximeow Jun 19, 2024
19bebd1
visit_disp is only outlined for bad reasons
iximeow Jun 19, 2024
8b1677e
dedup mem size prefix printing
iximeow Jun 19, 2024
4a01c5c
no more fmt in display code, remove more dead struct fields
iximeow Jun 19, 2024
8221d7c
more warning cleanup
iximeow Jun 19, 2024
55a64ff
better testing for alternate sinks, fix hex formatting bug....
iximeow Jun 19, 2024
89b8aee
starting to get new DisplaySink stuff ready to extract...
iximeow Jun 20, 2024
3c8271a
slightly simpler (?) write_u* impls
iximeow Jun 20, 2024
70f7673
swap printed size check and lzcnt
iximeow Jun 20, 2024
e39d6b5
separate out display code further, reword comments on InstructionText…
iximeow Jun 21, 2024
d16cc79
things compile again, add a few more caution signs around Instruction…
iximeow Jun 21, 2024
347042c
extract reusable display bits into yaxpeax-arch, add a visitor fn to …
iximeow Jun 22, 2024
bebdead
NoColorsSink has a decent name now
iximeow Jun 22, 2024
4c1f3c8
add more conditional inlining for 32-bit and 16-bit decoders
iximeow Jun 23, 2024
931ad9b
InstructionTextBuffer is only present with alloc (new crate flag)
iximeow Jun 23, 2024
42f9eed
port opcode helpers and reordering to 32-bit and 16-bit decoders
iximeow Jun 23, 2024
df67ba2
actually use new can_rep in 32b and 16b modes
iximeow Jun 23, 2024
e692829
actually use new can_lock in 32b and 16b modes
iximeow Jun 23, 2024
f951ccb
centralize unsafe claims and better validate
iximeow Jun 23, 2024
22a7e97
adapt OperandVisitor to protected mode too
iximeow Jun 23, 2024
eec945b
fix AbsoluteFarAddress being tagged as a memory operand
iximeow Jun 23, 2024
b121313
adapt the rest of formating changes to protected_mode
iximeow Jun 23, 2024
2252844
adapt OperandVisitor and related to real_mode
iximeow Jun 23, 2024
949aa2e
fix inlining attributes re. profiling flag in protected_mode
iximeow Jun 23, 2024
f70232d
normalize imports, pull safer_unchecked from yaxpeax-arch
iximeow Jun 23, 2024
dc500de
adapt protected-mode display to real mode
iximeow Jun 23, 2024
2ac46a9
forward long deprecation allowances as appropriate
iximeow Jun 23, 2024
2002347
add additional `call` test cases
iximeow Jun 23, 2024
4225510
stale file
iximeow Jun 23, 2024
9d9bb9b
InstructionTextBuffer for all three modes, adjust fuzzer to match
iximeow Jun 23, 2024
1fdd243
fuzz caught negation bug
iximeow Jun 23, 2024
24d5384
another fuzz bug
iximeow Jun 23, 2024
bc4abf8
last vestiges of initial perf experiments
iximeow Jun 23, 2024
0a5e948
cfg_attr wants feature, not features plural
iximeow Jun 23, 2024
09dcfca
remove yaxpeax-x86 safer_unchecked.rs, it is now in yaxpeax-arch
iximeow Jun 23, 2024
25b9a53
fix several sources of dead code warnings in various crate configs
iximeow Jun 24, 2024
577b8e8
nightly correctly remarked that == on fat pointers is ambiguous
iximeow Jun 24, 2024
238d65c
update yaxpeax-arch to 0.3.1, fix fuzz target warnings
iximeow Jun 24, 2024
0e35363
note yaxpeax-arch version bump in changelog
iximeow Jun 24, 2024
b8a294d
remove selects_cs(), cs() now does the right thing
iximeow Jun 24, 2024
1b8019d
rename most operand variants, make them structy rather than tupley
iximeow Jun 24, 2024
f4ae2ed
one more stray docs error
iximeow Jun 24, 2024
ddde47c
consistently enter register/number/opcode spans
iximeow Jun 24, 2024
dd8bd5c
justify the current max instruction length
iximeow Jun 24, 2024
42f29e3
bump cargo version to 2.0.0, not quite releasing yet
iximeow Jun 24, 2024
016583f
bench: fetch from fork updated for yaxpeax-x86 2.0.0
iximeow Jun 24, 2024
6a5ea10
add missing feature flag to real-mode ffi library
iximeow Jun 24, 2024
24b33d5
document one more stray unsafe
iximeow Jun 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
## 2.0.0

* upgrade to `yaxpeax-arch 0.3.1`, which brings with it a deprecation of the
`Colorize` and `ShowContextual` traits.
* because common use of yaxpeax-x86 involves using both this crate and
`yaxpeax-arch`, moving to a newer major version of `yaxpeax-arch` is a major
version bump of `yaxpeax-x86` as well. so, 2.0.0!

changes:

* `Operand` variants have had their naming made more consistent.
- many variants starting with "Reg" actually describe a memory access. they
now begin with "Mem" instead.
- several variants mentioned "Scale" in their name, but not "Index", even
though they use an index register. they now do.
- several variants mentioned their constituent parts out of order. for
example, "RegIndexBaseScaleDisp", even though the parts were specified as
base, then index, then scale, then displacement. these names have been
adjusted to reflect the order of their fields, which is roughly the order
those fields are shown when printed.
- `DisplacementU*` operands have always been access to memory at the absolute
address they specify. their names are now `AbsoluteU*`
* `Operand`, across the board, now uses struct-style enum variants, rather than tuple-style.
* the two changes together mean an operand that was
`RegIndexBaseScaleDisp(reg, reg, u8, i32)`
is now
`MemBaseIndexScaleDisp { base, index, scale, disp }`
and similar for other variants.
* two operand kinds, and their masked variants, were never actually constructed, and have been deleted.
- long ago yaxpeax-x86 returned different Operand variants when an index
register was used with scale 1, to hint that no scaling actually occurred.
this was eventually changed to return a scaling Operand variant with
scale==1, but the old variants remained.
- RegIndexBase has been removed
- RegIndexBaseDisp has been removed
* `Prefixes::selects_cs()` has been moved to `Prefixes::cs()`, and the old
useless functions are no more. `inst.prefixes().cs()` is finally a reasonable
way to determine if an instruction reads or writes through the cs prefix.

fixes:

* fix 32-bit call/jmp not respecting 66 prefix if set - such cases use 16-bit
operands, but decoded as if they used 32-bit operands.

## 1.2.2

* fix `hreset` reporting two operands, with a second operand of `Nothing`.
Expand Down
16 changes: 13 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

name = "yaxpeax-x86"
version = "1.2.2"
version = "2.0.0"
authors = [ "iximeow <me@iximeow.net>" ]
license = "0BSD"
repository = "http://git.iximeow.net/yaxpeax-x86/"
Expand All @@ -10,7 +10,7 @@ readme = "README.md"
edition = "2018"

[dependencies]
yaxpeax-arch = { version = "0.2.7", default-features = false, features = [] }
yaxpeax-arch = { version = "0.3.1", default-features = false, features = [] }
"num-traits" = { version = "0.2", default-features = false }
"serde" = { version = "1.0", optional = true }
"serde_json" = { version = "1.0", optional = true }
Expand Down Expand Up @@ -40,7 +40,13 @@ lto = true
default = ["std", "colors", "use-serde", "fmt"]

# opt-in for some apis that are really much nicer with String
std = ["yaxpeax-arch/std"]
std = ["alloc", "yaxpeax-arch/std"]

# opt-in for some formatting-related helpers that require performing allocation
#
# this should only be useful with `fmt` currently, but in the future there could
# be other `fmt`-independent code gated on `alloc`.
alloc = ["yaxpeax-arch/alloc"]

# feature for formatting instructions and their components
fmt = []
Expand All @@ -52,3 +58,7 @@ colors = ["yaxpeax-arch/colors"]
# This enables some capstone benchmarks over the same
# instruction bytes used to bench this code.
capstone_bench = []

# this disables a lot of inlining to make it easier for me to measure
# likelihood of codepaths for typical instruction sequences
profiling = []
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn main() {
#[cfg(capstone_bench)]
#[cfg(feature="capstone_bench")]
{
println!("cargo:rustc-link-search=/usr/lib/");
println!("cargo:rustc-link-lib=capstone");
Expand Down
2 changes: 1 addition & 1 deletion ffi/long_mode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2018"

[dependencies]
yaxpeax-x86 = { path = "../../", default-features = false }
yaxpeax-arch = { version = "0.2.7", default-features = false }
yaxpeax-arch = { version = "0.3.1", default-features = false }

[lib]
name = "yaxpeax_x86_ffi_long_mode"
Expand Down
2 changes: 1 addition & 1 deletion ffi/multiarch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2018"

[dependencies]
yaxpeax-x86 = { path = "../../", default-features = false }
yaxpeax-arch = { version = "0.2.7", default-features = false }
yaxpeax-arch = { version = "0.3.1", default-features = false }

[lib]
name = "yaxpeax_x86_ffi_multiarch"
Expand Down
2 changes: 1 addition & 1 deletion ffi/protected_mode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2018"

[dependencies]
yaxpeax-x86 = { path = "../../", default-features = false }
yaxpeax-arch = { version = "0.2.7", default-features = false }
yaxpeax-arch = { version = "0.3.1", default-features = false }

[lib]
name = "yaxpeax_x86_ffi_protected_mode"
Expand Down
9 changes: 7 additions & 2 deletions ffi/real_mode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ edition = "2018"

[dependencies]
yaxpeax-x86 = { path = "../../", default-features = false }
yaxpeax-arch = { version = "0.2.7", default-features = false }
yaxpeax-arch = { version = "0.3.1", default-features = false }

[lib]
name = "yaxpeax_x86_ffi_real_mode"
path = "src/lib.rs"
crate-type = ["staticlib"]
crate-type = ["staticlib", "cdylib"]

[features]
default = ["fmt"]

fmt = ["yaxpeax-x86/fmt"]
14 changes: 14 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ cargo-fuzz = true

[dependencies.yaxpeax-x86]
path = ".."
[dependencies.yaxpeax-arch]
version = "0.3.1"
[dependencies.libfuzzer-sys]
git = "https://github.com/rust-fuzz/libfuzzer-sys.git"

Expand All @@ -27,6 +29,18 @@ path = "fuzz_targets/display_does_not_panic.rs"
test = false
doc = false

[[bin]]
name = "displaysink_used_correctly"
path = "fuzz_targets/displaysink_used_correctly.rs"
test = false
doc = false

[[bin]]
name = "instruction_text_buffer_size_ok"
path = "fuzz_targets/instruction_text_buffer_size_ok.rs"
test = false
doc = false

[[bin]]
name = "display_c_does_not_panic"
path = "fuzz_targets/display_c_does_not_panic.rs"
Expand Down
6 changes: 3 additions & 3 deletions fuzz/fuzz_targets/decode_does_not_panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fuzz_target!(|data: &[u8]| {
let x86_64_decoder = yaxpeax_x86::long_mode::InstDecoder::default();
let x86_32_decoder = yaxpeax_x86::protected_mode::InstDecoder::default();
let x86_16_decoder = yaxpeax_x86::real_mode::InstDecoder::default();
drop(x86_64_decoder.decode_slice(data));
drop(x86_32_decoder.decode_slice(data));
drop(x86_16_decoder.decode_slice(data));
x86_64_decoder.decode_slice(data).expect("is ok");
x86_32_decoder.decode_slice(data).expect("is ok");
x86_16_decoder.decode_slice(data).expect("is ok");
});
18 changes: 15 additions & 3 deletions fuzz/fuzz_targets/display_does_not_panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,26 @@ fuzz_target!(|data: &[u8]| {
let x86_16_decoder = yaxpeax_x86::real_mode::InstDecoder::default();

if let Ok(inst) = x86_64_decoder.decode_slice(data) {
inst.write_to(&mut String::new()).expect("format does not panic");
let mut out = String::new();
inst.write_to(&mut out).expect("format does not panic");
let mut text_buf = yaxpeax_x86::long_mode::InstructionTextBuffer::new();
text_buf.format_inst(&inst.display_with(yaxpeax_x86::long_mode::DisplayStyle::Intel)).expect("can format");
assert_eq!(text_buf.text_str(), out);
};

if let Ok(inst) = x86_32_decoder.decode_slice(data) {
inst.write_to(&mut String::new()).expect("format does not panic");
let mut out = String::new();
inst.write_to(&mut out).expect("format does not panic");
let mut text_buf = yaxpeax_x86::protected_mode::InstructionTextBuffer::new();
text_buf.format_inst(&inst.display_with(yaxpeax_x86::protected_mode::DisplayStyle::Intel)).expect("can format");
assert_eq!(text_buf.text_str(), out);
};

if let Ok(inst) = x86_16_decoder.decode_slice(data) {
inst.write_to(&mut String::new()).expect("format does not panic");
let mut out = String::new();
inst.write_to(&mut out).expect("format does not panic");
let mut text_buf = yaxpeax_x86::real_mode::InstructionTextBuffer::new();
text_buf.format_inst(&inst.display_with(yaxpeax_x86::real_mode::DisplayStyle::Intel)).expect("can format");
assert_eq!(text_buf.text_str(), out);
};
});
24 changes: 24 additions & 0 deletions fuzz/fuzz_targets/displaysink_used_correctly.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate yaxpeax_x86;
extern crate yaxpeax_arch;

fuzz_target!(|data: &[u8]| {
let x86_64_decoder = yaxpeax_x86::long_mode::InstDecoder::default();
let x86_32_decoder = yaxpeax_x86::protected_mode::InstDecoder::default();
let x86_16_decoder = yaxpeax_x86::real_mode::InstDecoder::default();

use yaxpeax_arch::testkit::DisplaySinkValidator;

if let Ok(inst) = x86_64_decoder.decode_slice(data) {
inst.display_into(&mut DisplaySinkValidator::new()).expect("instruction can be displayed");
};

if let Ok(inst) = x86_32_decoder.decode_slice(data) {
inst.display_into(&mut DisplaySinkValidator::new()).expect("instruction can be displayed");
};

if let Ok(inst) = x86_16_decoder.decode_slice(data) {
inst.display_into(&mut DisplaySinkValidator::new()).expect("instruction can be displayed");
};
});
51 changes: 51 additions & 0 deletions fuzz/fuzz_targets/instruction_text_buffer_size_ok.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate yaxpeax_x86;
extern crate yaxpeax_arch;

use std::fmt::Write;

fuzz_target!(|data: &[u8]| {
let x86_64_decoder = yaxpeax_x86::long_mode::InstDecoder::default();
let x86_32_decoder = yaxpeax_x86::protected_mode::InstDecoder::default();
let x86_16_decoder = yaxpeax_x86::real_mode::InstDecoder::default();

if let Ok(inst) = x86_64_decoder.decode_slice(data) {
use yaxpeax_x86::long_mode::DisplayStyle;

let mut s = String::new();
write!(s, "{}", inst.display_with(DisplayStyle::Intel)).expect("can write");
// MAX_INSTRUCTION_LEN is not a public crate item yet...
assert!(s.len() < 512);
s.clear();
write!(s, "{}", inst.display_with(DisplayStyle::C)).expect("can write");
// MAX_INSTRUCTION_LEN is not a public crate item yet...
assert!(s.len() < 512);
};

if let Ok(inst) = x86_32_decoder.decode_slice(data) {
use yaxpeax_x86::protected_mode::DisplayStyle;

let mut s = String::new();
write!(s, "{}", inst.display_with(DisplayStyle::Intel)).expect("can write");
// MAX_INSTRUCTION_LEN is not a public crate item yet...
assert!(s.len() < 512);
s.clear();
write!(s, "{}", inst.display_with(DisplayStyle::C)).expect("can write");
// MAX_INSTRUCTION_LEN is not a public crate item yet...
assert!(s.len() < 512);
};

if let Ok(inst) = x86_16_decoder.decode_slice(data) {
use yaxpeax_x86::real_mode::DisplayStyle;

let mut s = String::new();
write!(s, "{}", inst.display_with(DisplayStyle::Intel)).expect("can write");
// MAX_INSTRUCTION_LEN is not a public crate item yet...
assert!(s.len() < 512);
s.clear();
write!(s, "{}", inst.display_with(DisplayStyle::C)).expect("can write");
// MAX_INSTRUCTION_LEN is not a public crate item yet...
assert!(s.len() < 512);
};
});
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/small_reg_is_always_old_bank_if_possible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ extern crate yaxpeax_x86;
// cases. leaving them in for fuzz targets to match other cases, and In Case Of Future Change.
fuzz_target!(|data: &[u8]| {
let x86_64_decoder = yaxpeax_x86::long_mode::InstDecoder::default();
let x86_32_decoder = yaxpeax_x86::protected_mode::InstDecoder::default();
let x86_16_decoder = yaxpeax_x86::real_mode::InstDecoder::default();
// let x86_32_decoder = yaxpeax_x86::protected_mode::InstDecoder::default();
// let x86_16_decoder = yaxpeax_x86::real_mode::InstDecoder::default();

if let Ok(inst) = x86_64_decoder.decode_slice(data) {
for i in 0..inst.operand_count() {
Expand Down
2 changes: 1 addition & 1 deletion goodfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Build.artifact(sopath)

-- now run some perf numbers...
Step.start("perf")
Build.run({"git", "clone", "https://github.com/athre0z/disas-bench.git", "disas-bench"})
Build.run({"git", "clone", "https://github.com/iximeow/disas-bench.git", "disas-bench"})
Build.run({"git", "submodule", "update", "--recursive", "--init"}, {cwd="disas-bench"})
Build.run({"git", "remote", "add", "dev", "../../.."}, {cwd="disas-bench/libs/yaxpeax"})
Build.run({"git", "fetch", "-a", "dev"}, {cwd="disas-bench/libs/yaxpeax"})
Expand Down
45 changes: 40 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
//! #[cfg(features="fmt")]
//! assert_eq!("xor eax, dword [rcx]", inst.to_string());
//!
//! assert_eq!(Operand::Register(RegSpec::eax()), inst.operand(0));
//! assert_eq!(Operand::Register { reg: RegSpec::eax() }, inst.operand(0));
//! #[cfg(features="fmt")]
//! assert_eq!("eax", inst.operand(0).to_string());
//! assert_eq!(Operand::RegDeref(RegSpec::rcx()), inst.operand(1));
//! assert_eq!(Operand::MemDeref { base: RegSpec::rcx() }, inst.operand(1));
//!
//! // an operand in isolation does not know the size of memory it references, if any
//! #[cfg(features="fmt")]
Expand Down Expand Up @@ -138,9 +138,44 @@ pub use protected_mode::Arch as x86_32;
pub mod real_mode;
pub use real_mode::Arch as x86_16;

mod safer_unchecked;
// this exists to size `InstructionTextBuffer`'s buffer. it ideally would come from an `Arch`
// impl, or something related to `Arch`, but i'm not yet sure how to wire that up into
// yaxpeax-arch. so instead calculate an appropriate max size for all of 16-bit/32-bit/64-bit
// instruction printing that `InstructionTextBuffer` can be used for.
//
// `InstructionTextBuffer` prints an `InstructionDisplayer`, which means either intel syntax or
// pseudo-C. in the future, at&t probably, as well.
//
// the pseudo-C syntax's max length would be something like:
// ```
// xacquire xrelease lock { repnz qword if /* signed */ greater_or_equal(rflags) then jmp gs:[xmm31 +
// xmm31 * 8 + 0x12345678]{k7}{z}{rne-sae} }
// ```
// (which is nonsensical) or for an unknown opcode,
// ```
// xacquire xrelease lock { op0 = op(op0, op1, op2, op3) }
// ```
// where `opN` is an operand. the longest operand, same as above, would be something like
// ```
// gs:[xmm31 + xmm31 * 8 + 0x12345678]{k7}{z}{rne-sae}
// ```
// for a length like 262 bytes of operand, 55 bytes of prefixes and syntax, and another up-to-20
// bytes of opcode.
//
// the longest contextualize_c might write is around 337 bytes. round up to 512 because it's.. not
// much extra.
//
// the same reasoning for intel syntax yields a smaller instruction:
// ```
// xacquire xrelease lock op op1, op2, op3, op4
// ```
// where the longest operands are the same as above. this comes out to closer to 307 bytes. 512
// bytes is still the longest of the two options.
#[allow(dead_code)] // can be an unused constant in some library configurations
const MAX_INSTRUCTION_LEN: usize = 512;

const MEM_SIZE_STRINGS: [&'static str; 64] = [
const MEM_SIZE_STRINGS: [&'static str; 65] = [
"BUG",
"byte", "word", "BUG", "dword", "ptr", "far", "BUG", "qword",
"BUG", "mword", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword",
"BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
Expand Down Expand Up @@ -194,7 +229,7 @@ impl MemoryAccessSize {
/// "variable" accesses access a number of bytes dependent on the physical processor and its
/// operating mode. this is particularly relevant for `xsave`/`xrstor`-style instructions.
pub fn size_name(&self) -> &'static str {
MEM_SIZE_STRINGS[self.size as usize - 1]
MEM_SIZE_STRINGS[self.size as usize]
}
}

Expand Down
Loading