From b9bd878207c6b784694c15675a09636d112242d7 Mon Sep 17 00:00:00 2001 From: David Li Date: Mon, 4 Jan 2016 11:09:51 -0700 Subject: Implement initializing memory from text/data segments --- src/binary.rs | 2 ++ src/lib.rs | 33 ++++++++++++++++++++++++++++++- src/memory.rs | 45 +++++++++++++++++++++++++++++++++++++++++++ src/rust-elfloader/src/elf.rs | 20 +++++++++---------- 4 files changed, 89 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/binary.rs b/src/binary.rs index 122af51..a1d447e 100644 --- a/src/binary.rs +++ b/src/binary.rs @@ -22,6 +22,7 @@ use std::num; use std::path::Path; use std::str; +/// Representation of a binary pub struct Binary { pub words: Vec, } @@ -72,6 +73,7 @@ impl From for BinaryError { } impl Binary { + /// Load a binary from a hex file (generated with elf2hex) pub fn new_from_hex_file(path: &Path) -> Result { let file = try!(File::open(path)); let file = io::BufReader::new(file); diff --git a/src/lib.rs b/src/lib.rs index 5dda62e..1a176fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with rustv. If not, see . -#![feature(braced_empty_structs, step_by)] +#![feature(braced_empty_structs, clone_from_slice, raw, step_by)] pub mod isa; pub mod binary; pub mod memory; @@ -40,6 +40,37 @@ fn it_works() { } } +#[test] +fn test_elfloader() { + use std::io::prelude::*; + use std::fs::File; + extern crate elfloader; + + let mut f = File::open("../riscv/kernel").unwrap(); + let mut buffer = Vec::new(); + + f.read_to_end(&mut buffer).unwrap(); + + let elf = elfloader::ElfBinary::new("test", &buffer).unwrap(); + println!("HEADERS"); + for p in elf.program_headers() { + println!("{}", p); + } + for p in elf.section_headers() { + println!("{}", p); + if p.name.0 == 0x1b { + let data = elf.section_data(p); + print!("\t"); + for x in data[0..8].iter() { + print!("{:02x}", x); + } + println!(""); + } + } + + println!("{:?}", elf); +} + #[cfg(test)] mod tests { #[test] diff --git a/src/memory.rs b/src/memory.rs index 92aefd5..db0dca4 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -157,6 +157,31 @@ pub struct DirectMappedCache<'a> { next_level: SharedMemory<'a>, } +fn copy_u8_into_u32(src: &[u8], dst: &mut [u32]) { + for (offset, word) in src.chunks(4).enumerate() { + let word = if word.len() == 4 { + (word[0] as u32) | + ((word[1] as u32) << 8) | + ((word[2] as u32) << 16) | + ((word[3] as u32) << 24) + } + else if word.len() == 3 { + (word[0] as u32) | + ((word[1] as u32) << 8) | + ((word[2] as u32) << 16) + } + else if word.len() == 2 { + (word[0] as u32) | + ((word[1] as u32) << 8) + } + else { + word[0] as u32 + }; + + dst[offset] = word; + } +} + impl Memory { pub fn new(size: isa::Address) -> Memory { Memory { @@ -175,6 +200,26 @@ impl Memory { memory: memory, } } + + pub fn new_from_text_and_data(size: usize, + text: &[u8], text_offset: usize, + data: &[u8], data_offset: usize) -> Memory { + let mut memory = vec![0; size]; + + { + let mut text_segment = &mut memory[(text_offset / 4)..size]; + copy_u8_into_u32(text, text_segment); + } + + { + let mut data_segment = &mut memory[(data_offset / 4)..size]; + copy_u8_into_u32(data, data_segment); + } + + Memory { + memory: memory, + } + } } impl MemoryInterface for Memory { diff --git a/src/rust-elfloader/src/elf.rs b/src/rust-elfloader/src/elf.rs index 5a1df57..46b8eb8 100644 --- a/src/rust-elfloader/src/elf.rs +++ b/src/rust-elfloader/src/elf.rs @@ -641,7 +641,7 @@ impl fmt::Display for SectionType { /// Wrapper type for SectionFlag /// #[derive(Copy, Clone, PartialEq)] -pub struct SectionFlag(pub u64); +pub struct SectionFlag(pub u32); /// Empty flags pub const SHF_NONE : SectionFlag = SectionFlag(0); @@ -704,19 +704,19 @@ pub struct SectionHeader { /// Section Flags pub flags: SectionFlag, /// in-memory address where this section is loaded - pub addr: u64, + pub addr: u32, /// Byte-offset into the file where this section starts - pub offset: u64, + pub offset: u32, /// Section size in bytes - pub size: u64, + pub size: u32, /// Defined by section type pub link: u32, /// Defined by section type pub info: u32, /// address alignment - pub addralign: u64, + pub addralign: u32, /// size of an entry if section data is an array of entries - pub entsize: u64, + pub entsize: u32, } impl fmt::Display for SectionHeader { @@ -817,13 +817,13 @@ impl fmt::Display for SymbolVis { pub struct Symbol { /// Symbol name pub name: StrOffset, + /// Symbol value + pub value: u32, + /// Symbol size + pub size: u32, info: u8, other: u8, section_index: u16, - /// Symbol value - pub value: u64, - /// Symbol size - pub size: u64, } impl fmt::Display for Symbol { -- cgit v1.2.3