aboutsummaryrefslogtreecommitdiffhomepage
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
parent8ca27aeeb99a0da43e92e39918aa07c0b1443c07 (diff)
downloadjuicebox-asm-2bb15c8d75a75f1d75d52ca63017e9492753b8ef.tar.gz
juicebox-asm-2bb15c8d75a75f1d75d52ca63017e9492753b8ef.zip
disasm: move out and implement on asm/rt
-rw-r--r--src/asm.rs13
-rw-r--r--src/disasm.rs51
-rw-r--r--src/lib.rs1
-rw-r--r--src/rt.rs39
4 files changed, 66 insertions, 38 deletions
diff --git a/src/asm.rs b/src/asm.rs
index 8647e83..1790e4e 100644
--- a/src/asm.rs
+++ b/src/asm.rs
@@ -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
+ )
+ );
+}
diff --git a/src/lib.rs b/src/lib.rs
index ef49859..201a10f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -74,6 +74,7 @@
//! ```
mod asm;
+mod disasm;
mod imm;
mod label;
mod mem;
diff --git a/src/rt.rs b/src/rt.rs
index a47cada..76a34b1 100644
--- a/src/rt.rs
+++ b/src/rt.rs
@@ -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`.