diff --git a/src/backend/arch/x86_64.rs b/src/backend/arch/x86_64.rs index 6f72963..36283e4 100644 --- a/src/backend/arch/x86_64.rs +++ b/src/backend/arch/x86_64.rs @@ -13,6 +13,7 @@ pub struct Asm { pub enum Instr { Mov { dst: RegMode, src: RegImm }, Int { code: u8 }, + Syscall, Lea { dst: RegMode, sym: Symbol }, } @@ -85,6 +86,7 @@ impl super::super::program::Instr for Instr { }; data.extend(addr_offset(data.len(), addr)); } + Instr::Syscall => data.extend([0x0f, 0x05]), } Ok(None) } diff --git a/src/backend/elf.rs b/src/backend/elf.rs index 2d85d99..c0bf45b 100644 --- a/src/backend/elf.rs +++ b/src/backend/elf.rs @@ -64,9 +64,19 @@ impl Arch { } } +#[repr(u8)] +pub enum EType { + None = 0, + Rel = 1, + Exec = 2, + Dyn = 3, + Core = 4, +} + // this is currently specialized for riscv64; obviously add params later pub fn create(program: &[u8], start_offset: Addr) -> Vec { - let addr_start = 0x400000; + let pie = true; + let addr_start = if pie { 0 } else { 0x400000 }; let page_size = 0x1000; // I don't know if I have to add addr_start here, idk how it maps the memory let program_size = std::mem::size_of_val(program) as u64; @@ -90,7 +100,7 @@ pub fn create(program: &[u8], start_offset: Addr) -> Vec { os_abi: 0x0, // system-v os_abi_ver: 0x0, pad: [0x0; 7], - ty: 0x2, // executable + ty: if pie { EType::Dyn } else { EType::Exec } as u16, machine: Arch::X86_64.machine(), e_version: 0x1, entry: addr_start + program_pos + start_offset.val(), diff --git a/src/backend/test.rs b/src/backend/test.rs index 6ebdeda..7811771 100644 --- a/src/backend/test.rs +++ b/src/backend/test.rs @@ -1,7 +1,7 @@ use crate::backend::{ program::{UnlinkedFunction, UnlinkedProgram}, symbol::Symbol, - x86_64::{instr::*, reg::*}, + x86_64::{Instr, instr::*, reg::*}, }; use std::{fs::OpenOptions, io::Write, os::unix::fs::OpenOptionsExt, process::Command}; @@ -10,20 +10,20 @@ pub fn test_x86_64() { let program = UnlinkedProgram { fns: vec![UnlinkedFunction { instrs: vec![ - mov(eax, 4), - mov(ebx, 1), - lea(ecx, Symbol::raw(1)), - mov(edx, s.len() as u64), - int(0x80), - mov(eax, 1), - mov(ebx, 39), - int(0x80), + mov(rax, 1), + mov(rdi, 1), + lea(rsi, Symbol::raw(1)), + mov(rdx, s.len() as u64), + Instr::Syscall, + mov(rax, 0x3c), + mov(rdi, 39), + Instr::Syscall, ], sym: Symbol::raw(0), locations: Default::default(), }], ro_data: vec![(s.to_vec(), Symbol::raw(1))], - sym_count: 3, + sym_count: 2, start: Some(Symbol::raw(0)), }; let Ok(linked) = program.link() else { @@ -42,7 +42,23 @@ pub fn test_x86_64() { file.sync_all().expect("Failed to sync file"); drop(file); println!("running..."); - let mut proc = Command::new(path).spawn().expect("failed to run"); + 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); diff --git a/x86_64_test b/x86_64_test index 0174fb8..42cd68a 100755 Binary files a/x86_64_test and b/x86_64_test differ