diff options
author | iximeow <me@iximeow.net> | 2024-06-21 02:05:24 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2024-06-21 02:05:24 -0700 |
commit | d16cc79d7b7091f67328a0080634ce6cd4880dbd (patch) | |
tree | 3bc0a0d7d89a5a7b16b2e01514554b6ec9fbc830 /src/long_mode | |
parent | e39d6b576da2f25490bf739b61fc8c9f3ab7c2ec (diff) |
things compile again, add a few more caution signs around InstructionTextBuffer
Diffstat (limited to 'src/long_mode')
-rw-r--r-- | src/long_mode/display.rs | 17 | ||||
-rw-r--r-- | src/long_mode/mod.rs | 2 |
2 files changed, 15 insertions, 4 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index d9799e1..3615538 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -4303,6 +4303,7 @@ impl <T: fmt::Write, Y: YaxColors> ShowContextual<u64, [Option<alloc::string::St } } +// TODO: should include CALL static RELATIVE_BRANCHES: [Opcode; 21] = [ Opcode::JMP, Opcode::JRCXZ, Opcode::LOOP, Opcode::LOOPZ, Opcode::LOOPNZ, @@ -4474,12 +4475,13 @@ impl<'a, F: DisplaySink> crate::long_mode::OperandVisitor for RelativeBranchPrin /// ``` /// use yaxpeax_x86::long_mode::InstDecoder; /// use yaxpeax_x86::long_mode::InstructionTextBuffer; +/// use yaxpeax_x86::long_mode::DisplayStyle; /// /// let bytes = &[0x33, 0xc0]; /// let inst = InstDecoder::default().decode_slice(bytes).expect("can decode"); /// let mut text_buf = InstructionTextBuffer::new(); /// assert_eq!( -/// text_buf.format_inst(&inst).expect("can format"), +/// text_buf.format_inst(&inst.display_with(DisplayStyle::Intel)).expect("can format"), /// "xor eax, eax" /// ); /// @@ -4511,7 +4513,9 @@ impl InstructionTextBuffer { /// this clears and reuses an internal buffer; if an instruction had been previously formatted /// through this buffer, it will be overwritten. pub fn format_inst<'buf, 'instr>(&'buf mut self, display: &InstructionDisplayer<'instr>) -> Result<&'buf str, fmt::Error> { - let mut handle = self.write_handle(); + // Safety: this sink is used to format exactly one instruction and then dropped. it can + // never escape `format_inst`. + let mut handle = unsafe { self.write_handle() }; match display.style { DisplayStyle::Intel => { @@ -4531,8 +4535,15 @@ impl InstructionTextBuffer { self.content.as_str() } - fn write_handle(&mut self) -> crate::display::InstructionTextSink { + /// do the necessary bookkeeping and provide an `InstructionTextSink` to write an instruction + /// into. + /// + /// SAFETY: callers must print at most one instruction into this handle. + unsafe fn write_handle(&mut self) -> crate::display::InstructionTextSink { self.content.clear(); + // Safety: `content` was just cleared, so writing begins at the start of the buffer. + // `content`is large enough to hold a fully-formatted instruction (see + // `InstructionTextBuffer::new`). crate::display::InstructionTextSink::new(&mut self.content) } } diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 418d57f..9aeacdc 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -7,7 +7,7 @@ pub mod uarch; pub use crate::MemoryAccessSize; #[cfg(feature = "fmt")] -pub use self::display::{DisplayStyle, InstructionDisplayer}; +pub use self::display::{DisplayStyle, InstructionDisplayer, InstructionTextBuffer}; use core::cmp::PartialEq; use crate::safer_unchecked::unreachable_kinda_unchecked as unreachable_unchecked; |