Skip to content

Commit e550d51

Browse files
authored
remove unused load_elf (#204)
1 parent 96da3e8 commit e550d51

File tree

1 file changed

+2
-243
lines changed

1 file changed

+2
-243
lines changed

prover/src/cpu/kernel/elf.rs

+2-243
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
extern crate alloc;
2-
use crate::poseidon_sponge::poseidon_sponge_stark::poseidon;
32
use alloc::collections::BTreeMap;
4-
use anyhow::{anyhow, bail, Context, Result};
5-
use elf::{endian::BigEndian, file::Class, ElfBytes};
6-
use plonky2::field::goldilocks_field::GoldilocksField;
3+
use anyhow::{Context, Result};
74
use serde::{Deserialize, Serialize};
85
use std::fs::{self};
96
use std::io::Read;
10-
use zkm_emulator::memory::{INIT_SP, WORD_SIZE};
7+
use zkm_emulator::memory::WORD_SIZE;
118
use zkm_emulator::state::{Segment, REGISTERS_START};
129
pub const PAGE_SIZE: u32 = 4096;
1310

@@ -58,211 +55,6 @@ impl Program {
5855
Ok(true)
5956
}
6057

61-
/// Initialize a MIPS Program from an appropriate ELF file
62-
pub fn load_elf(input: &[u8], max_mem: u32) -> Result<Program> {
63-
let mut image: BTreeMap<u32, u32> = BTreeMap::new();
64-
let elf = ElfBytes::<BigEndian>::minimal_parse(input)
65-
.map_err(|err| anyhow!("Elf parse error: {err}"))?;
66-
if elf.ehdr.class != Class::ELF32 {
67-
bail!("Not a 32-bit ELF");
68-
}
69-
if elf.ehdr.e_machine != elf::abi::EM_MIPS {
70-
bail!("Invalid machine type, must be MIPS");
71-
}
72-
if elf.ehdr.e_type != elf::abi::ET_EXEC {
73-
bail!("Invalid ELF type, must be executable");
74-
}
75-
let entry: u32 = elf
76-
.ehdr
77-
.e_entry
78-
.try_into()
79-
.map_err(|err| anyhow!("e_entry was larger than 32 bits. {err}"))?;
80-
if entry >= max_mem || entry % WORD_SIZE as u32 != 0 {
81-
bail!("Invalid entrypoint");
82-
}
83-
let segments = elf.segments().ok_or(anyhow!("Missing segment table"))?;
84-
if segments.len() > 256 {
85-
bail!("Too many program headers");
86-
}
87-
88-
let mut hiaddr = 0u32;
89-
for segment in segments.iter().filter(|x| x.p_type == elf::abi::PT_LOAD) {
90-
let file_size: u32 = segment
91-
.p_filesz
92-
.try_into()
93-
.map_err(|err| anyhow!("filesize was larger than 32 bits. {err}"))?;
94-
if file_size >= max_mem {
95-
bail!("Invalid segment file_size");
96-
}
97-
let mem_size: u32 = segment
98-
.p_memsz
99-
.try_into()
100-
.map_err(|err| anyhow!("mem_size was larger than 32 bits {err}"))?;
101-
if mem_size >= max_mem {
102-
bail!("Invalid segment mem_size");
103-
}
104-
let vaddr: u32 = segment
105-
.p_vaddr
106-
.try_into()
107-
.map_err(|err| anyhow!("vaddr is larger than 32 bits. {err}"))?;
108-
if vaddr % WORD_SIZE as u32 != 0 {
109-
bail!("vaddr {vaddr:08x} is unaligned");
110-
}
111-
112-
let a = vaddr + mem_size;
113-
if a > hiaddr {
114-
hiaddr = a;
115-
}
116-
117-
let offset: u32 = segment
118-
.p_offset
119-
.try_into()
120-
.map_err(|err| anyhow!("offset is larger than 32 bits. {err}"))?;
121-
for i in (0..mem_size).step_by(WORD_SIZE) {
122-
let addr = vaddr.checked_add(i).context("Invalid segment vaddr")?;
123-
if addr >= max_mem {
124-
bail!("Address [0x{addr:08x}] exceeds maximum address for guest programs [0x{max_mem:08x}]");
125-
}
126-
if i >= file_size {
127-
// Past the file size, all zeros.
128-
image.insert(addr, 0);
129-
} else {
130-
let mut word = 0;
131-
// Don't read past the end of the file.
132-
let len = core::cmp::min(file_size - i, WORD_SIZE as u32);
133-
for j in 0..len {
134-
let offset = (offset + i + j) as usize;
135-
let byte = input.get(offset).context("Invalid segment offset")?;
136-
word |= (*byte as u32) << (j * 8);
137-
}
138-
image.insert(addr, word);
139-
}
140-
}
141-
}
142-
143-
let brk = hiaddr - (hiaddr & (PAGE_SIZE - 1)) + PAGE_SIZE;
144-
145-
let (symtab, strtab) = elf
146-
.symbol_table()
147-
.expect("Failed to read symbol table")
148-
.expect("Failed to find symbol table");
149-
150-
// PatchGO
151-
for symbol in symtab.iter() {
152-
let name = strtab
153-
.get(symbol.st_name as usize)
154-
.expect("Failed to get name from strtab");
155-
156-
let addr: u32 = symbol
157-
.st_value
158-
.try_into()
159-
.map_err(|err| anyhow!("offset is larger than 32 bits. {err}"))?;
160-
161-
match name {
162-
"runtime.gcenable" |
163-
"runtime.init.5" | // patch out: init() { go forcegchelper() }
164-
"runtime.main.func1" | // patch out: main.func() { newm(sysmon, ....) }
165-
"runtime.deductSweepCredit" | // uses floating point nums and interacts with gc we disabled
166-
"runtime.(*gcControllerState).commit" |
167-
// these prometheus packages rely on concurrent background things. We cannot run those.
168-
"github.com/prometheus/client_golang/prometheus.init" |
169-
"github.com/prometheus/client_golang/prometheus.init.0" |
170-
"github.com/prometheus/procfs.init" |
171-
"github.com/prometheus/common/model.init" |
172-
"github.com/prometheus/client_model/go.init" |
173-
"github.com/prometheus/client_model/go.init.0" |
174-
"github.com/prometheus/client_model/go.init.1" |
175-
// skip flag pkg init, we need to debug arg-processing more to see why this fails
176-
"flag.init" |
177-
// We need to patch this out, we don't pass float64nan because we don't support floats
178-
"runtime.check" => {
179-
// MIPS32 patch: ret (pseudo instruction)
180-
// 03e00008 = jr $ra = ret (pseudo instruction)
181-
// 00000000 = nop (executes with delay-slot, but does nothing)
182-
image.insert(addr, 0x0800e003);
183-
image.insert(addr + 4, 0);
184-
},
185-
"runtime.MemProfileRate" => { image.insert(addr, 0) ; },
186-
&_ => (),
187-
}
188-
}
189-
190-
// PatchStack
191-
let mut sp = INIT_SP - 4 * PAGE_SIZE;
192-
// allocate 1 page for the initial stack data, and 16KB = 4 pages for the stack to grow
193-
for i in (0..5 * PAGE_SIZE).step_by(WORD_SIZE) {
194-
image.insert(sp + i, 0);
195-
}
196-
197-
sp = INIT_SP;
198-
// init argc, argv, aux on stack
199-
image.insert(sp + 4, 0x42u32.to_be()); // argc = 0 (argument count)
200-
image.insert(sp + 4 * 2, 0x35u32.to_be()); // argv[n] = 0 (terminating argv)
201-
image.insert(sp + 4 * 3, 0); // envp[term] = 0 (no env vars)
202-
image.insert(sp + 4 * 4, 6u32.to_be()); // auxv[0] = _AT_PAGESZ = 6 (key)
203-
image.insert(sp + 4 * 5, 4096u32.to_be()); // auxv[1] = page size of 4 KiB (value) - (== minPhysPageSize)
204-
image.insert(sp + 4 * 6, 25u32.to_be()); // auxv[2] = AT_RANDOM
205-
image.insert(sp + 4 * 7, (sp + 4 * 9).to_be()); // auxv[3] = address of 16 bytes containing random value
206-
image.insert(sp + 4 * 8, 0); // auxv[term] = 0
207-
208-
image.insert(sp + 4 * 9, 0x34322343u32.to_be());
209-
image.insert(sp + 4 * 10, 0x54323423u32.to_be());
210-
image.insert(sp + 4 * 11, 0x44572234u32.to_be());
211-
image.insert(sp + 4 * 12, 0x90032dd2u32.to_be());
212-
213-
let mut gprs = [0; 32];
214-
gprs[29] = INIT_SP as usize;
215-
216-
let lo = 0;
217-
let hi = 0;
218-
let heap = 0x20000000;
219-
let end_pc: u32 = 0;
220-
221-
// this is just for test
222-
let mut final_data = [0u8; 36];
223-
let page_hash_root = [1u8; 32];
224-
final_data[0..32].copy_from_slice(&page_hash_root);
225-
final_data[32..].copy_from_slice(&end_pc.to_be_bytes());
226-
227-
let image_id_u64s = poseidon::<GoldilocksField>(&final_data);
228-
let image_id = image_id_u64s
229-
.iter()
230-
.flat_map(|&num| num.to_le_bytes())
231-
.collect::<Vec<_>>();
232-
233-
let pre_hash_root = [1u8; 32];
234-
final_data[0..32].copy_from_slice(&pre_hash_root);
235-
final_data[32..].copy_from_slice(&entry.to_be_bytes());
236-
237-
let pre_image_id_u64s = poseidon::<GoldilocksField>(&final_data);
238-
let pre_image_id = pre_image_id_u64s
239-
.iter()
240-
.flat_map(|&num| num.to_le_bytes())
241-
.collect::<Vec<_>>();
242-
243-
Ok(Program {
244-
entry,
245-
next_pc: (entry + 4) as usize,
246-
image,
247-
gprs,
248-
lo,
249-
hi,
250-
heap,
251-
brk: brk as usize,
252-
local_user: 0,
253-
end_pc: end_pc as usize,
254-
step: 0,
255-
image_id: image_id.try_into().unwrap(),
256-
pre_image_id: pre_image_id.try_into().unwrap(),
257-
pre_hash_root,
258-
page_hash_root,
259-
input_stream: Vec::new(),
260-
input_stream_ptr: 0,
261-
public_values_stream: Vec::new(),
262-
public_values_stream_ptr: 0,
263-
})
264-
}
265-
26658
pub fn load_segment<T: Read>(reader: T) -> Result<Program> {
26759
let segment: Segment = serde_json::from_reader(reader).unwrap();
26860

@@ -346,36 +138,3 @@ impl Program {
346138
})
347139
}
348140
}
349-
350-
#[cfg(test)]
351-
mod test {
352-
use crate::cpu::kernel::elf::*;
353-
use std::fs::File;
354-
use std::io::BufReader;
355-
use zkm_emulator::utils::get_block_path;
356-
357-
#[test]
358-
fn load_and_check_mips_elf() {
359-
env_logger::try_init().unwrap_or_default();
360-
let mut reader = BufReader::new(File::open("../emulator/test-vectors/hello").unwrap());
361-
let mut buffer = Vec::new();
362-
reader.read_to_end(&mut buffer).unwrap();
363-
let max_mem = 0x80000000;
364-
let mut p: Program = Program::load_elf(&buffer, max_mem).unwrap();
365-
log::info!("entry: {}", p.entry);
366-
367-
let real_blockpath = get_block_path("../emulator/test-vectors", "13284491", "input");
368-
log::info!("real block path: {}", real_blockpath);
369-
p.load_block(&real_blockpath).unwrap();
370-
371-
p.image.iter().for_each(|(k, v)| {
372-
if *k > INIT_SP && *k < INIT_SP + 50 {
373-
log::debug!("{:X}: {:X}", k, v.to_be());
374-
}
375-
376-
if *k > 0x30000000 && *k < 0x30000020 {
377-
log::debug!("{:X}: {:X}", k, v.to_be());
378-
}
379-
})
380-
}
381-
}

0 commit comments

Comments
 (0)