aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/disasm.rs
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2024-12-20 23:35:12 +0100
committerJohannes Stoelp <johannes.stoelp@gmail.com>2024-12-20 23:35:12 +0100
commit2bb15c8d75a75f1d75d52ca63017e9492753b8ef (patch)
treeb3d68435d865238f393878c6a5d7cb861fd57646 /src/disasm.rs
parent8ca27aeeb99a0da43e92e39918aa07c0b1443c07 (diff)
downloadjuicebox-asm-2bb15c8d75a75f1d75d52ca63017e9492753b8ef.tar.gz
juicebox-asm-2bb15c8d75a75f1d75d52ca63017e9492753b8ef.zip
disasm: move out and implement on asm/rt
Diffstat (limited to 'src/disasm.rs')
-rw-r--r--src/disasm.rs51
1 files changed, 51 insertions, 0 deletions
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
+ )
+ );
+}