Relocations are working
This commit is contained in:
@@ -14,3 +14,5 @@ log = "0.4"
|
|||||||
critical-section = { version = "1", features = ["restore-state-bool"] }
|
critical-section = { version = "1", features = ["restore-state-bool"] }
|
||||||
bffs = { path = "../../../code/bffs", features = ["alloc"] }
|
bffs = { path = "../../../code/bffs", features = ["alloc"] }
|
||||||
shared = { path = "crates/shared" }
|
shared = { path = "crates/shared" }
|
||||||
|
# ELF parsing helper
|
||||||
|
goblin = { version = "0.7", default-features = false, features = ["elf32", "elf64", "endian_fd"] }
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ macro_rules! custom_std_setup {
|
|||||||
|
|
||||||
unsafe impl core::alloc::GlobalAlloc for GlobalAllocator {
|
unsafe impl core::alloc::GlobalAlloc for GlobalAllocator {
|
||||||
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||||
syscall::write_string_temp("Alloc user called");
|
|
||||||
$crate::syscall::alloc(layout)
|
$crate::syscall::alloc(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,11 +50,11 @@ macro_rules! print {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! println {
|
macro_rules! println {
|
||||||
() => {
|
() => {
|
||||||
// $crate::print!("");
|
$crate::print!("");
|
||||||
$crate::print!("\n\r");
|
// $crate::print!("\n\r");
|
||||||
};
|
};
|
||||||
($($args:expr),*) => {
|
($($args:expr),*) => {
|
||||||
$crate::print!($($args),*);
|
$crate::print!($($args),*);
|
||||||
$crate::println!();
|
// $crate::println!();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
10
justfile
10
justfile
@@ -12,11 +12,11 @@ sync_filesystem:
|
|||||||
sync
|
sync
|
||||||
|
|
||||||
build_user_prog prog:
|
build_user_prog prog:
|
||||||
RUSTFLAGS="-C relocation-model=pic -C link-arg=-Tuser.ld" cargo b {{ cargo_flags }} --package {{ prog }}
|
RUSTFLAGS="-C relocation-model=pic -C link-arg=-Tuser.ld -C link-arg=-pie" cargo b {{ cargo_flags }} --package {{ prog }}
|
||||||
# cp {{ bin_path / prog }} {{ "mnt/usr/bin" / prog }}
|
cp {{ bin_path / prog }} {{ "mnt/usr/bin" / prog }}
|
||||||
riscv64-elf-objcopy -O binary {{ bin_path / prog }} {{ "mnt/usr/bin" / prog }}
|
# riscv64-elf-objcopy -O binary {{ bin_path / prog }} {{ "mnt/usr/bin" / prog }}
|
||||||
|
|
||||||
build: mount_filesystem (map_dir "user" "build_user_prog")
|
build: mount_filesystem (map_dir "user" f"just cargo_flags=\"{{cargo_flags}}\" build_user_prog")
|
||||||
cargo b {{ cargo_flags }}
|
cargo b {{ cargo_flags }}
|
||||||
just sync_filesystem
|
just sync_filesystem
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ run: build
|
|||||||
|
|
||||||
map_dir dir recipe:
|
map_dir dir recipe:
|
||||||
@for file in `ls {{ dir }}`; do \
|
@for file in `ls {{ dir }}`; do \
|
||||||
just cargo_flags="{{ cargo_flags }}" {{ recipe }} $file ; \
|
{{ recipe }} $file ; \
|
||||||
done
|
done
|
||||||
|
|
||||||
qemu := "qemu-system-riscv64 -machine virt -device bochs-display -bios none -m 512M -device loader,file=disk.img,addr=0x90000000"
|
qemu := "qemu-system-riscv64 -machine virt -device bochs-display -bios none -m 512M -device loader,file=disk.img,addr=0x90000000"
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
ptr_metadata
|
ptr_metadata
|
||||||
)]
|
)]
|
||||||
|
|
||||||
use alloc::string::String;
|
|
||||||
use embedded_alloc::LlffHeap as Heap;
|
use embedded_alloc::LlffHeap as Heap;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use core::time::Duration;
|
|||||||
|
|
||||||
use alloc::{boxed::Box, format, string::String, vec::Vec};
|
use alloc::{boxed::Box, format, string::String, vec::Vec};
|
||||||
use bffs::{io::Read, path::Path};
|
use bffs::{io::Read, path::Path};
|
||||||
|
use goblin::elf::reloc::R_RISCV_RELATIVE;
|
||||||
use shared::syscall::exit;
|
use shared::syscall::exit;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -134,6 +135,78 @@ pub fn create_process_from_file<'a, T: Into<Path<'a>>>(path: T) -> i64 {
|
|||||||
|
|
||||||
println!("Loading binary at address: {:x?}", content.as_ptr());
|
println!("Loading binary at address: {:x?}", content.as_ptr());
|
||||||
|
|
||||||
|
// If ELF, use goblin to load PT_LOAD segments and apply relocations
|
||||||
|
if let Ok(gelf) = goblin::elf::Elf::parse(&content) {
|
||||||
|
// Determine memory bounds from program headers
|
||||||
|
let mut min_vaddr = u64::MAX;
|
||||||
|
let mut max_vaddr = 0u64;
|
||||||
|
for ph in gelf.program_headers.iter() {
|
||||||
|
if ph.p_type == goblin::elf::program_header::PT_LOAD && ph.p_memsz > 0 {
|
||||||
|
min_vaddr = core::cmp::min(min_vaddr, ph.p_vaddr);
|
||||||
|
max_vaddr = core::cmp::max(max_vaddr, ph.p_vaddr + ph.p_memsz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if min_vaddr != u64::MAX {
|
||||||
|
let size = (max_vaddr - min_vaddr) as usize;
|
||||||
|
use alloc::alloc::{alloc_zeroed, Layout};
|
||||||
|
let layout = Layout::from_size_align(size, 0x1000).unwrap();
|
||||||
|
let base = unsafe { alloc_zeroed(layout) };
|
||||||
|
|
||||||
|
// Copy segments
|
||||||
|
for ph in gelf.program_headers.iter() {
|
||||||
|
if ph.p_type == goblin::elf::program_header::PT_LOAD {
|
||||||
|
let dst = unsafe { base.add((ph.p_vaddr - min_vaddr) as usize) };
|
||||||
|
let src_off = ph.p_offset as usize;
|
||||||
|
let copy_len = ph.p_filesz as usize;
|
||||||
|
if copy_len > 0 {
|
||||||
|
unsafe {
|
||||||
|
core::ptr::copy_nonoverlapping(
|
||||||
|
content.as_ptr().add(src_off),
|
||||||
|
dst,
|
||||||
|
copy_len,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ph.p_memsz as usize > copy_len {
|
||||||
|
unsafe {
|
||||||
|
core::slice::from_raw_parts_mut(
|
||||||
|
dst.add(copy_len),
|
||||||
|
ph.p_memsz as usize - copy_len,
|
||||||
|
)
|
||||||
|
.fill(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply relocations using our parser (handles RELA entries)
|
||||||
|
for rela in gelf.dynrelas.iter() {
|
||||||
|
let r_type = rela.r_type;
|
||||||
|
match r_type {
|
||||||
|
x if x == R_RISCV_RELATIVE => {
|
||||||
|
let where_off = (rela.r_offset - min_vaddr) as usize;
|
||||||
|
let where_ptr = unsafe { base.add(where_off) } as *mut u64;
|
||||||
|
let val = (base as u64).wrapping_add(rela.r_addend.unwrap() as u64);
|
||||||
|
unsafe { core::ptr::write_unaligned(where_ptr, val) };
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry point
|
||||||
|
let entry_va = gelf.entry;
|
||||||
|
let entry_addr = unsafe { base.add((entry_va - min_vaddr) as usize) } as *const u8;
|
||||||
|
let entry_fn =
|
||||||
|
unsafe { core::mem::transmute::<*const u8, extern "C" fn()>(entry_addr) };
|
||||||
|
let wrapper = Box::leak(Box::new(move || {
|
||||||
|
entry_fn();
|
||||||
|
}));
|
||||||
|
println!("Program loaded at : {:x?}", entry_addr);
|
||||||
|
return create_process(wrapper, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback: treat the file as a raw binary blob and execute in-place
|
// Fallback: treat the file as a raw binary blob and execute in-place
|
||||||
let entry_point =
|
let entry_point =
|
||||||
unsafe { core::mem::transmute::<*const u8, extern "C" fn()>(Vec::leak(content).as_ptr()) };
|
unsafe { core::mem::transmute::<*const u8, extern "C" fn()>(Vec::leak(content).as_ptr()) };
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(fmt_internals)]
|
|
||||||
|
|
||||||
use core::fmt::{write, Arguments, Write};
|
|
||||||
|
|
||||||
use os_std::syscall;
|
|
||||||
os_std::custom_std_setup! {}
|
os_std::custom_std_setup! {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -14,14 +9,5 @@ fn main() {
|
|||||||
for _ in 0..50 {
|
for _ in 0..50 {
|
||||||
test.push('C');
|
test.push('C');
|
||||||
}
|
}
|
||||||
let mut b = String::from("test");
|
println!("Hello from PIC program loaded dynamically with custom std and a better justfile, and syscalls !");
|
||||||
b.write_str("string: uaeuieuei");
|
|
||||||
// (&mut b as &mut dyn Write).write_str("string: uaeuieuei");
|
|
||||||
syscall::write_string_temp(&b);
|
|
||||||
// write(&mut b, Arguments::from_str_nonconst("string: uaeuieuei"));
|
|
||||||
// write(&mut b, format_args!("string: uaeuie{}", "uei"));
|
|
||||||
// syscall::write_int_temp(b.capacity() as u64);
|
|
||||||
// syscall::write_string_temp(&b);
|
|
||||||
// println!("{}", test);
|
|
||||||
// println!("Hello from PIC program loaded dynamically with custom std and a better justfile, and syscalls !");
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user