Skip to content

Commit

Permalink
Merge pull request #138 from valida-xyz/morgan/issue/135
Browse files Browse the repository at this point in the history
Loading ELF files
  • Loading branch information
morganthomas committed Apr 8, 2024
2 parents 898d5ce + a3c35c8 commit 3fcc93b
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 6 deletions.
15 changes: 15 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"bus",
"cpu",
"derive",
"elf",
"native_field",
"machine",
"memory",
Expand Down
1 change: 1 addition & 0 deletions basic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ valida-assembler = { path = "../assembler" }
valida-bus = { path = "../bus" }
valida-cpu = { path = "../cpu" }
valida-derive = { path = "../derive" }
valida-elf = { path = "../elf" }
valida-machine = { path = "../machine" }
valida-memory = { path = "../memory" }
valida-opcodes = { path = "../opcodes" }
Expand Down
16 changes: 10 additions & 6 deletions basic/src/bin/valida.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use clap::Parser;
use std::fs;
use std::fs::File;
use std::io::{stdout, Write};

Expand All @@ -11,7 +12,9 @@ use valida_cpu::MachineWithCpuChip;
use valida_machine::{Machine, MachineProof, ProgramROM, StdinAdviceProvider};
use valida_memory::MachineWithMemoryChip;

use valida_elf::{load_executable_file, Program};
use valida_program::MachineWithProgramChip;
use valida_static_data::MachineWithStaticDataChip;

use p3_challenger::DuplexChallenger;
use p3_dft::Radix2DitParallel;
Expand Down Expand Up @@ -283,16 +286,17 @@ fn main() {
}

let mut machine = BasicMachine::<BabyBear>::default();
let rom = match ProgramROM::from_file(&args.program) {
Ok(contents) => contents,
Err(e) => panic!("Failure to load file: {}. {}", &args.program, e),
};
machine.program_mut().set_program_rom(&rom);
let Program { code, data } = load_executable_file(
fs::read(&args.program)
.expect(format!("Failed to read executable file: {}", &args.program).as_str()),
);
machine.program_mut().set_program_rom(&code);
machine.cpu_mut().fp = args.stack_height;
machine.cpu_mut().save_register_state();
machine.static_data_mut().load(data);

// Run the program
machine.run(&rom, &mut StdinAdviceProvider);
machine.run(&code, &mut StdinAdviceProvider);

type Val = BabyBear;
type Challenge = BinomialExtensionField<Val, 5>;
Expand Down
9 changes: 9 additions & 0 deletions elf/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "valida-elf"
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"

[dependencies]
elf = "0.7.4"
valida-machine = { path = "../machine" }
90 changes: 90 additions & 0 deletions elf/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#![no_std]

extern crate alloc;

use alloc::collections::BTreeMap;
use alloc::vec;
use alloc::vec::Vec;
use elf::abi;
use elf::endian::AnyEndian;
use elf::section::SectionHeader;
use elf::ElfBytes;
use valida_machine::{ProgramROM, Word};

pub struct Program {
pub code: ProgramROM<i32>,
pub data: BTreeMap<u32, Word<u8>>,
}

pub fn load_executable_file(file: Vec<u8>) -> Program {
if file[0] == 0x7F && file[1] == 0x45 && file[2] == 0x4C && file[3] == 0x46 {
load_elf_object_file(file)
} else {
Program {
code: ProgramROM::from_machine_code(file.as_slice()),
data: BTreeMap::new(),
}
}
}

pub fn load_elf_object_file(file: Vec<u8>) -> Program {
let file = ElfBytes::<AnyEndian>::minimal_parse(file.as_slice()).unwrap();
let mut data_sections: Vec<(SectionHeader, &[u8])> = vec![];
let mut bss_sections: Vec<SectionHeader> = vec![];
let mut text_sections: Vec<(SectionHeader, &[u8])> = vec![];
for section_header in file.section_headers().unwrap().iter() {
let is_data: bool = section_header.sh_type == abi::SHT_PROGBITS
&& section_header.sh_flags == (abi::SHF_ALLOC | abi::SHF_WRITE).into();
let is_bss: bool = section_header.sh_type == abi::SHT_NOBITS
&& section_header.sh_flags == (abi::SHF_ALLOC | abi::SHF_WRITE).into();
let is_text: bool = section_header.sh_type == abi::SHT_PROGBITS
&& section_header.sh_flags == (abi::SHF_ALLOC | abi::SHF_EXECINSTR).into();
let is_useful: bool = is_data || is_bss || is_text;
if is_useful {
if is_data || is_text {
let section_data = file.section_data(&section_header).unwrap();
match section_data {
(section_data, None) => {
if is_data {
data_sections.push((section_header, section_data));
} else if is_text {
text_sections.push((section_header, section_data));
}
}
_ => panic!("unsupported: compressed ELF section data"),
}
} else if is_bss {
bss_sections.push(section_header);
}
}
}
let code_size = text_sections
.iter()
.map(|(section_header, _)| section_header.sh_addr + section_header.sh_size)
.fold(0, |a, b| a.max(b));
let mut code: Vec<u8> = vec![0; code_size as usize];
for (section_header, section_data) in text_sections {
for i in 0..section_header.sh_size as usize {
code[i + section_header.sh_addr as usize] = section_data[i];
}
}
let mut data: BTreeMap<u32, Word<u8>> = BTreeMap::new();
for (section_header, section_data) in data_sections {
for i in 0..(section_header.sh_size / 4) as usize {
data.insert(
<u64 as TryInto<u32>>::try_into(section_header.sh_addr).unwrap()
+ <usize as TryInto<u32>>::try_into(i * 4).unwrap(),
Word([
section_data[i * 4],
section_data[i * 4 + 1],
section_data[i * 4 + 2],
section_data[i * 4 + 3],
]),
);
}
}
Program {
code: ProgramROM::from_machine_code(code.as_slice()),
data: data,
}
}
4 changes: 4 additions & 0 deletions static_data/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ impl StaticDataChip {
}
}

pub fn load(&mut self, cells: BTreeMap<u32, Word<u8>>) {
self.cells = cells;
}

pub fn write(&mut self, address: u32, value: Word<u8>) {
self.cells.insert(address, value);
}
Expand Down

0 comments on commit 3fcc93b

Please sign in to comment.