pie elf
This commit is contained in:
@@ -13,6 +13,7 @@ pub struct Asm {
|
|||||||
pub enum Instr {
|
pub enum Instr {
|
||||||
Mov { dst: RegMode, src: RegImm },
|
Mov { dst: RegMode, src: RegImm },
|
||||||
Int { code: u8 },
|
Int { code: u8 },
|
||||||
|
Syscall,
|
||||||
Lea { dst: RegMode, sym: Symbol },
|
Lea { dst: RegMode, sym: Symbol },
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +86,7 @@ impl super::super::program::Instr for Instr {
|
|||||||
};
|
};
|
||||||
data.extend(addr_offset(data.len(), addr));
|
data.extend(addr_offset(data.len(), addr));
|
||||||
}
|
}
|
||||||
|
Instr::Syscall => data.extend([0x0f, 0x05]),
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-2
@@ -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
|
// this is currently specialized for riscv64; obviously add params later
|
||||||
pub fn create(program: &[u8], start_offset: Addr) -> Vec<u8> {
|
pub fn create(program: &[u8], start_offset: Addr) -> Vec<u8> {
|
||||||
let addr_start = 0x400000;
|
let pie = true;
|
||||||
|
let addr_start = if pie { 0 } else { 0x400000 };
|
||||||
let page_size = 0x1000;
|
let page_size = 0x1000;
|
||||||
// I don't know if I have to add addr_start here, idk how it maps the memory
|
// 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;
|
let program_size = std::mem::size_of_val(program) as u64;
|
||||||
@@ -90,7 +100,7 @@ pub fn create(program: &[u8], start_offset: Addr) -> Vec<u8> {
|
|||||||
os_abi: 0x0, // system-v
|
os_abi: 0x0, // system-v
|
||||||
os_abi_ver: 0x0,
|
os_abi_ver: 0x0,
|
||||||
pad: [0x0; 7],
|
pad: [0x0; 7],
|
||||||
ty: 0x2, // executable
|
ty: if pie { EType::Dyn } else { EType::Exec } as u16,
|
||||||
machine: Arch::X86_64.machine(),
|
machine: Arch::X86_64.machine(),
|
||||||
e_version: 0x1,
|
e_version: 0x1,
|
||||||
entry: addr_start + program_pos + start_offset.val(),
|
entry: addr_start + program_pos + start_offset.val(),
|
||||||
|
|||||||
+27
-11
@@ -1,7 +1,7 @@
|
|||||||
use crate::backend::{
|
use crate::backend::{
|
||||||
program::{UnlinkedFunction, UnlinkedProgram},
|
program::{UnlinkedFunction, UnlinkedProgram},
|
||||||
symbol::Symbol,
|
symbol::Symbol,
|
||||||
x86_64::{instr::*, reg::*},
|
x86_64::{Instr, instr::*, reg::*},
|
||||||
};
|
};
|
||||||
use std::{fs::OpenOptions, io::Write, os::unix::fs::OpenOptionsExt, process::Command};
|
use std::{fs::OpenOptions, io::Write, os::unix::fs::OpenOptionsExt, process::Command};
|
||||||
|
|
||||||
@@ -10,20 +10,20 @@ pub fn test_x86_64() {
|
|||||||
let program = UnlinkedProgram {
|
let program = UnlinkedProgram {
|
||||||
fns: vec![UnlinkedFunction {
|
fns: vec![UnlinkedFunction {
|
||||||
instrs: vec![
|
instrs: vec![
|
||||||
mov(eax, 4),
|
mov(rax, 1),
|
||||||
mov(ebx, 1),
|
mov(rdi, 1),
|
||||||
lea(ecx, Symbol::raw(1)),
|
lea(rsi, Symbol::raw(1)),
|
||||||
mov(edx, s.len() as u64),
|
mov(rdx, s.len() as u64),
|
||||||
int(0x80),
|
Instr::Syscall,
|
||||||
mov(eax, 1),
|
mov(rax, 0x3c),
|
||||||
mov(ebx, 39),
|
mov(rdi, 39),
|
||||||
int(0x80),
|
Instr::Syscall,
|
||||||
],
|
],
|
||||||
sym: Symbol::raw(0),
|
sym: Symbol::raw(0),
|
||||||
locations: Default::default(),
|
locations: Default::default(),
|
||||||
}],
|
}],
|
||||||
ro_data: vec![(s.to_vec(), Symbol::raw(1))],
|
ro_data: vec![(s.to_vec(), Symbol::raw(1))],
|
||||||
sym_count: 3,
|
sym_count: 2,
|
||||||
start: Some(Symbol::raw(0)),
|
start: Some(Symbol::raw(0)),
|
||||||
};
|
};
|
||||||
let Ok(linked) = program.link() else {
|
let Ok(linked) = program.link() else {
|
||||||
@@ -42,7 +42,23 @@ pub fn test_x86_64() {
|
|||||||
file.sync_all().expect("Failed to sync file");
|
file.sync_all().expect("Failed to sync file");
|
||||||
drop(file);
|
drop(file);
|
||||||
println!("running...");
|
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");
|
let status = proc.wait().expect("failed to wait");
|
||||||
if let Some(code) = status.code() {
|
if let Some(code) = status.code() {
|
||||||
std::process::exit(code);
|
std::process::exit(code);
|
||||||
|
|||||||
BIN
Binary file not shown.
Reference in New Issue
Block a user