ADD ELF SUPPORT

This commit is contained in:
2025-12-23 19:56:42 +01:00
parent 36faa1e39c
commit 8ed4845d58
6 changed files with 151 additions and 23 deletions

67
src/execload.rs Normal file
View File

@@ -0,0 +1,67 @@
// Copyright (c) 2025 taitep
// SPDX-License-Identifier: MIT
//
// This file is part of TRVE (https://gitea.taitep.se/taitep/trve)
// See LICENSE file in the project root for full license text.
use std::{fs, path::Path};
use anyhow::{Result, bail};
use goblin::{
Object,
elf::{
header::{EM_RISCV, ET_EXEC},
program_header::PT_LOAD,
},
};
use trve::consts::Addr;
pub fn load<P: AsRef<Path>>(path: P, ram: &mut [u8], ram_start: Addr) -> Result<Addr> {
let buf = fs::read(path)?;
match Object::parse(&buf)? {
Object::Elf(elf) => {
if elf.header.e_type != ET_EXEC {
bail!("Executable type incorrect, may not be an executable or may be dynamic");
}
if elf.header.e_machine != EM_RISCV {
bail!("Executable architecture is not RISC-V");
}
if !elf.is_64 {
bail!("Executable is not 64-bit");
}
if !elf.little_endian {
bail!("Executable is not little-endian");
}
for ph in elf.program_headers {
if ph.p_type == PT_LOAD {
let start = (ph.p_vaddr - ram_start) as usize;
let end = start + ph.p_memsz as usize;
let file_end = start + ph.p_filesz as usize;
if end > ram_start as usize + ram.len() {
bail!("Segment at 0x{:x} does not fit in RAM", ph.p_vaddr);
}
ram[start..file_end].copy_from_slice(
&buf[ph.p_offset as usize..(ph.p_offset + ph.p_filesz) as usize],
);
ram[file_end..end].fill(0);
}
}
Ok(elf.entry)
}
Object::Unknown(_) => {
eprintln!("Unrecognized executable format identifier, assuming raw binary");
if buf.len() > ram.len() {
bail!("Program too large for RAM");
}
ram[..buf.len()].copy_from_slice(&buf);
Ok(ram_start)
}
_ => bail!("Unsupported executable format"),
}
}