use libloong::{Machine, MachineOptions};
use std::env;
use std::fs;
use std::process;
use std::time::Instant;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!("Usage: {} <loongarch_elf_file>", args[0]);
eprintln!();
eprintln!("Example:");
eprintln!(" {} ../tests/programs/hello_world.elf", args[0]);
process::exit(1);
}
let elf_path = &args[1];
let binary = match fs::read(elf_path) {
Ok(data) => data,
Err(e) => {
eprintln!("Failed to read ELF file '{}': {}", elf_path, e);
process::exit(1);
}
};
println!("Loading LoongArch ELF: {}", elf_path);
println!("Binary size: {} bytes", binary.len());
let options = MachineOptions {
memory_max: 600 * 1024 * 1024,
..Default::default()
};
let mut machine = match Machine::new(&binary, options) {
Ok(m) => m,
Err(e) => {
eprintln!("Failed to create machine: {}", e);
process::exit(1);
}
};
libloong::set_stdout_callback(Some(|data| {
print!("{}", String::from_utf8_lossy(data));
}));
Machine::setup_linux_syscalls();
if let Err(e) = machine.setup_linux(&["program"], &[]) {
eprintln!("Failed to setup Linux: {}", e);
process::exit(1);
}
if let Err(e) = machine.setup_accelerated_syscalls() {
eprintln!("Failed to setup accelerated syscalls: {}", e);
process::exit(1);
}
let start_time = Instant::now();
let max_instructions = u64::MAX;
match machine.simulate(max_instructions) {
Ok(_) => {
let elapsed = start_time.elapsed();
let exit_code = machine.return_value() as i32;
println!(
"Exit code: {} Time: {:.3} seconds",
exit_code,
elapsed.as_secs_f64()
);
if max_instructions != u64::MAX {
let instr_count = machine.instruction_counter();
let mips = instr_count as f64 / (elapsed.as_secs_f64() * 1_000_000.0);
println!("Instructions: {} ({:.2} MI/s)", instr_count, mips);
}
process::exit(exit_code);
}
Err(e) => {
let elapsed = start_time.elapsed();
eprintln!("\nExecution failed: {}", e);
eprintln!("Time: {:.3} seconds", elapsed.as_secs_f64());
if max_instructions != u64::MAX {
eprintln!("Instructions executed: {}", machine.instruction_counter());
}
eprintln!("PC: 0x{:016x}", machine.get_pc());
process::exit(1);
}
}
}