use std::{fs::OpenOptions, io::Write, os::unix::fs::OpenOptionsExt, process::Command}; use crate::{ arch::x86_64::*, backend::{Instr as BInstr, Program}, }; pub fn test_x86_64() { let mut program = Program::::default(); let text = b"Hello world!\n"; let text_sym = program.ro_data(text); let entry = program.func([BInstr::Asm(Asm { instrs: vec![ mov(ax, 1), mov(di, 1), lea(rsi, text_sym), mov(dx, text.len() as u64), Instr::Syscall, mov(ax, 0x3c), mov(di, 39), Instr::Syscall, ], })]); program.entry = Some(entry); let linked = program.compile().expect("failed to compile"); let binary = linked.to_elf(); let path = "./x86_64_test"; let mut file = OpenOptions::new() .create(true) .write(true) .truncate(true) .mode(0o750) .open(path) .expect("Failed to create file"); file.write_all(&binary).expect("Failed to write to file"); file.sync_all().expect("Failed to sync file"); drop(file); println!("running..."); let gdb = false; let mut proc = if gdb { let mut cmd = Command::new("gdb"); #[rustfmt::skip] cmd.args([ "-q", "-ex", "starti", "-ex", "layout asm", "-ex", "focus next", "x86_64_test", ]); cmd } else { Command::new(path) } .spawn() .expect("failed to run"); let status = proc.wait().expect("failed to wait"); if let Some(code) = status.code() { std::process::exit(code); } }