diff --git a/basic/src/bin/valida.rs b/basic/src/bin/valida.rs index c59b45e..817521e 100644 --- a/basic/src/bin/valida.rs +++ b/basic/src/bin/valida.rs @@ -75,13 +75,18 @@ impl Context { last_fp_size_: 0, }; - let Program { code, data } = load_executable_file( + let Program { + code, + data, + initial_program_counter, + } = load_executable_file( fs::read(&args.program) .expect(format!("Failed to read executable file: {}", &args.program).as_str()), ); context.machine_.program_mut().set_program_rom(&code); context.machine_.static_data_mut().load(data); + context.machine_.cpu_mut().pc = initial_program_counter; context.machine_.cpu_mut().fp = args.stack_height; context.machine_.cpu_mut().save_register_state(); @@ -322,12 +327,17 @@ fn main() { } let mut machine = BasicMachine::::default(); - let Program { code, data } = load_executable_file( + let Program { + code, + data, + initial_program_counter, + } = 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().pc = initial_program_counter; machine.cpu_mut().save_register_state(); machine.static_data_mut().load(data); diff --git a/basic/src/lib.rs b/basic/src/lib.rs index 67fe80f..d1df172 100644 --- a/basic/src/lib.rs +++ b/basic/src/lib.rs @@ -1165,7 +1165,7 @@ impl Machine for BasicMachine { >::OPCODE => { WriteInstruction::execute_with_advice::(self, ops, advice) } - _ => panic!("Unrecognized opcode: {}", opcode), + _ => panic!("Unrecognized opcode: {}, pc = {}", opcode, pc), }; self.read_word(pc as usize); diff --git a/elf/src/lib.rs b/elf/src/lib.rs index 3cd5b4b..352ca54 100644 --- a/elf/src/lib.rs +++ b/elf/src/lib.rs @@ -9,11 +9,12 @@ use elf::abi; use elf::endian::AnyEndian; use elf::section::SectionHeader; use elf::ElfBytes; -use valida_machine::{ProgramROM, Word}; +use valida_machine::{ProgramROM, Word, INSTRUCTION_ELEMENTS}; pub struct Program { pub code: ProgramROM, pub data: BTreeMap>, + pub initial_program_counter: u32, } pub fn load_executable_file(file: Vec) -> Program { @@ -23,6 +24,7 @@ pub fn load_executable_file(file: Vec) -> Program { Program { code: ProgramROM::from_machine_code(file.as_slice()), data: BTreeMap::new(), + initial_program_counter: 0, } } } @@ -35,29 +37,34 @@ pub fn load_elf_object_file(file: Vec) -> Program { 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_rodata: bool = section_header.sh_type == abi::SHT_PROGBITS + && (section_header.sh_flags == abi::SHF_ALLOC.into() + || section_header.sh_flags == 0x32); // TODO: what is 0x32? 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(§ion_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)); - } + if is_data || is_rodata || is_text { + let section_data = file.section_data(§ion_header).unwrap(); + match section_data { + (section_data, None) => { + if is_data || is_rodata { + 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); + _ => panic!("unsupported: compressed ELF section data"), } + } else if is_bss { + bss_sections.push(section_header); } } + let initial_program_counter = text_sections + .iter() + .map(|(section_header, _)| section_header.sh_addr / ((INSTRUCTION_ELEMENTS * 4) as u64)) + .reduce(|a, b| a.min(b)) + .unwrap(); let code_size = text_sections .iter() .map(|(section_header, _)| section_header.sh_addr + section_header.sh_size) @@ -70,7 +77,11 @@ pub fn load_elf_object_file(file: Vec) -> Program { } let mut data: BTreeMap> = BTreeMap::new(); for (section_header, section_data) in data_sections { - for i in 0..(section_header.sh_size / 4) as usize { + let mut section_data = Vec::from(section_data); + while section_data.len() % 4 != 0 { + section_data.push(0); + } + for i in 0..(section_data.len() / 4) as usize { data.insert( >::try_into(section_header.sh_addr).unwrap() + >::try_into(i * 4).unwrap(), @@ -85,6 +96,7 @@ pub fn load_elf_object_file(file: Vec) -> Program { } Program { code: ProgramROM::from_machine_code(code.as_slice()), - data: data, + data, + initial_program_counter: >::try_into(initial_program_counter).unwrap(), } }