aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2024-06-24 14:06:22 -0700
committeriximeow <me@iximeow.net>2024-06-24 14:27:25 -0700
commitdd8bd5ce0772b08c271205508e48e98ef1c58ea8 (patch)
tree946630c89a554843dd33a9988a36bb43db48d539 /src
parentddde47c4c8c2058379b448894bebb3e099ea0585 (diff)
justify the current max instruction length
this is also checked by a new fuzz target
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs36
-rw-r--r--src/long_mode/display.rs4
-rw-r--r--src/protected_mode/display.rs4
-rw-r--r--src/real_mode/display.rs4
4 files changed, 39 insertions, 9 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 7ab6cb8..93274f9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -138,6 +138,42 @@ pub use protected_mode::Arch as x86_32;
pub mod real_mode;
pub use real_mode::Arch as x86_16;
+// 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; 65] = [
"BUG",
"byte", "word", "BUG", "dword", "ptr", "far", "BUG", "qword",
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index 1193f35..89d952b 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -4410,9 +4410,7 @@ mod buffer_sink {
/// settings format instructions identically to their corresponding `fmt::Display`.
pub fn new() -> Self {
let mut buf = alloc::string::String::new();
- // TODO: move 512 out to a MAX_INSTRUCTION_LEN const and appropriate justification (and
- // fuzzing and ..)
- buf.reserve(512);
+ buf.reserve(crate::MAX_INSTRUCTION_LEN);
Self {
content: buf,
}
diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs
index db12878..321b5b5 100644
--- a/src/protected_mode/display.rs
+++ b/src/protected_mode/display.rs
@@ -2955,9 +2955,7 @@ mod buffer_sink {
/// settings format instructions identically to their corresponding `fmt::Display`.
pub fn new() -> Self {
let mut buf = alloc::string::String::new();
- // TODO: move 512 out to a MAX_INSTRUCTION_LEN const and appropriate justification (and
- // fuzzing and ..)
- buf.reserve(512);
+ buf.reserve(crate::MAX_INSTRUCTION_LEN);
Self {
content: buf,
}
diff --git a/src/real_mode/display.rs b/src/real_mode/display.rs
index e8bd191..669b8d7 100644
--- a/src/real_mode/display.rs
+++ b/src/real_mode/display.rs
@@ -2957,9 +2957,7 @@ mod buffer_sink {
/// settings format instructions identically to their corresponding `fmt::Display`.
pub fn new() -> Self {
let mut buf = alloc::string::String::new();
- // TODO: move 512 out to a MAX_INSTRUCTION_LEN const and appropriate justification (and
- // fuzzing and ..)
- buf.reserve(512);
+ buf.reserve(crate::MAX_INSTRUCTION_LEN);
Self {
content: buf,
}