diff options
-rw-r--r-- | src/asm.rs | 13 | ||||
-rw-r--r-- | src/disasm.rs | 51 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/rt.rs | 39 |
4 files changed, 66 insertions, 38 deletions
@@ -42,6 +42,19 @@ impl Asm { self.buf } + /// Disassemble the code currently added to the runtime, using + /// [`ndisasm`](https://nasm.us/index.php) and print it to _stdout_. If + /// `ndisasm` is not available on the system this prints a warning and + /// becomes a nop. + /// + /// # Panics + /// + /// Panics if anything goes wrong with spawning, writing to or reading from + /// the `ndisasm` child process. + pub fn disasm(&self) { + crate::disasm::disasm(&self.buf); + } + /// Emit a slice of bytes. pub(crate) fn emit(&mut self, bytes: &[u8]) { self.buf.extend_from_slice(bytes); diff --git a/src/disasm.rs b/src/disasm.rs new file mode 100644 index 0000000..d8e6058 --- /dev/null +++ b/src/disasm.rs @@ -0,0 +1,51 @@ +use std::io::{ErrorKind, Write}; +use std::process::{Command, Stdio}; + +/// Disassemble the code currently added to the runtime, using +/// [`ndisasm`](https://nasm.us/index.php) and print it to _stdout_. If +/// `ndisasm` is not available on the system this prints a warning and +/// becomes a nop. +/// +/// # Panics +/// +/// Panics if anything goes wrong with spawning, writing to or reading from +/// the `ndisasm` child process. +pub(crate) fn disasm<T: AsRef<[u8]>>(code: T) { + let code = code.as_ref(); + + // Create ndisasm process, which expects input on stdin. + let mut child = match Command::new("ndisasm") + .args(["-b64", "-"]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + { + Ok(child) => child, + Err(err) if err.kind() == ErrorKind::NotFound => { + println!("disasm: skipping, ndisasm not found"); + return; + } + Err(err) => { + panic!("{:?}", err); + } + }; + + // Write code to stdin of ndisasm. + child + .stdin + .take() + .expect("failed to take stdin") + .write_all(code) + .expect("failed to write bytes to stdin"); + + // Wait for output from ndisasm and print to stdout. + println!( + "{}", + String::from_utf8_lossy( + &child + .wait_with_output() + .expect("failed to get stdout") + .stdout + ) + ); +} @@ -74,6 +74,7 @@ //! ``` mod asm; +mod disasm; mod imm; mod label; mod mem; @@ -167,44 +167,7 @@ impl Runtime { /// the `ndisasm` child process. pub fn disasm(&self) { assert!(self.idx <= self.len); - let code = unsafe { core::slice::from_raw_parts(self.buf, self.idx) }; - - // Create ndisasm process, which expects input on stdin. - let mut child = match std::process::Command::new("ndisasm") - .args(["-b64", "-"]) - .stdin(std::process::Stdio::piped()) - .stdout(std::process::Stdio::piped()) - .spawn() - { - Ok(child) => child, - Err(err) if err.kind() == std::io::ErrorKind::NotFound => { - println!("Runtime::disasm: ndisasm not found, skipping!"); - return; - } - Err(err) => { - panic!("{:?}", err); - } - }; - - // Write code to stdin of ndisasm. - use std::io::Write; - child - .stdin - .take() - .expect("failed to take stdin") - .write_all(code) - .expect("failed to write bytes to stdin"); - - // Wait for output from ndisasm and print to stdout. - println!( - "{}", - String::from_utf8_lossy( - &child - .wait_with_output() - .expect("failed to get stdout") - .stdout - ) - ); + crate::disasm::disasm(unsafe { core::slice::from_raw_parts(self.buf, self.idx) }); } /// Reinterpret the block of code pointed to by `fn_start` as `F`. |