use libloong::{Machine, MachineOptions};
use std::env;
use std::fs;
use std::process;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!(
"Usage: {} <loongarch_elf_file> [function_name] [args...]",
args[0]
);
eprintln!();
eprintln!("Example:");
eprintln!(" {} ../tests/programs/cxx_test.elf test_addition", args[0]);
process::exit(1);
}
let elf_path = &args[1];
let func_name = args.get(2).map(|s| s.as_str()).unwrap_or("main");
let func_args: Vec<u64> = args[3..].iter().filter_map(|s| s.parse().ok()).collect();
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);
let mut machine = match Machine::new(&binary, MachineOptions::default()) {
Ok(m) => m,
Err(e) => {
eprintln!("Failed to create machine: {}", e);
process::exit(1);
}
};
Machine::setup_linux_syscalls();
if let Err(e) = machine.setup_linux(&["program"], &[]) {
eprintln!("Failed to setup Linux: {}", e);
process::exit(1);
}
libloong::set_stdout_callback(Some(|data| {
print!("{}", String::from_utf8_lossy(data));
}));
if !machine.has_symbol(func_name) {
eprintln!("Function '{}' not found in binary", func_name);
eprintln!("\nTry running with a different function name.");
process::exit(1);
}
println!("Calling function '{}'", func_name);
println!("Arguments: {:?}", func_args);
println!();
match machine.vmcall(func_name, &func_args) {
Ok(()) => {
let result = machine.return_value();
println!("\nFunction returned: {} (0x{:x})", result, result);
println!("Instructions executed: {}", machine.instruction_counter());
}
Err(e) => {
eprintln!("\nVmcall failed: {}", e);
eprintln!("Instructions executed: {}", machine.instruction_counter());
eprintln!("PC: 0x{:016x}", machine.get_pc());
process::exit(1);
}
}
}