Skip to content

Commit

Permalink
No alloc needed & Return entry point
Browse files Browse the repository at this point in the history
  • Loading branch information
wenxuanjun committed Nov 3, 2024
1 parent d56f8df commit 0d81a00
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[unstable]
build-std-features = ["compiler-builtins-mem"]
build-std = ["core", "compiler_builtins", "alloc"]
build-std = ["core", "compiler_builtins"]

[build]
target = ["i686-unknown-none.json", "x86_64-unknown-none"]
21 changes: 6 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ opt-level = 3
strip = true
codegen-units = 1

[dependencies.object]
version = "0.36.5"
features = ["read_core", "elf", "unaligned"]
[dependencies.elf]
version = "0.7.4"
default-features = false
85 changes: 32 additions & 53 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,18 @@
#![no_std]
#![no_main]
#![feature(alloc_error_handler)]

extern crate alloc;

use core::alloc::{GlobalAlloc, Layout};
use core::ffi::c_void;
use core::panic::PanicInfo;
use core::slice::from_raw_parts;
use object::{File, Object, ObjectSegment};

use elf::abi::PT_LOAD;
use elf::endian::NativeEndian;
use elf::ElfBytes;

#[panic_handler]
unsafe fn panic(_info: &PanicInfo) -> ! {
loop {}
}

#[global_allocator]
static ALLOCATOR: Allocator = Allocator;

#[alloc_error_handler]
fn alloc_error_handler(layout: Layout) -> ! {
panic!("Allocation error: {:?}", layout);
}

struct Allocator;

static mut MALLOC: Option<extern "C" fn(usize) -> *mut c_void> = None;
static mut FREE: Option<extern "C" fn(*mut c_void)> = None;

unsafe impl GlobalAlloc for Allocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
MALLOC.unwrap()(layout.size()) as *mut u8
}

unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
FREE.unwrap()(ptr as *mut c_void);
}
}

#[repr(C)]
pub struct Segment {
address: u64,
Expand All @@ -47,14 +22,19 @@ pub struct Segment {

impl Segment {
pub fn new(address: u64, size: u64, data: *const u8) -> Self {
Self { address, size, data }
Self {
address,
size,
data,
}
}
}

#[repr(C)]
pub enum ParseElfError {
None = 0,
pub enum ElfParseResult {
EntryPoint(usize),
InvalidElfData,
ElfContainsNoSegments,
FailedToGetSegmentData,
AllocFunctionNotProvided,
}
Expand All @@ -63,32 +43,31 @@ pub enum ParseElfError {
pub unsafe extern "C" fn parse_elf(
elf_data: *const u8,
elf_size: usize,
callback: extern "C" fn(segment: Segment),
malloc: Option<extern "C" fn(usize) -> *mut c_void>,
free: Option<extern "C" fn(*mut c_void)>,
) -> ParseElfError {
if malloc.is_none() || free.is_none() {
return ParseElfError::AllocFunctionNotProvided;
}

MALLOC = malloc;
FREE = free;

mapping_callback: extern "C" fn(segment: Segment),
) -> ElfParseResult {
let buffer = from_raw_parts(elf_data, elf_size);

let binary = match File::parse(buffer) {
Ok(file) => file,
Err(_) => return ParseElfError::InvalidElfData,
let elf_file = match ElfBytes::<NativeEndian>::minimal_parse(buffer) {
Ok(elf) => elf,
Err(_) => return ElfParseResult::InvalidElfData,
};

let parsing_table = match elf_file.segments() {
Some(s) => s,
None => return ElfParseResult::ElfContainsNoSegments,
};

for segment in binary.segments() {
let data = match segment.data() {
Ok(d) => d,
Err(_) => return ParseElfError::FailedToGetSegmentData,
};
for header in parsing_table {
if header.p_type == PT_LOAD {
let data = match elf_file.segment_data(&header) {
Ok(d) => d,
Err(_) => return ElfParseResult::FailedToGetSegmentData,
};

callback(Segment::new(segment.address(), segment.size(), data.as_ptr()));
let segment = Segment::new(header.p_vaddr, header.p_memsz, data.as_ptr());
mapping_callback(segment);
}
}

ParseElfError::None
ElfParseResult::EntryPoint(elf_file.ehdr.e_entry as usize)
}

0 comments on commit 0d81a00

Please sign in to comment.