use std::{error::Error, fs::OpenOptions, path::Path}; use ygen::debug::{DebugLocation, DebugRegistry}; use ygen::{Obj::*, Target::Triple}; use ygen::Target::x64::{instr::*, x64Reg}; fn main() -> Result<(), Box> { // test.c: // 01 #include // 02 // 03 int main() { // 04 printf("Hello World!"); // 05 return 0; // 06 } let mut obj = ObjectBuilder::new( Triple::parse("x86_64-pc-windows")? ); obj.decls(vec![ ("main", Decl::Function, Linkage::External), ("string", Decl::Constant, Linkage::Internal), ("printf", Decl::Function, Linkage::Extern), ]); let mut debug = DebugRegistry::new("ygen example".to_string(), gimli::DW_LANG_C, Path::new("test.c")); let mut data = vec![]; data.extend_from_slice(&X64MCInstr::with1(Mnemonic::Push, Operand::Reg(x64Reg::Rbp)).compile()?); data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Sub, Operand::Reg(x64Reg::Rsp), Operand::Imm(40)).compile()?); debug.add_location(&"main".to_string(), DebugLocation { line: 3, col: 0, epilog: false, prolog: true, adr: data.len() as u64 }); let rip_relativ = Operand::Mem(MemOp { base: None, index: None, scale: 1, displ: 0, rip: true }); data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Lea, Operand::Reg(x64Reg::Rax), rip_relativ).compile()?); obj.link( Link { from: "main".into(), to: "string".into(), at: data.len(), addend: -4, special: false }); if cfg!(target_os = "windows") { data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rcx), Operand::Reg(x64Reg::Rax)).compile()?); } else { data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rsi), Operand::Reg(x64Reg::Rax)).compile()?); } debug.add_location(&"main".to_string(), DebugLocation { line: 4, col: 4, epilog: false, prolog: false, adr: data.len() as u64 }); data.extend_from_slice(&X64MCInstr::with1(Mnemonic::Call, Operand::Imm(0)).compile()?); // call printf obj.link( Link { from: "main".into(), to: "printf".into(), at: data.len(), addend: -4, special: false }); debug.add_location(&"main".to_string(), DebugLocation { line: 5, col: 4, epilog: false, prolog: false, adr: data.len() as u64 }); data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Xor, Operand::Reg(x64Reg::Eax), Operand::Reg(x64Reg::Eax)).compile()?); debug.add_location(&"main".to_string(), DebugLocation { line: 6, col: 0, epilog: true, prolog: false, adr: data.len() as u64 }); data.extend_from_slice(&X64MCInstr::with2(Mnemonic::Add, Operand::Reg(x64Reg::Rsp), Operand::Imm(40)).compile()?); data.extend_from_slice(&X64MCInstr::with0(Mnemonic::Ret).compile()?); // ret obj.define("main", data); obj.define("string", b"Hello World!\n\0".into()); obj.debug = true; obj.emit( OpenOptions::new().create(true).write(true).open("output.o")?, Some(debug) )?; Ok(()) }